From 1ae0b216306e72c128c91b116775e6fa3a88a8ea Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 17 Feb 2017 10:49:29 -0800 Subject: [PATCH] Replace CSharpIRToken with RazorIRToken Deletes CSharpIRToken to use the more general RazorIRToken class. Rather than using the visitor to visit tokens, now writing a CSharpExpresionIRNode is an 'atom', and will write its tokens itself. --- .../DesignTimeCSharpRenderer.cs | 36 +++++++++-------- .../PageStructureCSharpRenderer.cs | 4 +- .../CodeGeneration/RuntimeCSharpRenderer.cs | 22 +++++++---- .../DefaultRazorIRLoweringPhase.cs | 11 +++--- .../Intermediate/CSharpTokenIRNode.cs | 39 ------------------- .../Intermediate/RazorIRNodeVisitor.cs | 5 --- .../Intermediate/RazorIRNodeVisitorOfT.cs | 5 --- .../DefaultInstrumentationPassTest.cs | 12 ++++-- .../InstrumentationPassIntegrationTest.cs | 1 + .../IntegrationTests/RazorIRNodeWriter.cs | 6 --- .../Intermediate/RazorIRAssert.cs | 4 +- .../HtmlWithConditionalAttribute.ir.txt | 2 +- .../HtmlWithDataDashAttribute.ir.txt | 2 +- .../BasicTest.ir.txt | 4 +- .../TagHelpersWithBoundAttributes.ir.txt | 2 +- 15 files changed, 59 insertions(+), 96 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/CSharpTokenIRNode.cs diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/DesignTimeCSharpRenderer.cs b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/DesignTimeCSharpRenderer.cs index 46ee7b2d06..4992de82aa 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/DesignTimeCSharpRenderer.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/DesignTimeCSharpRenderer.cs @@ -14,11 +14,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration { } - public override void VisitCSharpToken(CSharpTokenIRNode node) - { - Context.Writer.Write(node.Content); - } - public override void VisitCSharpExpression(CSharpExpressionIRNode node) { if (node.Children.Count == 0) @@ -38,14 +33,17 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration for (var i = 0; i < node.Children.Count; i++) { - var childNode = node.Children[i]; - - if (childNode is CSharpTokenIRNode) + var token = node.Children[i] as RazorIRToken; + if (token != null && token.IsCSharp) { - AddLineMappingFor(childNode); + AddLineMappingFor(token); + Context.Writer.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + Visit(node.Children[i]); } - - childNode.Accept(this); } Context.Writer.WriteLine(";"); @@ -278,9 +276,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration private void AddLineMappingFor(RazorIRNode node) { - var sourceLocation = node.Source.Value; - var generatedLocation = new SourceSpan(Context.Writer.GetCurrentSourceLocation(), sourceLocation.Length); - var lineMapping = new LineMapping(sourceLocation, generatedLocation); + if (node.Source == null) + { + return; + } + + var source = node.Source.Value; + + var generatedLocation = new SourceSpan(Context.Writer.GetCurrentSourceLocation(), source.Length); + var lineMapping = new LineMapping(source, generatedLocation); Context.LineMappings.Add(lineMapping); } @@ -305,14 +309,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration Context.Writer.Write(((HtmlContentIRNode)node).Content); } - else if (node is CSharpTokenIRNode) + else if (node is RazorIRToken token && token.IsCSharp) { if (node.Source != null) { AddLineMappingFor(node); } - Context.Writer.Write(((CSharpTokenIRNode)node).Content); + Context.Writer.Write(token.Content); } else if (node is CSharpStatementIRNode) { diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/PageStructureCSharpRenderer.cs b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/PageStructureCSharpRenderer.cs index dde8a540d7..218668a645 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/PageStructureCSharpRenderer.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/PageStructureCSharpRenderer.cs @@ -116,9 +116,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration protected static void RenderExpressionInline(RazorIRNode node, CSharpRenderingContext context) { - if (node is CSharpTokenIRNode) + if (node is RazorIRToken token && token.IsCSharp) { - context.Writer.Write(((CSharpTokenIRNode)node).Content); + context.Writer.Write(token.Content); } else { diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/RuntimeCSharpRenderer.cs b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/RuntimeCSharpRenderer.cs index 71d48c265d..4e37c2a96c 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/RuntimeCSharpRenderer.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/CodeGeneration/RuntimeCSharpRenderer.cs @@ -32,11 +32,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration } } - public override void VisitCSharpToken(CSharpTokenIRNode node) - { - Context.Writer.Write(node.Content); - } - public override void VisitHtml(HtmlContentIRNode node) { const int MaxStringLiteralLength = 1024; @@ -78,7 +73,18 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration Context.Writer.Write(Context.RenderingConventions.StartWriteMethod); - VisitDefault(node); + for (var i = 0; i < node.Children.Count; i++) + { + if (node.Children[i] is RazorIRToken token && token.IsCSharp) + { + Context.Writer.Write(token.Content); + } + else + { + // There may be something else inside the expression like a Template or another extension node. + Visit(node.Children[i]); + } + } Context.Writer.WriteEndMethodInvocation(); @@ -651,9 +657,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration { Context.Writer.Write(((HtmlContentIRNode)node).Content); } - else if (node is CSharpTokenIRNode) + else if (node is RazorIRToken token && token.IsCSharp) { - Context.Writer.Write(((CSharpTokenIRNode)node).Content); + Context.Writer.Write(token.Content); } else if (node is CSharpStatementIRNode) { diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/DefaultRazorIRLoweringPhase.cs b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultRazorIRLoweringPhase.cs index 53ec9cb731..656569a8db 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/DefaultRazorIRLoweringPhase.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultRazorIRLoweringPhase.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution ThrowForMissingDependency(syntaxTree); var builder = RazorIRBuilder.Document(); - + var document = (DocumentIRNode)builder.Current; document.Options = syntaxTree.Options; @@ -58,11 +58,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution var visitor = new MainSourceVisitor(document, builder, namespaces) { - Filename = syntaxTree.Source.Filename, + Filename = syntaxTree.Source.Filename, }; visitor.VisitBlock(syntaxTree.Root); - + codeDocument.SetIRDocument(document); } @@ -304,7 +304,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution VisitDefault(block); _builder.Pop(); - + if (templateNode.Children.Count > 0) { var sourceRangeStart = templateNode @@ -376,9 +376,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution } } - _builder.Add(new CSharpTokenIRNode() + _builder.Add(new RazorIRToken() { Content = span.Content, + Kind = RazorIRToken.TokenKind.CSharp, Source = BuildSourceSpanFromNode(span), }); } diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/CSharpTokenIRNode.cs b/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/CSharpTokenIRNode.cs deleted file mode 100644 index 62c6079960..0000000000 --- a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/CSharpTokenIRNode.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate -{ - public class CSharpTokenIRNode : RazorIRNode - { - public override IList Children { get; } = EmptyArray; - - public override RazorIRNode Parent { get; set; } - - public override SourceSpan? Source { get; set; } - - public string Content { get; set; } - - public override void Accept(RazorIRNodeVisitor visitor) - { - if (visitor == null) - { - throw new ArgumentNullException(nameof(visitor)); - } - - visitor.VisitCSharpToken(this); - } - - public override TResult Accept(RazorIRNodeVisitor visitor) - { - if (visitor == null) - { - throw new ArgumentNullException(nameof(visitor)); - } - - return visitor.VisitCSharpToken(this); - } - } -} diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitor.cs b/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitor.cs index 318cddcb1a..bb8a842925 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitor.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitor.cs @@ -49,11 +49,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate VisitDefault(node); } - public virtual void VisitCSharpToken(CSharpTokenIRNode node) - { - VisitDefault(node); - } - public virtual void VisitHtmlAttributeValue(HtmlAttributeValueIRNode node) { VisitDefault(node); diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitorOfT.cs b/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitorOfT.cs index 7585a82ae9..d2188b3413 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitorOfT.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/RazorIRNodeVisitorOfT.cs @@ -50,11 +50,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate return VisitDefault(node); } - public virtual TResult VisitCSharpToken(CSharpTokenIRNode node) - { - return VisitDefault(node); - } - public virtual TResult VisitHtmlAttributeValue(HtmlAttributeValueIRNode node) { return VisitDefault(node); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/DefaultInstrumentationPassTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/DefaultInstrumentationPassTest.cs index 22b70a077a..f0489774a1 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/DefaultInstrumentationPassTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/DefaultInstrumentationPassTest.cs @@ -67,9 +67,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution { Source = CreateSource(2), }); - builder.Add(new CSharpTokenIRNode() + builder.Add(new RazorIRToken() { Content = "Hi", + Kind = RazorIRToken.TokenKind.CSharp, }); var irDocument = (DocumentIRNode)builder.Build(); @@ -93,9 +94,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution // Arrange var builder = RazorIRBuilder.Document(); builder.Push(new CSharpExpressionIRNode()); - builder.Add(new CSharpTokenIRNode() + builder.Add(new RazorIRToken() { Content = "Hi", + Kind = RazorIRToken.TokenKind.CSharp, }); var irDocument = (DocumentIRNode)builder.Build(); @@ -128,9 +130,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution Source = CreateSource(5) }); - builder.Add(new CSharpTokenIRNode() + builder.Add(new RazorIRToken() { Content = "Hi", + Kind = RazorIRToken.TokenKind.CSharp, }); var irDocument = (DocumentIRNode)builder.Build(); @@ -175,9 +178,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution Source = CreateSource(5) }); - builder.Add(new CSharpTokenIRNode() + builder.Add(new RazorIRToken() { Content = "Hi", + Kind = RazorIRToken.TokenKind.CSharp, }); var irDocument = (DocumentIRNode)builder.Build(); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/InstrumentationPassIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/InstrumentationPassIntegrationTest.cs index 71170f3783..ef96bead23 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/InstrumentationPassIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/InstrumentationPassIntegrationTest.cs @@ -61,6 +61,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests // Assert AssertIRMatchesBaseline(document.GetIRDocument()); + var csharpDocument = document.GetCSharpDocument(); AssertCSharpDocumentMatchesBaseline(csharpDocument); Assert.Empty(csharpDocument.Diagnostics); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorIRNodeWriter.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorIRNodeWriter.cs index 356e9c8e5b..cb8a192ce3 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorIRNodeWriter.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorIRNodeWriter.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -42,11 +41,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests WriteContentNode(node, node.Content); } - public override void VisitCSharpToken(CSharpTokenIRNode node) - { - WriteContentNode(node, node.Content); - } - public override void VisitToken(RazorIRToken node) { WriteContentNode(node, node.Kind.ToString(), node.Content); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/Intermediate/RazorIRAssert.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/Intermediate/RazorIRAssert.cs index 2f92bb5ee5..d3d4610ea6 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/Intermediate/RazorIRAssert.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/Intermediate/RazorIRAssert.cs @@ -203,7 +203,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate var content = new StringBuilder(); for (var i = 0; i < cSharp.Children.Count; i++) { - content.Append(((CSharpTokenIRNode)cSharp.Children[i]).Content); + var token = Assert.IsType(cSharp.Children[i]); + Assert.Equal(RazorIRToken.TokenKind.CSharp, token.Kind); + content.Append(token.Content); } Assert.Equal(expected, content.ToString()); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt index 1f69c34356..71b4bede6a 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt @@ -9,5 +9,5 @@ Document - HtmlAttribute - (25:2,9 [13] HtmlWithConditionalAttribute.cshtml) - val=" - " CSharpAttributeValue - (31:2,15 [6] HtmlWithConditionalAttribute.cshtml) - CSharpExpression - (32:2,16 [5] HtmlWithConditionalAttribute.cshtml) - CSharpToken - (32:2,16 [5] HtmlWithConditionalAttribute.cshtml) - Hello + RazorIRToken - (32:2,16 [5] HtmlWithConditionalAttribute.cshtml) - CSharp - Hello HtmlContent - (38:2,22 [22] HtmlWithConditionalAttribute.cshtml) - />\n\n" diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt index 27d5940f69..34d44113b7 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt @@ -7,5 +7,5 @@ Document - RazorMethodDeclaration - - - - - HtmlContent - (0:0,0 [36] HtmlWithDataDashAttribute.cshtml) - \n\n \n\n" diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt index 9c33ee24ab..60c6b21b1a 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt @@ -14,7 +14,7 @@ Document - CSharpStatement - - EndContext(); CSharpStatement - - BeginContext(61, 7, false); CSharpExpression - (61:2,2 [7] BasicTest.cshtml) - CSharpToken - (61:2,2 [7] BasicTest.cshtml) - "Hello" + RazorIRToken - (61:2,2 [7] BasicTest.cshtml) - CSharp - "Hello" CSharpStatement - - EndContext(); CSharpStatement - - BeginContext(69, 2, true); HtmlContent - (69:2,10 [2] BasicTest.cshtml) - \n @@ -30,7 +30,7 @@ Document - SetPreallocatedTagHelperProperty - - __tagHelperAttribute_0 - value - FooProp SetTagHelperProperty - (121:4,28 [13] BasicTest.cshtml) - date - BarProp - HtmlAttributeValueStyle.DoubleQuotes CSharpExpression - (122:4,29 [12] BasicTest.cshtml) - CSharpToken - (122:4,29 [12] BasicTest.cshtml) - DateTime.Now + RazorIRToken - (122:4,29 [12] BasicTest.cshtml) - CSharp - DateTime.Now AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 CSharpStatement - - BeginContext(97, 52, false); ExecuteTagHelpers - diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt index 4202671e6e..bbf60ae89f 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt @@ -13,7 +13,7 @@ Document - CreateTagHelper - - InputTagHelper SetTagHelperProperty - (56:2,17 [6] TagHelpersWithBoundAttributes.cshtml) - bound - FooProp - HtmlAttributeValueStyle.DoubleQuotes CSharpExpression - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - CSharpToken - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - Hello + RazorIRToken - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - CSharp - Hello AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 ExecuteTagHelpers - HtmlContent - (77:2,38 [9] TagHelpersWithBoundAttributes.cshtml) - \n