Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support Linq methods on ImmutableArray + added Errors tab to Compilation Page #1713

Merged
merged 3 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ public void AddDefaultMethodTranslators()
AddMethodTranslator(() => default(ICollection)!.Count, lengthMethod);
AddMethodTranslator(() => default(ICollection<Generic.T>)!.Count, lengthMethod);
AddMethodTranslator(() => default(IReadOnlyCollection<Generic.T>)!.Count, lengthMethod);
AddMethodTranslator(() => default(ImmutableArray<Generic.T>)!.Length, lengthMethod);
AddMethodTranslator(() => "".Length, lengthMethod);
AddMethodTranslator(() => Enums.GetNames<Generic.Enum>(), new EnumGetNamesMethodTranslator());
var identityTranslator = new GenericMethodCompiler(a => a[1]);
Expand Down Expand Up @@ -538,27 +539,43 @@ bool IsDelegateReturnTypeEnum(Type type)
string GetDelegateReturnTypeHash(Type type)
=> type.GetGenericArguments().Last().GetTypeHash();

AddMethodTranslator(() => Enumerable.All(Enumerable.Empty<Generic.T>(), _ => false), new GenericMethodCompiler(args => args[1].Member("every").Invoke(args[2])));
AddMethodTranslator(() => Enumerable.Any(Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1].Member("some").Invoke(returnTrueFunc.Clone())));
AddMethodTranslator(() => Enumerable.Any(Enumerable.Empty<Generic.T>(), _ => false), new GenericMethodCompiler(args => args[1].Member("some").Invoke(args[2])));
var all = new GenericMethodCompiler(args => args[1].Member("every").Invoke(args[2]));
AddMethodTranslator(() => Enumerable.All(Enumerable.Empty<Generic.T>(), _ => false), all);
AddMethodTranslator(() => ImmutableArrayExtensions.All(default(ImmutableArray<Generic.T>), _ => false), all);
var any = new GenericMethodCompiler(args => args[1].Member("length").Binary(BinaryOperatorType.Greater, new JsLiteral(0)));
AddMethodTranslator(() => Enumerable.Any(Enumerable.Empty<Generic.T>()), any);
AddMethodTranslator(() => ImmutableArrayExtensions.Any(default(ImmutableArray<Generic.T>)), any);
var anyPred = new GenericMethodCompiler(args => args[1].Member("some").Invoke(args[2]));
AddMethodTranslator(() => Enumerable.Any(Enumerable.Empty<Generic.T>(), _ => false), anyPred);
AddMethodTranslator(() => ImmutableArrayExtensions.Any(default(ImmutableArray<Generic.T>), _ => false), anyPred);
AddMethodTranslator(() => Enumerable.Concat(Enumerable.Empty<Generic.T>(), Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1].Member("concat").Invoke(args[2])));
AddMethodTranslator(() => Enumerable.Count(Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1].Member("length")));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Distinct(), new GenericMethodCompiler(args => new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("distinct").Invoke(args[1]),
check: (method, target, arguments) => EnsureIsComparableInJavascript(method, ReflectionUtils.GetEnumerableType(arguments.First().Type).NotNull())));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().ElementAt(0),
new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method)));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().ElementAtOrDefault(0),
new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method)));
AddMethodTranslator(() => ImmutableArrayExtensions.ElementAt(default(ImmutableArray<Generic.T>), 0),
new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method)));
AddMethodTranslator(() => ImmutableArrayExtensions.ElementAtOrDefault(default(ImmutableArray<Generic.T>), 0),
new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method)));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().FirstOrDefault(), new GenericMethodCompiler((args, m) =>
args[1].Indexer(0)
.WithAnnotation(new VMPropertyInfoAnnotation(m.ReturnType)).WithAnnotation(MayBeNullAnnotation.Instance)));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().FirstOrDefault(_ => true), new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("firstOrDefault").Invoke(args[1], args[2]).WithAnnotation(MayBeNullAnnotation.Instance)));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().LastOrDefault(), new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("lastOrDefault").Invoke(args[1], returnTrueFunc.Clone()).WithAnnotation(MayBeNullAnnotation.Instance)));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().LastOrDefault(_ => false), new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("lastOrDefault").Invoke(args[1], args[2]).WithAnnotation(MayBeNullAnnotation.Instance)));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().FirstOrDefault(), new GenericMethodCompiler((args, m) => BuildIndexer(args[1], new JsLiteral(0), m)));
AddMethodTranslator(() => ImmutableArrayExtensions.FirstOrDefault(default(ImmutableArray<Generic.T>)), new GenericMethodCompiler((args, m) => BuildIndexer(args[1], new JsLiteral(0), m)));
var firstOrDefaultPred = new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("firstOrDefault").Invoke(args[1], args[2]).WithAnnotation(MayBeNullAnnotation.Instance));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().FirstOrDefault(_ => true), firstOrDefaultPred);
AddMethodTranslator(() => ImmutableArrayExtensions.FirstOrDefault(default(ImmutableArray<Generic.T>), _ => true), firstOrDefaultPred);

