Skip to content

Commit 07d59c6

Browse files
Change WritePadding extension to target CodeRenderingContext
Because `CodeRenderingContext` owns the `CodeWriter` instance used for code gen, and the `WritePadding` extension method targets `CodeWriter` and also takes a `CodeRenderingContext`, we can change it can target `CodeRenderingContext`.
1 parent 9e67d40 commit 07d59c6

File tree

5 files changed

+104
-90
lines changed

5 files changed

+104
-90
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeRenderingContextExtensions.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,55 @@
66
using System.Diagnostics;
77
using Microsoft.AspNetCore.Razor.Language.Intermediate;
88
using Microsoft.AspNetCore.Razor.Utilities;
9+
using Microsoft.CodeAnalysis.Text;
910
using static Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions;
1011

1112
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration;
1213

1314
internal static class CodeRenderingContextExtensions
1415
{
16+
public static void WritePadding(this CodeRenderingContext context, int offset, SourceSpan? span)
17+
{
18+
if (span is not SourceSpan spanValue)
19+
{
20+
return;
21+
}
22+
23+
var sourceDocument = context.SourceDocument;
24+
25+
if (sourceDocument.FilePath != null &&
26+
!string.Equals(sourceDocument.FilePath, spanValue.FilePath, StringComparison.OrdinalIgnoreCase))
27+
{
28+
// We don't want to generate padding for nodes from imports.
29+
return;
30+
}
31+
32+
var basePadding = CalculatePadding(sourceDocument.Text, spanValue);
33+
var resolvedPadding = Math.Max(basePadding - offset, 0);
34+
35+
context.CodeWriter.Indent(resolvedPadding);
36+
37+
static int CalculatePadding(SourceText text, SourceSpan span)
38+
{
39+
var spaceCount = 0;
40+
for (var i = span.AbsoluteIndex - 1; i >= 0; i--)
41+
{
42+
var @char = text[i];
43+
if (@char == '\n' || @char == '\r')
44+
{
45+
break;
46+
}
47+
else
48+
{
49+
// Note that a tab is also replaced with a single space so character indices match.
50+
spaceCount++;
51+
}
52+
}
53+
54+
return spaceCount;
55+
}
56+
}
57+
1558
public static CSharpCodeWritingScope BuildNamespace(this CodeRenderingContext context, string? name, SourceSpan? span)
1659
{
1760
var writer = context.CodeWriter;
@@ -365,7 +408,7 @@ public LinePragmaScope(
365408
// If the caller requested an enhanced line directive, but we fell back to regular ones, write out the extra padding that is required
366409
if (!_context.Options.UseEnhancedLinePragma)
367410
{
368-
writer.WritePadding(0, span, context);
411+
context.WritePadding(offset: 0, span);
369412
characterOffset = 0;
370413
}
371414

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriterExtensions.cs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,48 +37,6 @@ public static bool IsAtBeginningOfLine(this CodeWriter writer)
3737
return writer.LastChar is '\n';
3838
}
3939

40-
public static CodeWriter WritePadding(this CodeWriter writer, int offset, SourceSpan? span, CodeRenderingContext context)
41-
{
42-
if (span == null)
43-
{
44-
return writer;
45-
}
46-
47-
if (context.SourceDocument.FilePath != null &&
48-
!string.Equals(context.SourceDocument.FilePath, span.Value.FilePath, StringComparison.OrdinalIgnoreCase))
49-
{
50-
// We don't want to generate padding for nodes from imports.
51-
return writer;
52-
}
53-
54-
var basePadding = CalculatePadding();
55-
var resolvedPadding = Math.Max(basePadding - offset, 0);
56-
57-
writer.Indent(resolvedPadding);
58-
59-
return writer;
60-
61-
int CalculatePadding()
62-
{
63-
var spaceCount = 0;
64-
for (var i = span.Value.AbsoluteIndex - 1; i >= 0; i--)
65-
{
66-
var @char = context.SourceDocument.Text[i];
67-
if (@char == '\n' || @char == '\r')
68-
{
69-
break;
70-
}
71-
else
72-
{
73-
// Note that a tab is also replaced with a single space so character indices match.
74-
spaceCount++;
75-
}
76-
}
77-
78-
return spaceCount;
79-
}
80-
}
81-
8240
public static CodeWriter WriteVariableDeclaration(this CodeWriter writer, string type, string name, string value)
8341
{
8442
writer.Write(type).Write(" ").Write(name);

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DesignTimeNodeWriter.cs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,22 @@ public override void WriteCSharpExpression(CodeRenderingContext context, CSharpE
5050
return;
5151
}
5252

53+
var writer = context.CodeWriter;
54+
5355
if (node.Source is SourceSpan source)
5456
{
5557
using (context.BuildLinePragma(source))
5658
{
5759
var offset = DesignTimeDirectivePass.DesignTimeVariable.Length + " = ".Length;
58-
context.CodeWriter.WritePadding(offset, source, context);
59-
context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
60+
context.WritePadding(offset, source);
61+
writer.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
6062

6163
foreach (var child in node.Children)
6264
{
6365
if (child is IntermediateToken { IsCSharp: true } token)
6466
{
6567
context.AddSourceMappingFor(token);
66-
context.CodeWriter.Write(token.Content);
68+
writer.Write(token.Content);
6769
}
6870
else
6971
{
@@ -72,25 +74,27 @@ public override void WriteCSharpExpression(CodeRenderingContext context, CSharpE
7274
}
7375
}
7476

75-
context.CodeWriter.WriteLine(";");
77+
writer.WriteLine(";");
7678
}
7779
}
7880
else
7981
{
80-
context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
81-
for (var i = 0; i < node.Children.Count; i++)
82+
writer.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
83+
84+
foreach (var child in node.Children)
8285
{
83-
if (node.Children[i] is IntermediateToken token && token.IsCSharp)
86+
if (child is IntermediateToken { IsCSharp: true } token)
8487
{
85-
context.CodeWriter.Write(token.Content);
88+
writer.Write(token.Content);
8689
}
8790
else
8891
{
8992
// There may be something else inside the expression like a Template or another extension node.
90-
context.RenderNode(node.Children[i]);
93+
context.RenderNode(child);
9194
}
9295
}
93-
context.CodeWriter.WriteLine(";");
96+
97+
writer.WriteLine(";");
9498
}
9599
}
96100

@@ -102,7 +106,7 @@ public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeInt
102106
{
103107
using (context.BuildLinePragma(source))
104108
{
105-
writer.WritePadding(0, source, context);
109+
context.WritePadding(offset: 0, source);
106110
RenderChildren(context, node);
107111
}
108112
}
@@ -157,35 +161,38 @@ public override void WriteCSharpExpressionAttributeValue(CodeRenderingContext co
157161
return;
158162
}
159163

164+
var writer = context.CodeWriter;
165+
160166
var firstChild = node.Children[0];
161167
if (firstChild.Source is SourceSpan source)
162168
{
163169
using (context.BuildLinePragma(source))
164170
{
165171
var offset = DesignTimeDirectivePass.DesignTimeVariable.Length + " = ".Length;
166-
context.CodeWriter.WritePadding(offset, source, context);
167-
context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
172+
context.WritePadding(offset, source);
173+
writer.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
168174

169-
for (var i = 0; i < node.Children.Count; i++)
175+
foreach (var child in node.Children)
170176
{
171-
if (node.Children[i] is IntermediateToken token && token.IsCSharp)
177+
if (child is IntermediateToken { IsCSharp: true } token)
172178
{
173179
context.AddSourceMappingFor(token);
174-
context.CodeWriter.Write(token.Content);
180+
writer.Write(token.Content);
175181
}
176182
else
177183
{
178184
// There may be something else inside the expression like a Template or another extension node.
179-
context.RenderNode(node.Children[i]);
185+
context.RenderNode(child);
180186
}
181187
}
182188

183-
context.CodeWriter.WriteLine(";");
189+
writer.WriteLine(";");
184190
}
185191
}
186192
else
187193
{
188-
context.CodeWriter.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
194+
writer.WriteStartAssignment(DesignTimeDirectivePass.DesignTimeVariable);
195+
189196
for (var i = 0; i < node.Children.Count; i++)
190197
{
191198
if (node.Children[i] is IntermediateToken token && token.IsCSharp)
@@ -195,15 +202,16 @@ public override void WriteCSharpExpressionAttributeValue(CodeRenderingContext co
195202
context.AddSourceMappingFor(token);
196203
}
197204

198-
context.CodeWriter.Write(token.Content);
205+
writer.Write(token.Content);
199206
}
200207
else
201208
{
202209
// There may be something else inside the expression like a Template or another extension node.
203210
context.RenderNode(node.Children[i]);
204211
}
205212
}
206-
context.CodeWriter.WriteLine(";");
213+
214+
writer.WriteLine(";");
207215
}
208216
}
209217

@@ -221,7 +229,7 @@ public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context,
221229
{
222230
using (context.BuildLinePragma(source))
223231
{
224-
context.CodeWriter.WritePadding(0, source, context);
232+
context.WritePadding(offset: 0, source);
225233

226234
context.AddSourceMappingFor(token);
227235
context.CodeWriter.Write(token.Content);
@@ -230,7 +238,7 @@ public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context,
230238
continue;
231239
}
232240

233-
context.CodeWriter.WritePadding(0, source, context);
241+
context.WritePadding(offset: 0, source);
234242
}
235243
else if (isWhitespaceStatement)
236244
{

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

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ private void WriteCSharpExpressionInnards(CodeRenderingContext context, CSharpEx
109109
return;
110110
}
111111

112+
var writer = context.CodeWriter;
113+
112114
if (node.Source is SourceSpan source)
113115
{
114116
using (context.BuildLinePragma(source))
@@ -120,49 +122,51 @@ private void WriteCSharpExpressionInnards(CodeRenderingContext context, CSharpEx
120122
offset += type.Length + 2; // two parenthesis
121123
}
122124

123-
context.CodeWriter.WritePadding(offset, source, context);
124-
context.CodeWriter.WriteStartAssignment(DesignTimeVariable);
125+
context.WritePadding(offset, source);
126+
writer.WriteStartAssignment(DesignTimeVariable);
125127

126128
if (type != null)
127129
{
128-
context.CodeWriter.Write("(");
129-
TypeNameHelper.WriteGloballyQualifiedName(context.CodeWriter, type);
130-
context.CodeWriter.Write(")");
130+
writer.Write("(");
131+
TypeNameHelper.WriteGloballyQualifiedName(writer, type);
132+
writer.Write(")");
131133
}
132134

133-
for (var i = 0; i < node.Children.Count; i++)
135+
foreach (var child in node.Children)
134136
{
135-
if (node.Children[i] is IntermediateToken token && token.IsCSharp)
137+
if (child is IntermediateToken { IsCSharp: true } token)
136138
{
137139
context.AddSourceMappingFor(token);
138-
context.CodeWriter.Write(token.Content);
140+
writer.Write(token.Content);
139141
}
140142
else
141143
{
142144
// There may be something else inside the expression like a Template or another extension node.
143-
context.RenderNode(node.Children[i]);
145+
context.RenderNode(child);
144146
}
145147
}
146148

147-
context.CodeWriter.WriteLine(";");
149+
writer.WriteLine(";");
148150
}
149151
}
150152
else
151153
{
152-
context.CodeWriter.WriteStartAssignment(DesignTimeVariable);
153-
for (var i = 0; i < node.Children.Count; i++)
154+
writer.WriteStartAssignment(DesignTimeVariable);
155+
156+
foreach (var child in node.Children)
154157
{
155-
if (node.Children[i] is IntermediateToken token && token.IsCSharp)
158+
if (child is IntermediateToken { IsCSharp: true } token)
156159
{
157-
context.CodeWriter.Write(token.Content);
160+
writer.Write(token.Content);
158161
}
159162
else
160163
{
161164
// There may be something else inside the expression like a Template or another extension node.
162-
context.RenderNode(node.Children[i]);
165+
context.RenderNode(child);
163166
}
164167
}
165-
context.CodeWriter.WriteLine(";");
168+
169+
writer.WriteLine(";");
166170
}
167171
}
168172

