Skip to content

Commit b73e3f4

Browse files
Fix up compiler passes using FindDescendantNodes
Now that `FindDirectiveReferences` returns an `ImmutableArray`, several compiler passes need to be adjusted. - Use `Length` rather than `Count`. - Prefer foreach statements now that we're not contending with an `IReadOnlyList`. - Enable nullability where it was trivial.
1 parent 5604593 commit b73e3f4

10 files changed

+38
-66
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentBindLoweringPass.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,12 +1097,12 @@ private void RewriteNodesForElementEventCallbackBind(
10971097
private static IntermediateToken GetAttributeContent(IntermediateNode node)
10981098
{
10991099
var nodes = node.FindDescendantNodes<TemplateIntermediateNode>();
1100-
var template = nodes.Count > 0 ? nodes[0] : default;
1100+
var template = nodes.Length > 0 ? nodes[0] : default;
11011101
if (template != null)
11021102
{
11031103
// See comments in TemplateDiagnosticPass
11041104
node.AddDiagnostic(ComponentDiagnosticFactory.Create_TemplateInvalidLocation(template.Source));
1105-
return new IntermediateToken() { Kind = TokenKind.CSharp, Content = string.Empty, };
1105+
return new IntermediateToken() { Kind = TokenKind.CSharp, Content = string.Empty };
11061106
}
11071107

11081108
if (node.Children[0] is HtmlContentIntermediateNode htmlContentNode)

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentComplexAttributeContentPass.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System.Linq;
75
using Microsoft.AspNetCore.Razor.Language.Intermediate;
86

@@ -25,10 +23,9 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
2523
return;
2624
}
2725

28-
var nodes = documentNode.FindDescendantNodes<TagHelperIntermediateNode>();
29-
for (var i = 0; i < nodes.Count; i++)
26+
foreach (var node in documentNode.FindDescendantNodes<TagHelperIntermediateNode>())
3027
{
31-
ProcessAttributes(nodes[i]);
28+
ProcessAttributes(node);
3229
}
3330
}
3431

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentCssScopePass.cs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,15 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
2424
return;
2525
}
2626

27-
var nodes = documentNode.FindDescendantNodes<MarkupElementIntermediateNode>();
28-
for (var i = 0; i < nodes.Count; i++)
27+
foreach (var node in documentNode.FindDescendantNodes<MarkupElementIntermediateNode>())
2928
{
30-
ProcessElement(nodes[i], cssScope);
29+
// Add a minimized attribute whose name is simply the CSS scope
30+
node.Children.Add(new HtmlAttributeIntermediateNode
31+
{
32+
AttributeName = cssScope,
33+
Prefix = cssScope,
34+
Suffix = string.Empty,
35+
});
3136
}
3237
}
33-
34-
private void ProcessElement(MarkupElementIntermediateNode node, string cssScope)
35-
{
36-
// Add a minimized attribute whose name is simply the CSS scope
37-
node.Children.Add(new HtmlAttributeIntermediateNode
38-
{
39-
AttributeName = cssScope,
40-
Prefix = cssScope,
41-
Suffix = string.Empty,
42-
});
43-
}
4438
}

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentDesignTimeNodeWriter.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System;
75
using System.Collections.Generic;
86
using System.Diagnostics;
@@ -104,7 +102,7 @@ public override void WriteCSharpExpression(CodeRenderingContext context, CSharpE
104102
WriteCSharpExpressionInnards(context, node);
105103
}
106104

107-
private void WriteCSharpExpressionInnards(CodeRenderingContext context, CSharpExpressionIntermediateNode node, string type = null)
105+
private void WriteCSharpExpressionInnards(CodeRenderingContext context, CSharpExpressionIntermediateNode node, string? type = null)
108106
{
109107
if (node.Children.Count == 0)
110108
{
@@ -191,7 +189,7 @@ public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeInt
191189
}
192190
}
193191

