diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/InjectDirective.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/InjectDirective.cs index 1ada48a1a6..77a2284ee4 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/InjectDirective.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/InjectDirective.cs @@ -70,14 +70,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions public IList Directives { get; } = new List(); - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (Class == null) { Class = node; } - base.VisitClass(node); + base.VisitClassDeclaration(node); } public override void VisitDirective(DirectiveIRNode node) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ModelDirective.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ModelDirective.cs index b981cc3b29..0edd7bdd10 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ModelDirective.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ModelDirective.cs @@ -113,24 +113,24 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions public IList ModelDirectives { get; } = new List(); - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { if (Namespace == null) { Namespace = node; } - base.VisitNamespace(node); + base.VisitNamespaceDeclaration(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (Class == null) { Class = node; } - base.VisitClass(node); + base.VisitClassDeclaration(node); } public override void VisitDirective(DirectiveIRNode node) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs index 946788eb77..e953280ff5 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs @@ -164,24 +164,24 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions // We want the last one, so get them all and then . public DirectiveIRNode LastNamespaceDirective { get; private set; } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { if (FirstNamespace == null) { FirstNamespace = node; } - base.VisitNamespace(node); + base.VisitNamespaceDeclaration(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (FirstClass == null) { FirstClass = node; } - base.VisitClass(node); + base.VisitClassDeclaration(node); } public override void VisitDirective(DirectiveIRNode node) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PagesPropertyInjectionPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PagesPropertyInjectionPass.cs index 02503519bc..499f8beb31 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PagesPropertyInjectionPass.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PagesPropertyInjectionPass.cs @@ -51,14 +51,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public ClassDeclarationIRNode Class { get; private set; } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (Class == null) { Class = node; } - base.VisitClass(node); + base.VisitClassDeclaration(node); } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperPass.cs index e296019a0f..a1d41a772c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperPass.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperPass.cs @@ -249,24 +249,24 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions } } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { if (Namespace == null) { Namespace = node; } - base.VisitNamespace(node); + base.VisitNamespaceDeclaration(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (Class == null) { Class = node; } - base.VisitClass(node); + base.VisitClassDeclaration(node); } public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node) diff --git a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DefaultDocumentWriter.cs b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DefaultDocumentWriter.cs index 9fb6bf645d..86ee034c42 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DefaultDocumentWriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DefaultDocumentWriter.cs @@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration Context.BasicWriter.WriteUsingStatement(Context, node); } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { Context.Writer .Write("namespace ") @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration } } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Context.Writer .Write(node.AccessModifier) @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration } } - public override void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public override void VisitMethodDeclaration(MethodDeclarationIRNode node) { Context.Writer.WriteLine("#pragma warning disable 1998"); @@ -174,6 +174,16 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration Context.Writer.WriteLine("#pragma warning restore 1998"); } + public override void VisitFieldDeclaration(FieldDeclarationIRNode node) + { + Context.Writer.WriteField(node.AccessModifier, node.Modifiers, node.Type, node.Name); + } + + public override void VisitPropertyDeclaration(PropertyDeclarationIRNode node) + { + Context.Writer.WriteAutoPropertyDeclaration(node.AccessModifier, node.Modifiers, node.Type, node.Name); + } + public override void VisitExtension(ExtensionIRNode node) { node.WriteNode(_target, Context); diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultDirectiveIRPass.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultDirectiveIRPass.cs index 0001274cb5..5ab238c627 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DefaultDirectiveIRPass.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultDirectiveIRPass.cs @@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Razor.Language public IList SectionDirectiveNodes { get; } = new List(); - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { if (ClassNode == null) { diff --git a/src/Microsoft.AspNetCore.Razor.Language/DocumentClassifierPassBase.cs b/src/Microsoft.AspNetCore.Razor.Language/DocumentClassifierPassBase.cs index f0d8441e44..7620df1e38 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DocumentClassifierPassBase.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DocumentClassifierPassBase.cs @@ -141,6 +141,12 @@ namespace Microsoft.AspNetCore.Razor.Language public override void VisitDefault(RazorIRNode node) { + if (node is MemberDeclarationIRNode) + { + _class.Add(node); + return; + } + _method.Add(node); } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/ClassDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/ClassDeclarationIRNode.cs index e759f9ce9e..552e658189 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/ClassDeclarationIRNode.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/ClassDeclarationIRNode.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Razor.Language.Intermediate { - public class ClassDeclarationIRNode : RazorIRNode + public sealed class ClassDeclarationIRNode : MemberDeclarationIRNode { private ItemCollection _annotations; @@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate return _annotations; } } + public override IList Children { get; } = new List(); public override RazorIRNode Parent { get; set; } @@ -43,7 +44,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate throw new ArgumentNullException(nameof(visitor)); } - visitor.VisitClass(this); + visitor.VisitClassDeclaration(this); } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/FieldDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/FieldDeclarationIRNode.cs new file mode 100644 index 0000000000..7293113dad --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/FieldDeclarationIRNode.cs @@ -0,0 +1,50 @@ +// 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.Language.Intermediate +{ + public sealed class FieldDeclarationIRNode : MemberDeclarationIRNode + { + private ItemCollection _annotations; + + public override ItemCollection Annotations + { + get + { + if (_annotations == null) + { + _annotations = new DefaultItemCollection(); + } + + return _annotations; + } + } + + public override IList Children { get; } = EmptyArray; + + public IList Modifiers { get; set; } = new List(); + + public override RazorIRNode Parent { get; set; } + + public override SourceSpan? Source { get; set; } + + public string AccessModifier { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public override void Accept(RazorIRNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitFieldDeclaration(this); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MemberDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MemberDeclarationIRNode.cs new file mode 100644 index 0000000000..754a22284a --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MemberDeclarationIRNode.cs @@ -0,0 +1,9 @@ +// 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. + +namespace Microsoft.AspNetCore.Razor.Language.Intermediate +{ + public abstract class MemberDeclarationIRNode : RazorIRNode + { + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MethodDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MethodDeclarationIRNode.cs index 5615739a69..43ac7664d4 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MethodDeclarationIRNode.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/MethodDeclarationIRNode.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Razor.Language.Intermediate { - public class MethodDeclarationIRNode : RazorIRNode + public sealed class MethodDeclarationIRNode : MemberDeclarationIRNode { private ItemCollection _annotations; @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate public string AccessModifier { get; set; } - public IList Modifiers { get; set; } + public IList Modifiers { get; set; } = new List(); public string Name { get; set; } @@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate throw new ArgumentNullException(nameof(visitor)); } - visitor.VisitRazorMethodDeclaration(this); + visitor.VisitMethodDeclaration(this); } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/NamespaceDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/NamespaceDeclarationIRNode.cs index bfd63a86a5..9f7945d151 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/NamespaceDeclarationIRNode.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/NamespaceDeclarationIRNode.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate throw new ArgumentNullException(nameof(visitor)); } - visitor.VisitNamespace(this); + visitor.VisitNamespaceDeclaration(this); } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/PropertyDeclarationIRNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/PropertyDeclarationIRNode.cs new file mode 100644 index 0000000000..2b85fad3ed --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/PropertyDeclarationIRNode.cs @@ -0,0 +1,50 @@ +// 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.Language.Intermediate +{ + public sealed class PropertyDeclarationIRNode : MemberDeclarationIRNode + { + private ItemCollection _annotations; + + public override ItemCollection Annotations + { + get + { + if (_annotations == null) + { + _annotations = new DefaultItemCollection(); + } + + return _annotations; + } + } + + public override IList Children { get; } = EmptyArray; + + public IList Modifiers { get; set; } = new List(); + + public override RazorIRNode Parent { get; set; } + + public override SourceSpan? Source { get; set; } + + public string AccessModifier { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public override void Accept(RazorIRNodeVisitor visitor) + { + if (visitor == null) + { + throw new ArgumentNullException(nameof(visitor)); + } + + visitor.VisitPropertyDeclaration(this); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/RazorIRNodeVisitor.cs b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/RazorIRNodeVisitor.cs index 86b3d2a0fe..922f05415b 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Intermediate/RazorIRNodeVisitor.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Intermediate/RazorIRNodeVisitor.cs @@ -64,12 +64,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate VisitDefault(node); } - public virtual void VisitClass(ClassDeclarationIRNode node) + public virtual void VisitClassDeclaration(ClassDeclarationIRNode node) { VisitDefault(node); } - public virtual void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public virtual void VisitMethodDeclaration(MethodDeclarationIRNode node) + { + VisitDefault(node); + } + + public virtual void VisitFieldDeclaration(FieldDeclarationIRNode node) + { + VisitDefault(node); + } + + public virtual void VisitPropertyDeclaration(PropertyDeclarationIRNode node) { VisitDefault(node); } @@ -84,7 +94,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate VisitDefault(node); } - public virtual void VisitNamespace(NamespaceDeclarationIRNode node) + public virtual void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { VisitDefault(node); } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeWriter.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeWriter.cs index ec16091906..0333fd5f95 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeWriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeWriter.cs @@ -358,6 +358,66 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName)); } + public CSharpCodeWriter WriteField(string accessibility, string typeName, string fieldName) + { + if (accessibility == null) + { + throw new ArgumentNullException(nameof(accessibility)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (fieldName == null) + { + throw new ArgumentNullException(nameof(fieldName)); + } + + return WriteField(accessibility, Array.Empty(), typeName, fieldName); + } + + public CSharpCodeWriter WriteField(string accessibility, IList modifiers, string typeName, string fieldName) + { + if (accessibility == null) + { + throw new ArgumentNullException(nameof(accessibility)); + } + + if (modifiers == null) + { + throw new ArgumentNullException(nameof(modifiers)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (fieldName == null) + { + throw new ArgumentNullException(nameof(fieldName)); + } + + Write(accessibility); + Write(" "); + + for (var i = 0; i < modifiers.Count; i++) + { + Write(modifiers[i]); + Write(" "); + } + + Write(typeName); + Write(" "); + Write(fieldName); + Write(";"); + WriteLine(); + + return this; + } + public CSharpCodeWriter WriteMethodInvocation(string methodName, params string[] parameters) { return WriteMethodInvocation(methodName, endLine: true, parameters: parameters); @@ -370,15 +430,64 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy .WriteEndMethodInvocation(endLine); } - public CSharpCodeWriter WriteAutoPropertyDeclaration(string accessibility, string typeName, string name) + public CSharpCodeWriter WriteAutoPropertyDeclaration(string accessibility, string typeName, string propertyName) { - return Write(accessibility) - .Write(" ") - .Write(typeName) - .Write(" ") - .Write(name) - .Write(" { get; set; }") - .WriteLine(); + if (accessibility == null) + { + throw new ArgumentNullException(nameof(accessibility)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (propertyName == null) + { + throw new ArgumentNullException(nameof(propertyName)); + } + + return WriteAutoPropertyDeclaration(accessibility, Array.Empty(), typeName, propertyName); + } + + public CSharpCodeWriter WriteAutoPropertyDeclaration(string accessibility, IList modifiers, string typeName, string propertyName) + { + if (accessibility == null) + { + throw new ArgumentNullException(nameof(accessibility)); + } + + if (modifiers == null) + { + throw new ArgumentNullException(nameof(modifiers)); + } + + if (typeName == null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + if (propertyName == null) + { + throw new ArgumentNullException(nameof(propertyName)); + } + + Write(accessibility); + Write(" "); + + for (var i = 0; i < modifiers.Count; i++) + { + Write(modifiers[i]); + Write(" "); + } + + Write(typeName); + Write(" "); + Write(propertyName); + Write(" { get; set; }"); + WriteLine(); + + return this; } public CSharpDisableWarningScope BuildDisableWarningScope(int warning) diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorDesignTimeIRPass.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorDesignTimeIRPass.cs index ea0da4a321..77aeb01a12 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorDesignTimeIRPass.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorDesignTimeIRPass.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language { private DesignTimeDirectiveIRNode _designTimeDirectiveIRNode; - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { var designTimeHelperDeclaration = new CSharpStatementIRNode(); RazorIRBuilder.Create(designTimeHelperDeclaration) diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorPreallocatedTagHelperAttributeOptimizationPass.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorPreallocatedTagHelperAttributeOptimizationPass.cs index 8181916c65..c1b5528b56 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorPreallocatedTagHelperAttributeOptimizationPass.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorPreallocatedTagHelperAttributeOptimizationPass.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Razor.Language private int _variableCountOffset; private int _preallocatedDeclarationCount = 0; - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { _classDeclaration = node; _variableCountOffset = node.Children.Count; diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/InjectDirectiveTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/InjectDirectiveTest.cs index 4b21c4d25f..74aff230e9 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/InjectDirectiveTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/InjectDirectiveTest.cs @@ -216,7 +216,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public ClassDeclarationIRNode Node { get; set; } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Node = node; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ModelDirectiveTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ModelDirectiveTest.cs index 0d97d9a81e..0d4d8c9f5a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ModelDirectiveTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ModelDirectiveTest.cs @@ -277,7 +277,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public ClassDeclarationIRNode Node { get; set; } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Node = node; } @@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public NamespaceDeclarationIRNode Node { get; set; } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { Node = node; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/MvcViewDocumentClassifierPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/MvcViewDocumentClassifierPassTest.cs index c2c427cbde..2e2f8de404 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/MvcViewDocumentClassifierPassTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/MvcViewDocumentClassifierPassTest.cs @@ -223,21 +223,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions public MethodDeclarationIRNode Method { get; private set; } - public override void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public override void VisitMethodDeclaration(MethodDeclarationIRNode node) { Method = node; } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { Namespace = node; - base.VisitNamespace(node); + base.VisitNamespaceDeclaration(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Class = node; - base.VisitClass(node); + base.VisitClassDeclaration(node); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs index 057602cb35..cfcd7b5ab9 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs @@ -249,21 +249,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions public MethodDeclarationIRNode Method { get; private set; } - public override void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public override void VisitMethodDeclaration(MethodDeclarationIRNode node) { Method = node; } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { Namespace = node; - base.VisitNamespace(node); + base.VisitNamespaceDeclaration(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Class = node; - base.VisitClass(node); + base.VisitClassDeclaration(node); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ViewComponentTagHelperPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ViewComponentTagHelperPassTest.cs index c80f07367f..9a31502648 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ViewComponentTagHelperPassTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/ViewComponentTagHelperPassTest.cs @@ -348,7 +348,7 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore. { public ClassDeclarationIRNode Node { get; set; } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { Node = node; } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs index 5844ad855f..39e57283c4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs @@ -125,6 +125,82 @@ internal virtual async string TestMethod() { } #pragma warning restore 1998 +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void WriteDocument_WritesField() + { + // Arrange + var codeDocument = TestRazorCodeDocument.CreateEmpty(); + var options = RazorParserOptions.CreateDefaultOptions(); + + var target = RuntimeTarget.CreateDefault(codeDocument, options); + var context = new CSharpRenderingContext() + { + Options = options, + Writer = new Legacy.CSharpCodeWriter(), + }; + var writer = new DefaultDocumentWriter(target, context); + + var builder = RazorIRBuilder.Document(); + builder.Add(new FieldDeclarationIRNode() + { + AccessModifier = "internal", + Modifiers = new List { "readonly",}, + Name = "_foo", + Type = "string", + }); + + var document = (DocumentIRNode)builder.Build(); + + // Act + writer.WriteDocument(document); + + // Assert + var csharp = context.Writer.Builder.ToString(); + Assert.Equal( +@"internal readonly string _foo; +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void WriteDocument_WritesProperty() + { + // Arrange + var codeDocument = TestRazorCodeDocument.CreateEmpty(); + var options = RazorParserOptions.CreateDefaultOptions(); + + var target = RuntimeTarget.CreateDefault(codeDocument, options); + var context = new CSharpRenderingContext() + { + Options = options, + Writer = new Legacy.CSharpCodeWriter(), + }; + var writer = new DefaultDocumentWriter(target, context); + + var builder = RazorIRBuilder.Document(); + builder.Add(new PropertyDeclarationIRNode() + { + AccessModifier = "internal", + Modifiers = new List { "virtual", }, + Name = "Foo", + Type = "string", + }); + + var document = (DocumentIRNode)builder.Build(); + + // Act + writer.WriteDocument(document); + + // Assert + var csharp = context.Writer.Builder.ToString(); + Assert.Equal( +@"internal virtual string Foo { get; set; } ", csharp, ignoreLineEndingDifferences: true); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpCodeWriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpCodeWriterTest.cs index 928333a2b6..cb5b385d4d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpCodeWriterTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpCodeWriterTest.cs @@ -1,6 +1,7 @@ // 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 Xunit; namespace Microsoft.AspNetCore.Razor.Language.Legacy @@ -45,5 +46,61 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Assert Assert.Equal(expected, code); } + + [Fact] + public void WriteField_WritesFieldDeclaration() + { + // Arrange + var writer = new CSharpCodeWriter(); + + // Act + writer.WriteField("private", "global::System.String", "_myString"); + + // Assert + var output = writer.GenerateCode(); + Assert.Equal("private global::System.String _myString;" + Environment.NewLine, output); + } + + [Fact] + public void WriteField_WithModifiers_WritesFieldDeclaration() + { + // Arrange + var writer = new CSharpCodeWriter(); + + // Act + writer.WriteField("private", new[] { "readonly", "static" }, "global::System.String", "_myString"); + + // Assert + var output = writer.GenerateCode(); + Assert.Equal("private readonly static global::System.String _myString;" + Environment.NewLine, output); + } + + [Fact] + public void WriteAutoPropertyDeclaration_WritesPropertyDeclaration() + { + // Arrange + var writer = new CSharpCodeWriter(); + + // Act + writer.WriteAutoPropertyDeclaration("public", "global::System.String", "MyString"); + + // Assert + var output = writer.GenerateCode(); + Assert.Equal("public global::System.String MyString { get; set; }" + Environment.NewLine, output); + } + + [Fact] + public void WriteAutoPropertyDeclaration_WithModifiers_WritesPropertyDeclaration() + { + // Arrange + var writer = new CSharpCodeWriter(); + + // Act + writer.WriteAutoPropertyDeclaration("public", new[] { "static" }, "global::System.String", "MyString"); + + // Assert + var output = writer.GenerateCode(); + Assert.Equal("public static global::System.String MyString { get; set; }" + Environment.NewLine, output); + } } } diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/IntegrationTestBase.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/IntegrationTestBase.cs index 0711004f23..4d3437f4ac 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/IntegrationTestBase.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/IntegrationTestBase.cs @@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests private class ApiSetsIRWalker : RazorIRNodeWalker { - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { node.Name = Filename.Replace('/', '_'); node.AccessModifier = "public"; @@ -229,14 +229,14 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests VisitDefault(node); } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { node.Content = "Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles"; VisitDefault(node); } - public override void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public override void VisitMethodDeclaration(MethodDeclarationIRNode node) { node.AccessModifier = "public"; node.Modifiers = new[] { "async" }; diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/RazorIRNodeWriter.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/RazorIRNodeWriter.cs index b0c7c1fe7b..d393c48f21 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/RazorIRNodeWriter.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Langauge/IntegrationTests/RazorIRNodeWriter.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests WriteBasicNode(node); } - public override void VisitClass(ClassDeclarationIRNode node) + public override void VisitClassDeclaration(ClassDeclarationIRNode node) { WriteContentNode(node, node.AccessModifier, node.Name, node.BaseType, string.Join(", ", node.Interfaces ?? new List())); } @@ -61,12 +61,12 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests WriteContentNode(node, node.Prefix, node.Content); } - public override void VisitNamespace(NamespaceDeclarationIRNode node) + public override void VisitNamespaceDeclaration(NamespaceDeclarationIRNode node) { WriteContentNode(node, node.Content); } - public override void VisitRazorMethodDeclaration(MethodDeclarationIRNode node) + public override void VisitMethodDeclaration(MethodDeclarationIRNode node) { WriteContentNode(node, node.AccessModifier, string.Join(", ", node.Modifiers ?? new List()), node.ReturnType, node.Name); }