protected override void Visit(ExpressionBlockChunk chunk) { var firstChildExpression = chunk.Children.FirstOrDefault() as ExpressionChunk; var padding = 0; MappingLocation documentLocation = null; if (firstChildExpression != null) { padding = _paddingBuilder.CalculateExpressionPadding((Span)firstChildExpression.Association); documentLocation = CreateMappingLocation(firstChildExpression.Start, firstChildExpression.Code.Length); } var expressionBlock = new CSharpBlock(); using (_context.Builder.UseBlock(expressionBlock)) { Accept(chunk.Children); } var renderExpression = new RenderExpression { Expression = expressionBlock, Padding = padding, DocumentLocation = documentLocation }; _context.Builder.Add(renderExpression); }
public void RenderDesignTimeExpressionBlockChunk(ExpressionBlockChunk chunk) { var firstChild = (ExpressionChunk)chunk.Children.FirstOrDefault(); if (firstChild != null) { var currentIndent = Writer.CurrentIndent; var designTimeAssignment = "__o = "; Writer.ResetIndent(); var documentLocation = firstChild.Association.Start; // This is only here to enable accurate formatting by the C# editor. Writer.WriteLineNumberDirective(documentLocation, Context.SourceFile); // We build the padding with an offset of the design time assignment statement. Writer.Write(_paddingBuilder.BuildExpressionPadding((Span)firstChild.Association, designTimeAssignment.Length)) .Write(designTimeAssignment); // We map the first line of code but do not write the line pragmas associated with it. CreateRawCodeMapping(firstChild.Code, documentLocation); // Render all but the first child. // The reason why we render the other children differently is because when formatting the C# code // the formatter expects the start line to have the assignment statement on it. Accept(chunk.Children.Skip(1).ToList()); Writer.WriteLine(";") .WriteLine() .WriteLineDefaultDirective() .WriteLineHiddenDirective() .SetIndent(currentIndent); } }
public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) { // TODO: Handle instrumentation if (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) { Accept(chunk.Children); } else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) { 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(); } }
protected override void Visit(ExpressionBlockChunk chunk) { if (Context.Host.DesignTimeMode) { RenderDesignTimeExpressionBlockChunk(chunk); } else { RenderRuntimeExpressionBlockChunk(chunk); } }
protected override void Visit(ExpressionBlockChunk chunk) { // TODO: Handle instrumentation if (Context.Host.DesignTimeMode) { RenderDesignTimeExpressionBlockChunk(chunk); } else { RenderRuntimeExpressionBlockChunk(chunk); } }
private void RenderRuntimeExpressionBlockChunkWithContentSpan(ExpressionBlockChunk chunk, Span contentSpan) { var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); if (generateInstrumentation) { Writer.WriteStartInstrumentationContext(Context, contentSpan, isLiteral: false); } using (var mappingWriter = new CSharpLineMappingWriter(Writer, chunk.Start, Context.SourceFile)) { if (!string.IsNullOrEmpty(Context.TargetWriterName)) { var generatedStart = WriteToMethodName.Length + Context.TargetWriterName.Length + 3; // 1 for the opening '(' and 2 for ', ' var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); Writer .Write(padding) .WriteStartMethodInvocation(WriteToMethodName) .Write(Context.TargetWriterName) .WriteParameterSeparator(); } else { var generatedStart = WriteMethodName.Length + 1; // for the opening '(' var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); Writer .Write(padding) .WriteStartMethodInvocation(WriteMethodName); } Accept(chunk.Children); Writer.WriteEndMethodInvocation(); } if (generateInstrumentation) { Writer.WriteEndInstrumentationContext(Context); } }
public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) { // 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 (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) { Accept(chunk.Children); } else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) { if (contentSpan != null) { RenderRuntimeExpressionBlockChunkWithContentSpan(chunk, contentSpan); } else { if (!string.IsNullOrEmpty(Context.TargetWriterName)) { Writer .WriteStartMethodInvocation(WriteToMethodName) .Write(Context.TargetWriterName) .WriteParameterSeparator(); } else { Writer.WriteStartMethodInvocation(WriteMethodName); } Accept(chunk.Children); Writer.WriteEndMethodInvocation() .WriteLine(); } } }
protected abstract void Visit(ExpressionBlockChunk chunk);
protected override void Visit(ExpressionBlockChunk chunk) { }
/// <summary> /// Writes code for the given <paramref name="chunk"/>. /// </summary> /// <param name="chunk">The <see cref="ExpressionBlockChunk"/> to render.</param> protected override void Visit(ExpressionBlockChunk chunk) { Accept(chunk.Children); }
protected virtual void Visit(ExpressionBlockChunk chunk) { }