194-
IDisposable linePragmaScope = null;
192+
IDisposable? linePragmaScope = null;
195193
if (node.Source != null)
196194
{
197195
if (!isWhitespaceStatement)
@@ -372,7 +370,7 @@ public override void WriteComponent(CodeRenderingContext context, ComponentInter
372370

373371
// We might need a scope for inferring types,
374372
CodeWriterExtensions.CSharpCodeWritingScope? typeInferenceCaptureScope = null;
375-
string typeInferenceLocalName = null;
373+
string? typeInferenceLocalName = null;
376374

377375
var suppressTypeInference = ShouldSuppressTypeInferenceCall(node);
378376
if (suppressTypeInference)
@@ -563,7 +561,7 @@ public override void WriteComponent(CodeRenderingContext context, ComponentInter
563561
// the "usings directive is unnecessary" message.
564562
// Looks like:
565563
// __o = typeof(SomeNamespace.SomeComponent);
566-
using (context.CodeWriter.BuildLinePragma(node.Source.Value, context))
564+
using (context.CodeWriter.BuildLinePragma(node.Source.AssumeNotNull(), context))
567565
{
568566
context.CodeWriter.Write(DesignTimeVariable);
569567
context.CodeWriter.Write(" = ");
@@ -677,7 +675,7 @@ public override void WriteComponentAttribute(CodeRenderingContext context, Compo
677675
context.CodeWriter.WriteLine();
678676
}
679677

680-
private void WritePropertyAccess(CodeRenderingContext context, ComponentAttributeIntermediateNode node, ComponentIntermediateNode componentNode, string typeInferenceLocalName, bool shouldWriteBL0005Disable, out bool wrotePropertyAccess)
678+
private void WritePropertyAccess(CodeRenderingContext context, ComponentAttributeIntermediateNode node, ComponentIntermediateNode componentNode, string? typeInferenceLocalName, bool shouldWriteBL0005Disable, out bool wrotePropertyAccess)
681679
{
682680
wrotePropertyAccess = false;
683681
if (node?.TagHelper?.Name is null || node.OriginalAttributeSpan is null)

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentEventHandlerLoweringPass.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Generic;
5+
using System.Collections.Immutable;
56
using System.Linq;
67
using Microsoft.AspNetCore.Razor.Language.Extensions;
78
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@@ -156,7 +157,7 @@ private static void ProcessDuplicates(IntermediateNode parent)
156157
private static IntermediateNode RewriteUsage(IntermediateNode parent, TagHelperDirectiveAttributeIntermediateNode node)
157158
{
158159
var original = GetAttributeContent(node);
159-
if (original.Count == 0)
160+
if (original.Length == 0)
160161
{
161162
// This can happen in error cases, the parser will already have flagged this
162163
// as an error, so ignore it.
@@ -171,8 +172,8 @@ private static IntermediateNode RewriteUsage(IntermediateNode parent, TagHelperD
171172
// correct context for intellisense when typing in the attribute.
172173
var eventArgsType = node.TagHelper.GetEventArgsType();
173174

174-
using var _ = ListPool<IntermediateToken>.GetPooledObject(out var tokens);
175-
tokens.SetCapacityIfLarger(original.Count + 2);
175+
using var tokens = new PooledArrayBuilder<IntermediateToken>(original.Length + 2);
176+
tokens.SetCapacityIfLarger(original.Length + 2);
176177

177178
tokens.Add(
178179
new IntermediateToken()
@@ -181,10 +182,7 @@ private static IntermediateNode RewriteUsage(IntermediateNode parent, TagHelperD
181182
Kind = TokenKind.CSharp
182183
});
183184

184-
for (var i = 0; i < original.Count; i++)
185-
{
186-
tokens.Add(original[i]);
187-
}
185+
tokens.AddRange(original);
188186

189187
tokens.Add(
190188
new IntermediateToken()
@@ -240,15 +238,15 @@ private static IntermediateNode RewriteUsage(IntermediateNode parent, TagHelperD
240238
}
241239
}
242240

243-
private static IReadOnlyList<IntermediateToken> GetAttributeContent(IntermediateNode node)
241+
private static ImmutableArray<IntermediateToken> GetAttributeContent(IntermediateNode node)
244242
{
245243
var nodes = node.FindDescendantNodes<TemplateIntermediateNode>();
246-
var template = nodes.Count > 0 ? nodes[0] : default;
244+
var template = nodes.Length > 0 ? nodes[0] : null;
247245
if (template != null)
248246
{
249247
// See comments in TemplateDiagnosticPass
250248
node.AddDiagnostic(ComponentDiagnosticFactory.Create_TemplateInvalidLocation(template.Source));
251-
return new[] { new IntermediateToken() { Kind = TokenKind.CSharp, Content = string.Empty, }, };
249+
return [new IntermediateToken() { Kind = TokenKind.CSharp, Content = string.Empty }];
252250
}
253251

254252
if (node.Children.Count == 1 && node.Children[0] is HtmlContentIntermediateNode htmlContentNode)
@@ -258,12 +256,10 @@ private static IReadOnlyList<IntermediateToken> GetAttributeContent(Intermediate
258256
var tokens = htmlContentNode.FindDescendantNodes<IntermediateToken>();
259257

260258
var content = "\"" + string.Join(string.Empty, tokens.Select(t => t.Content.Replace("\"", "\\\""))) + "\"";
261-
return new[] { new IntermediateToken() { Content = content, Kind = TokenKind.CSharp, } };
262-
}
263-
else
264-
{
265-
return node.FindDescendantNodes<IntermediateToken>();
259+
return [new IntermediateToken() { Content = content, Kind = TokenKind.CSharp }];
266260
}
261+
262+
return node.FindDescendantNodes<IntermediateToken>();
267263
}
268264

269265
private static IntermediateNode RewriteParameterUsage(TagHelperDirectiveAttributeParameterIntermediateNode node)

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentRuntimeNodeWriter.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System;
75
using System.Collections.Generic;
86
using System.Diagnostics;

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentSplatLoweringPass.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
1818
return;
1919
}
2020

21-
var references = documentNode.FindDescendantReferences<TagHelperDirectiveAttributeIntermediateNode>();
22-
23-
foreach (var reference in references)
21+
foreach (var reference in documentNode.FindDescendantReferences<TagHelperDirectiveAttributeIntermediateNode>())
2422
{
2523
var node = (TagHelperDirectiveAttributeIntermediateNode)reference.Node;
2624
if (node.TagHelper.IsSplatTagHelper())

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/DefaultTagHelperOptimizationPass.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System.Collections.Generic;
75
using System.Linq;
86
using Microsoft.AspNetCore.Razor.Language.Intermediate;

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/ViewCssScopePass.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System;
75
using Microsoft.AspNetCore.Razor.Language.Intermediate;
86

@@ -28,23 +26,22 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
2826
}
2927

3028
var scopeWithSeparator = " " + cssScope;
31-
var nodes = documentNode.FindDescendantNodes<HtmlContentIntermediateNode>();
32-
IntermediateToken previousTokenOpt = null;
33-
foreach (var node in nodes)
29+
IntermediateToken? previousToken = null;
30+
foreach (var node in documentNode.FindDescendantNodes<HtmlContentIntermediateNode>())
3431
{
35-
ProcessElement(node, scopeWithSeparator, ref previousTokenOpt);
32+
ProcessElement(node, scopeWithSeparator, ref previousToken);
3633
}
3734
}
3835

39-
private void ProcessElement(HtmlContentIntermediateNode node, string cssScope, ref IntermediateToken previousTokenOpt)
36+
private void ProcessElement(HtmlContentIntermediateNode node, string cssScope, ref IntermediateToken? previousToken)
4037
{
4138
// Add a minimized attribute whose name is simply the CSS scope
4239
for (var i = 0; i < node.Children.Count; i++)
4340
{
4441
var child = node.Children[i];
4542
if (child is IntermediateToken token && token.IsHtml)
4643
{
47-
if (IsValidElement(token, previousTokenOpt))
44+
if (IsValidElement(token, previousToken))
4845
{
4946
node.Children.Insert(i + 1, new IntermediateToken()
5047
{
@@ -55,16 +52,16 @@ private void ProcessElement(HtmlContentIntermediateNode node, string cssScope, r
5552
i++;
5653
}
5754

58-
previousTokenOpt = token;
55+
previousToken = token;
5956
}
6057
}
6158

62-
static bool IsValidElement(IntermediateToken token, IntermediateToken previousTokenOpt)
59+
static bool IsValidElement(IntermediateToken token, IntermediateToken? previousToken)
6360
{
6461
var content = token.Content.AsSpan();
6562

6663
// `<!tag` is lowered into separate nodes `<` and `tag`, we process the latter.
67-
if (previousTokenOpt?.Content == "<" && content is [not '<', ..])
64+
if (previousToken?.Content == "<" && content is [not '<', ..])
6865
{
6966
// There is no leading `<` to trim.
7067
}

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperPass.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System.Collections.Generic;
75
using Microsoft.AspNetCore.Razor.Language;
86
using Microsoft.AspNetCore.Razor.Language.Extensions;
@@ -36,10 +34,8 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
3634

3735
// For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct
3836
// and set properties on the the correct field, and using the name of the type we will generate.
39-
var nodes = documentNode.FindDescendantNodes<TagHelperIntermediateNode>();
40-
for (var i = 0; i < nodes.Count; i++)
37+
foreach (var node in documentNode.FindDescendantNodes<TagHelperIntermediateNode>())
4138
{
42-
var node = nodes[i];
4339
foreach (var tagHelper in node.TagHelpers)
4440
{
4541
RewriteUsage(context, node, tagHelper);

0 commit comments

Comments
 (0)