@@ -184,14 +188,14 @@ public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeInt
184188
{
185189
using (context.BuildLinePragma(source))
186190
{
187-
context.CodeWriter.WritePadding(0, source, context);
191+
context.WritePadding(offset: 0, source);
188192
RenderChildren(context, node);
189193
}
190194

191195
return;
192196
}
193197

194-
context.CodeWriter.WritePadding(0, source, context);
198+
context.WritePadding(offset: 0, source);
195199
}
196200
else if (isWhitespaceStatement)
197201
{
@@ -731,7 +735,7 @@ private void WritePropertyAccess(CodeRenderingContext context, ComponentAttribut
731735

732736
using (context.BuildLinePragma(attributeSourceSpan))
733737
{
734-
context.CodeWriter.WritePadding(0, attributeSourceSpan, context);
738+
context.WritePadding(offset: 0, attributeSourceSpan);
735739
context.CodeWriter.WriteIdentifierEscapeIfNeeded(node.PropertyName);
736740
context.AddSourceMappingFor(attributeSourceSpan);
737741
context.CodeWriter.WriteLine(node.PropertyName);
@@ -1233,15 +1237,16 @@ private void WriteCSharpToken(CodeRenderingContext context, IntermediateToken to
12331237
return;
12341238
}
12351239

1236-
if (token.Source?.FilePath == null)
1240+
if (token.Source is not SourceSpan source ||
1241+
source.FilePath == null)
12371242
{
12381243
context.CodeWriter.Write(token.Content);
12391244
return;
12401245
}
12411246

1242-
using (context.BuildLinePragma(token.Source))
1247+
using (context.BuildLinePragma(source))
12431248
{
1244-
context.CodeWriter.WritePadding(0, token.Source.Value, context);
1249+
context.WritePadding(offset: 0, source);
12451250
context.AddSourceMappingFor(token);
12461251
context.CodeWriter.Write(token.Content);
12471252
}

0 commit comments

Comments
 (0)