public override SyntaxNode VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) { CSharpTransitionSyntax transition = null; var builder = SyntaxListBuilder <RazorSyntaxNode> .Create(); if (_rewriteAsMarkup) { // Convert transition. // Change to a MarkupChunkGenerator so that the '@' \ parenthesis is generated as part of the output. var context = node.GetSpanContext(); var newContext = new SpanContext(new MarkupChunkGenerator(), context?.EditHandler ?? SpanEditHandler.CreateDefault((content) => Enumerable.Empty <Syntax.InternalSyntax.SyntaxToken>())); var expression = SyntaxFactory.CSharpExpressionLiteral(new SyntaxList <SyntaxToken>(node.Transition.Transition)).WithSpanContext(newContext); expression = (CSharpExpressionLiteralSyntax)VisitCSharpExpressionLiteral(expression); builder.Add(expression); // Since the original transition is part of the body, we need something to take it's place. transition = SyntaxFactory.CSharpTransition(SyntaxFactory.MissingToken(SyntaxKind.Transition)); var body = (CSharpExplicitExpressionBodySyntax)node.Body; var rewrittenOpenParen = (RazorSyntaxNode)VisitRazorMetaCode(body.OpenParen); var rewrittenBody = (CSharpCodeBlockSyntax)VisitCSharpCodeBlock(body.CSharpCode); var rewrittenCloseParen = (RazorSyntaxNode)VisitRazorMetaCode(body.CloseParen); builder.Add(rewrittenOpenParen); builder.AddRange(rewrittenBody.Children); builder.Add(rewrittenCloseParen); } else { // This is the first expression of a non-string attribute like attr=@(a + b) // Below code converts this to an implicit expression to make the parens // part of the expression so that it is rendered. transition = (CSharpTransitionSyntax)Visit(node.Transition); var body = (CSharpExplicitExpressionBodySyntax)node.Body; var rewrittenOpenParen = (RazorSyntaxNode)VisitRazorMetaCode(body.OpenParen); var rewrittenBody = (CSharpCodeBlockSyntax)VisitCSharpCodeBlock(body.CSharpCode); var rewrittenCloseParen = (RazorSyntaxNode)VisitRazorMetaCode(body.CloseParen); builder.Add(rewrittenOpenParen); builder.AddRange(rewrittenBody.Children); builder.Add(rewrittenCloseParen); } var rewrittenCodeBlock = SyntaxFactory.CSharpCodeBlock(builder.ToList()); return(SyntaxFactory.CSharpImplicitExpression(transition, SyntaxFactory.CSharpImplicitExpressionBody(rewrittenCodeBlock))); }
// CSharp expressions are broken up into blocks and spans because Razor allows Razor comments // inside an expression. // Ex: // @DateTime.@*This is a comment*@Now // // We need to capture this in the IR so that we can give each piece the correct source mappings public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) { if (_builder.Current is CSharpExpressionAttributeValueIntermediateNode) { base.VisitCSharpExplicitExpression(node); return; } var expressionNode = new CSharpExpressionIntermediateNode(); _builder.Push(expressionNode); base.VisitCSharpExplicitExpression(node); _builder.Pop(); if (expressionNode.Children.Count > 0) { var sourceRangeStart = expressionNode .Children .FirstOrDefault(child => child.Source != null) ?.Source; if (sourceRangeStart != null) { var contentLength = expressionNode.Children.Sum(child => child.Source?.Length ?? 0); expressionNode.Source = new SourceSpan( sourceRangeStart.Value.FilePath ?? SourceDocument.FilePath, sourceRangeStart.Value.AbsoluteIndex, sourceRangeStart.Value.LineIndex, sourceRangeStart.Value.CharacterIndex, contentLength); } } }
public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) { WriteBlock(node, FormattingBlockKind.Expression, base.VisitCSharpExplicitExpression); }
public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) { AddSemanticRange(node.Transition, RazorSemanticTokensLegend.RazorTransition); Visit(node.Body); }
public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node) { WriteBlock(node, BlockKindInternal.Expression, base.VisitCSharpExplicitExpression); }