var lastOrDefault = new GenericMethodCompiler(args => args[1].Member("at").Invoke(new JsLiteral(-1)).WithAnnotation(MayBeNullAnnotation.Instance));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().LastOrDefault(), lastOrDefault);
AddMethodTranslator(() => ImmutableArrayExtensions.LastOrDefault(default(ImmutableArray<Generic.T>)), lastOrDefault);
var lastOrDefaultPred = new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("lastOrDefault").Invoke(args[1], args[2]).WithAnnotation(MayBeNullAnnotation.Instance));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().LastOrDefault(_ => false), lastOrDefaultPred);
AddMethodTranslator(() => ImmutableArrayExtensions.LastOrDefault(default(ImmutableArray<Generic.T>), _ => false), lastOrDefaultPred);

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().OrderBy(_ => Generic.Enum.Something), new GenericMethodCompiler((jArgs, dArgs) => new JsIdentifierExpression("dotvvm").Member("translations").Member("array").Member("orderBy")
.Invoke(jArgs[1], jArgs[2], new JsLiteral((IsDelegateReturnTypeEnum(dArgs.Last().Type)) ? GetDelegateReturnTypeHash(dArgs.Last().Type) : null)),
Expand All @@ -567,17 +584,30 @@ string GetDelegateReturnTypeHash(Type type)
.Invoke(jArgs[1], jArgs[2], new JsLiteral((IsDelegateReturnTypeEnum(dArgs.Last().Type)) ? GetDelegateReturnTypeHash(dArgs.Last().Type) : null)),
check: (method, _, arguments) => EnsureIsComparableInJavascript(method, arguments.Last().Type.GetGenericArguments().Last())));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Select(_ => Generic.Enum.Something),
translator: new GenericMethodCompiler(args => args[1].Member("map").Invoke(args[2])));
var select = new GenericMethodCompiler(args => args[1].Member("map").Invoke(args[2]));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Select(_ => Generic.Enum.Something), select);
AddMethodTranslator(() => ImmutableArrayExtensions.Select(default(ImmutableArray<Generic.T>), _ => Generic.Enum.Something), select);
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Skip(0), new GenericMethodCompiler(args => args[1].Member("slice").Invoke(args[2])));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Take(0), new GenericMethodCompiler(args =>
args[1].Member("slice").Invoke(new JsLiteral(0), args[2])));

var where = new GenericMethodCompiler(args => args[1].Member("filter").Invoke(args[2]));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Where(_ => true), where);
AddMethodTranslator(() => ImmutableArrayExtensions.Where(default(ImmutableArray<Generic.T>), _ => true), where);

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().ToArray(), new GenericMethodCompiler(args => args[1]));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().ToList(), new GenericMethodCompiler(args => args[1]));
AddMethodTranslator(() => Enumerable.Empty<Generic.T>().ToHashSet(), new GenericMethodCompiler(args => args[1]));
AddMethodTranslator(() => Enumerable.AsEnumerable(Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1]));

