-
Notifications
You must be signed in to change notification settings - Fork 223
Updating CSharpCodeVisitor to generate implicit expressions on a single line #171
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -149,7 +149,7 @@ protected override void Visit(ExpressionBlockChunk chunk) | |
|
||
protected override void Visit(ExpressionChunk chunk) | ||
{ | ||
CreateExpressionCodeMapping(chunk.Code, chunk); | ||
Writer.Write(chunk.Code); | ||
} | ||
|
||
protected override void Visit(StatementChunk chunk) | ||
|
@@ -343,66 +343,103 @@ public void RenderDesignTimeExpressionBlockChunk(ExpressionBlockChunk chunk) | |
|
||
public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) | ||
{ | ||
var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); | ||
Span contentSpan = null; | ||
// For expression chunks, such as @value, @(value) etc, pick the first Code or Markup span | ||
// from the expression (in this case "value") and use that to calculate the length. This works | ||
// accurately for most parts. The scenarios that don't work are | ||
// (a) Expressions with inline comments (e.g. @(a @* comment *@ b)) - these have multiple code spans | ||
// (b) Expressions with inline templates (e.g. @Foo(@<p>Hello world</p>)). | ||
// Tracked via https://github.com/aspnet/Razor/issues/153 | ||
|
||
var block = (Block)chunk.Association; | ||
var contentSpan = block.Children | ||
.OfType<Span>() | ||
.FirstOrDefault(s => s.Kind == SpanKind.Code || s.Kind == SpanKind.Markup); | ||
|
||
if (generateInstrumentation) | ||
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) | ||
{ | ||
Accept(chunk.Children); | ||
} | ||
else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) | ||
{ | ||
// For expression chunks, such as @value, @(value) etc, pick the first Code or Markup span | ||
// from the expression (in this case "value") and use that to calculate the length. This works | ||
// accurately for most parts. The scenarios that don't work are | ||
// (a) Expressions with inline comments (e.g. @(a @* comment *@ b)) - these have multiple code spans | ||
// (b) Expressions with inline templates (e.g. @Foo(@<p>Hello world</p>)). | ||
// Tracked via https://github.com/aspnet/Razor/issues/153 | ||
|
||
var block = (Block)chunk.Association; | ||
contentSpan = block.Children | ||
.OfType<Span>() | ||
.FirstOrDefault(s => s.Kind == SpanKind.Code || s.Kind == SpanKind.Markup); | ||
|
||
if (contentSpan != null) | ||
{ | ||
Writer.WriteStartInstrumentationContext(Context, contentSpan, isLiteral: false); | ||
RenderRuntimeExpressionBlockChunkWithContentSpan(chunk, contentSpan); | ||
} | ||
else | ||
{ | ||
if (!string.IsNullOrEmpty(Context.TargetWriterName)) | ||
{ | ||
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteToMethodName) | ||
.Write(Context.TargetWriterName) | ||
.WriteParameterSeparator(); | ||
} | ||
else | ||
{ | ||
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteMethodName); | ||
} | ||
|
||
Accept(chunk.Children); | ||
|
||
Writer.WriteEndMethodInvocation() | ||
.WriteLine(); | ||
} | ||
} | ||
} | ||
|
||
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) | ||
private void RenderRuntimeExpressionBlockChunkWithContentSpan(ExpressionBlockChunk chunk, Span contentSpan) | ||
{ | ||
var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); | ||
|
||
if (generateInstrumentation) | ||
{ | ||
Accept(chunk.Children); | ||
Writer.WriteStartInstrumentationContext(Context, contentSpan, isLiteral: false); | ||
} | ||
else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) | ||
|
||
using (var mappingWriter = new CSharpLineMappingWriter(Writer, chunk.Start, Context.SourceFile)) | ||
{ | ||
if (!String.IsNullOrEmpty(Context.TargetWriterName)) | ||
if (!string.IsNullOrEmpty(Context.TargetWriterName)) | ||
{ | ||
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteToMethodName) | ||
var generatedStart = Context.Host.GeneratedClassContext.WriteToMethodName.Length + | ||
Context.TargetWriterName.Length + | ||
3; // 1 for the opening '(' and 2 for ', ' | ||
|
||
var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: extra line. |
||
|
||
Writer.Write(padding) | ||
.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteToMethodName) | ||
.Write(Context.TargetWriterName) | ||
.WriteParameterSeparator(); | ||
} | ||
else | ||
{ | ||
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteMethodName); | ||
var generatedStart = Context.Host.GeneratedClassContext.WriteMethodName.Length + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we could potentially calculate the |
||
1; // for the opening '(' | ||
var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); | ||
|
||
Writer.Write(padding) | ||
.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteMethodName); | ||
} | ||
|
||
Accept(chunk.Children); | ||
|
||
Writer.WriteEndMethodInvocation() | ||
.WriteLine(); | ||
Writer.WriteEndMethodInvocation(); | ||
} | ||
|
||
if (contentSpan != null) | ||
if (generateInstrumentation) | ||
{ | ||
Writer.WriteEndInstrumentationContext(Context); | ||
} | ||
} | ||
|
||
public void CreateExpressionCodeMapping(string code, Chunk chunk) | ||
public void CreateStatementCodeMapping(string code, Chunk chunk) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why re-order these methods? Or am I missing something. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bad merge. |
||
{ | ||
CreateCodeMapping(_paddingBuilder.BuildExpressionPadding((Span)chunk.Association), code, chunk); | ||
CreateCodeMapping(_paddingBuilder.BuildStatementPadding((Span)chunk.Association), code, chunk); | ||
} | ||
|
||
public void CreateStatementCodeMapping(string code, Chunk chunk) | ||
public void CreateExpressionCodeMapping(string code, Chunk chunk) | ||
{ | ||
CreateCodeMapping(_paddingBuilder.BuildStatementPadding((Span)chunk.Association), code, chunk); | ||
CreateCodeMapping(_paddingBuilder.BuildExpressionPadding((Span)chunk.Association), code, chunk); | ||
} | ||
|
||
public void CreateCodeMapping(string padding, string code, Chunk chunk) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we could potentially calculate the
generatedStart
preset value once on the creation of the visitor. Up to you if you think its worth it.