AddMethodTranslator(() => ImmutableArray.ToImmutableArray(Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1]));
AddMethodTranslator(() => ImmutableList.ToImmutableList(Enumerable.Empty<Generic.T>()), new GenericMethodCompiler(args => args[1]));
AddMethodTranslator(() => ImmutableArrayExtensions.ToArray(ImmutableArray<Generic.T>.Empty), new GenericMethodCompiler(args => args[1]));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>().Where(_ => true), new GenericMethodCompiler(args => args[1].Member("filter").Invoke(args[2])));

AddMethodTranslator(() => Enumerable.Empty<Generic.T>(), new GenericMethodCompiler(args => new JsArrayExpression()));
AddMethodTranslator(() => Array.Empty<Generic.T>(), new GenericMethodCompiler(args => new JsArrayExpression()));
AddDefaultNumericEnumerableTranslations();
}

Expand Down
95 changes: 86 additions & 9 deletions src/Framework/Framework/Diagnostics/CompilationPage.dothtml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@
Text="Master pages"
class="nav"
Class-active="{value: ActiveTab == 2}" />
<dot:Button Click="{staticCommand: ActiveTab = 3}"
Text="Errors"
class="nav"
Class-active="{value: ActiveTab == 3}" />
</nav>
<hr />
<main>
<section Visible="{value: ActiveTab == 0}">
<section IncludeInPage="{value: ActiveTab == 0}">
<h2>Routes</h2>
<dot:GridView DataSource="{value: Routes}" class="nowrap">
<RowDecorators>
Expand All @@ -52,15 +56,19 @@
<dot:GridViewTemplateColumn HeaderText="Url">
<ContentTemplate>
<span IncludeInPage={value: !HasParameters}>
<a href="{value: "/" + Url}">{{value: Url}}</a>
<a href="{value: _root.PathBase + Url}">{{value: Url == "" ? "<Empty>" : Url}}</a>
</span>
<span IncludeInPage={value: HasParameters}>
<span IncludeInPage={value: HasParameters} title={value: Url}>
{{value: Url}}
</span>
</ContentTemplate>
</dot:GridViewTemplateColumn>
<dot:GridViewTextColumn ValueBinding="{value: VirtualPath}"
HeaderText="Virtual Path" />
HeaderText="Virtual Path">
<CellDecorators>
<dot:Decorator title={value: VirtualPath} />
</CellDecorators>
</dot:GridViewTextColumn>
<dot:GridViewTextColumn ValueBinding="{value: Status}"
HeaderText="Status"
HeaderCssClass="fit"
Expand All @@ -76,7 +84,7 @@
</dot:GridView>
</section>

<section Visible="{value: ActiveTab == 1}">
<section IncludeInPage="{value: ActiveTab == 1}" Visible={value: _page.EvaluatingOnClient}>
<h2>Controls</h2>
<dot:GridView DataSource="{value: Controls}" class="nowrap">
<RowDecorators>
Expand All @@ -89,7 +97,11 @@
HeaderCssClass="fit"
CssClass="fit" />
<dot:GridViewTextColumn ValueBinding="{value: TagName}" HeaderText="Tag" />
<dot:GridViewTextColumn ValueBinding="{value: VirtualPath}" HeaderText="Virtual Path" />
<dot:GridViewTextColumn ValueBinding="{value: VirtualPath}" HeaderText="Virtual Path">
<CellDecorators>
<dot:Decorator title={value: VirtualPath} />
</CellDecorators>
</dot:GridViewTextColumn>
<dot:GridViewTextColumn ValueBinding="{value: Status}"
HeaderText="Status"
HeaderCssClass="fit"
Expand All @@ -103,7 +115,7 @@
</dot:GridView>
</section>

<section Visible="{value: ActiveTab == 2}">
<section IncludeInPage="{value: ActiveTab == 2}" Visible={value: _page.EvaluatingOnClient}>
<h2>Master pages</h2>
<dot:GridView DataSource="{value: MasterPages}" class="nowrap">

Expand All @@ -112,11 +124,15 @@
Class-success="{value: Status == 'CompletedSuccessfully'}" />
</RowDecorators>
<Columns>
<dot:GridViewTextColumn ValueBinding="{value: VirtualPath}" HeaderText="Virtual Path" />
<dot:GridViewTextColumn ValueBinding="{value: VirtualPath}" HeaderText="Virtual Path">
<CellDecorators>
<dot:Decorator title={value: VirtualPath} />
</CellDecorators>
</dot:GridViewTextColumn>
<dot:GridViewTextColumn ValueBinding="{value: Status}"
HeaderText="Status"
HeaderCssClass="fit"
CssClass="fit status" />
CssClass="fit status"/>
<dot:GridViewTemplateColumn HeaderText="Actions" HeaderCssClass="fit" CssClass="fit">
<ContentTemplate>
<span Visible="{value: Status != CompilationState.NonCompilable}">
Expand All @@ -127,6 +143,67 @@
</Columns>
</dot:GridView>
</section>
<section IncludeInPage={value: ActiveTab == 3} Visible={value: _page.EvaluatingOnClient} >
<h2>Errors</h2>

<p IncludeInPage={value: MasterPages.AsEnumerable().Any(m => m.Status == 'None') || Controls.AsEnumerable().Any(m => m.Status == 'None') || Routes.AsEnumerable().Any(m => m.Status == 'None')}
style="color: var(--error-dark-color)">
Some files have not been compiled yet. Please press the "Compile all" button to make the list of errors complete.
</p>
<table>
<thead>
<th>Type</th>
<th>Name</th>
<th>File path</th>
<th>Status</th>
<th>Actions</th>
</thead>
<dot:Repeater DataSource={value: Routes.Where(r => r.Status == 'CompilationFailed')} WrapperTagName=tbody >
<tr class="failure">
<td>Route</td>
<td title={value: $"{Url} -> {RouteName}"}>
<span IncludeInPage={value: !HasParameters}>
<a href="{value: _root.PathBase + Url}">{{value: RouteName}}</a>
</span>
<span IncludeInPage={value: HasParameters}>
{{value: RouteName}}
</span>
</td>
<td title={value: VirtualPath}>{{value: VirtualPath}}</td>
<td>{{value: Status}}</td>
<td>
<dot:LinkButton Click="{command: _root.BuildView(_this)}" Text="Recompile" class="execute" />
</td>
</tr>
</dot:Repeater>
<dot:Repeater DataSource={value: Controls.Where(r => r.Status == 'CompilationFailed')} WrapperTagName=tbody >
<tr class="failure">
<td>Control</td>
<td>
{{value: $"{TagPrefix}:{TagName}"}}
</td>
<td title={value: VirtualPath}>{{value: VirtualPath}}</td>
<td>{{value: Status}}</td>
<td>
<dot:LinkButton Click="{command: _root.BuildView(_this)}" Text="Recompile" class="execute" />
</td>
</tr>
</dot:Repeater>
<dot:Repeater DataSource={value: MasterPages.Where(r => r.Status == 'CompilationFailed')} WrapperTagName=tbody >
<tr class="failure">
<td>Master page</td>
<td></td>
<td title={value: VirtualPath}>{{value: VirtualPath}}</td>
<td>{{value: Status}}</td>
<td>
<dot:LinkButton Click="{command: _root.BuildView(_this)}" Text="Recompile" class="execute" />
</td>
</tr>
</dot:Repeater>


</table>
</section>
</main>
<hr />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class CompilationPageViewModel : DotvvmViewModelBase
public ImmutableArray<DotHtmlFileInfo> MasterPages => viewCompilationService.GetMasterPages();
public ImmutableArray<DotHtmlFileInfo> Controls => viewCompilationService.GetControls();
public int ActiveTab { get; set; } = 0;
public string PathBase => Context.TranslateVirtualPath("~/");

public CompilationPageViewModel(IDotvvmViewCompilationService viewCompilationService)
{
Expand Down
Loading
Loading