diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs index 045fc2ee3af..0e1e4627bb0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -66,7 +66,7 @@ public class MyService AssertSourceMappingsMatchBaseline(compiled.CodeDocument); // We expect this test to generate a bunch of errors. - Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + Assert.NotEmpty(compiled.CodeDocument.GetCSharpDocument().Diagnostics); } [Fact] diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs index 7ea5db9a39c..431c1ffef9a 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/AssemblyAttributeInjectionPassTest.cs @@ -19,7 +19,7 @@ public void Execute_NoOps_IfNamespaceNodeIsMissing() // Arrange var irDocument = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var pass = new AssemblyAttributeInjectionPass @@ -40,7 +40,7 @@ public void Execute_NoOps_IfNamespaceNodeHasEmptyContent() // Arrange var irDocument = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode() { Content = string.Empty }; @@ -66,7 +66,7 @@ public void Execute_NoOps_IfClassNameNodeIsMissing() // Arrange var irDocument = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); @@ -93,7 +93,7 @@ public void Execute_NoOps_IfClassNameIsEmpty() // Arrange var irDocument = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode @@ -134,7 +134,7 @@ public void Execute_NoOps_IfDocumentIsNotViewOrPage() var irDocument = new DocumentIntermediateNode { DocumentKind = "Default", - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" }; @@ -170,7 +170,7 @@ public void Execute_NoOps_ForDesignTime() var irDocument = new DocumentIntermediateNode { DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, - Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(), + Options = RazorCodeGenerationOptions.DesignTimeDefault, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode @@ -217,7 +217,7 @@ public void Execute_AddsRazorViewAttribute_ToViews() var irDocument = new DocumentIntermediateNode { DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode @@ -270,7 +270,7 @@ public void Execute_EscapesViewPathWhenAddingAttributeToViews() var irDocument = new DocumentIntermediateNode { DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode @@ -323,7 +323,7 @@ public void Execute_AddsRazorPagettribute_ToPage() var irDocument = new DocumentIntermediateNode { DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind, - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var pageDirective = new DirectiveIntermediateNode @@ -383,7 +383,7 @@ public void Execute_EscapesViewPathAndRouteWhenAddingAttributeToPage() var irDocument = new DocumentIntermediateNode { DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind, - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(irDocument); var @namespace = new NamespaceDeclarationIntermediateNode diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs index d5ac8364cc5..40723f0f28f 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/InstrumentationPassTest.cs @@ -18,7 +18,7 @@ public void InstrumentationPass_NoOps_ForDesignTime() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(), + Options = RazorCodeGenerationOptions.DesignTimeDefault, }; var builder = IntermediateNodeBuilder.Create(document); @@ -50,7 +50,7 @@ public void InstrumentationPass_InstrumentsHtml() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -89,7 +89,7 @@ public void InstrumentationPass_SkipsHtml_WithoutLocation() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -121,7 +121,7 @@ public void InstrumentationPass_InstrumentsCSharpExpression() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -157,7 +157,7 @@ public void InstrumentationPass_SkipsCSharpExpression_WithoutLocation() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -188,7 +188,7 @@ public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperAttribute() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -239,7 +239,7 @@ public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperProperty() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -290,7 +290,7 @@ public void InstrumentationPass_InstrumentsTagHelper() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); @@ -321,7 +321,7 @@ public void InstrumentationPass_SkipsTagHelper_WithoutLocation() // Arrange var document = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var builder = IntermediateNodeBuilder.Create(document); diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs index bc3aa19c9c1..4f0c1e71fab 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -85,7 +85,7 @@ public class MyService AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument()); // We expect this test to generate a bunch of errors. - Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + Assert.NotEmpty(compiled.CodeDocument.GetCSharpDocument().Diagnostics); } [Fact] @@ -536,7 +536,7 @@ public class MyService AssertSourceMappingsMatchBaseline(compiled.CodeDocument); // We expect this test to generate a bunch of errors. - Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + Assert.NotEmpty(compiled.CodeDocument.GetCSharpDocument().Diagnostics); } [Fact] diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs index de4dd521d8e..36a5ecf0f63 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -92,7 +92,7 @@ public class MyService AssertLinePragmas(compiled.CodeDocument, designTime: false); // We expect this test to generate a bunch of errors. - Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + Assert.NotEmpty(compiled.CodeDocument.GetCSharpDocument().Diagnostics); } [Fact] @@ -949,7 +949,7 @@ public class MyService AssertSourceMappingsMatchBaseline(compiled.CodeDocument); // We expect this test to generate a bunch of errors. - Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0); + Assert.NotEmpty(compiled.CodeDocument.GetCSharpDocument().Diagnostics); } [Fact] diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CSharpCodeWriterTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CSharpCodeWriterTest.cs index 8d7c6ff83c3..39604a88965 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CSharpCodeWriterTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CSharpCodeWriterTest.cs @@ -402,7 +402,7 @@ public void CSharpCodeWriter_RespectTabSetting() o.IndentSize = 4; }); - using var writer = new CodeWriter(Environment.NewLine, options); + using var writer = new CodeWriter(options); // Act writer.BuildClassDeclaration(Array.Empty(), "C", "", Array.Empty(), Array.Empty(), context: null); @@ -428,7 +428,7 @@ public void CSharpCodeWriter_RespectSpaceSetting() o.IndentSize = 4; }); - using var writer = new CodeWriter(Environment.NewLine, options); + using var writer = new CodeWriter(options); // Act writer.BuildClassDeclaration(Array.Empty(), "C", "", Array.Empty(), Array.Empty(), context: null); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CodeTargetTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CodeTargetTest.cs index 8d6f8d7f170..29ffd24e1f8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CodeTargetTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/CodeTargetTest.cs @@ -15,7 +15,7 @@ public void CreateDefault_CreatesDefaultCodeTarget() { // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; // Act var target = CodeTarget.CreateDefault(codeDocument, options); @@ -32,7 +32,7 @@ public void CreateDefault_CallsDelegate() Action @delegate = (b) => { wasCalled = true; }; var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; // Act CodeTarget.CreateDefault(codeDocument, options, @delegate); @@ -46,7 +46,7 @@ public void CreateDefault_AllowsNullDelegate() { // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; // Act CodeTarget.CreateDefault(codeDocument, options, configure: null); @@ -59,7 +59,7 @@ public void CreateEmpty_AllowsNullDelegate() { // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; // Act CodeTarget.CreateDefault(codeDocument, options, configure: null); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetBuilderTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetBuilderTest.cs index c2fc301395f..654d44608a0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetBuilderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetBuilderTest.cs @@ -14,7 +14,7 @@ public void Build_CreatesDefaultCodeTarget() { // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var builder = new DefaultCodeTargetBuilder(codeDocument, options); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetTest.cs index 50624d004e4..a8dbc432063 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultCodeTargetTest.cs @@ -14,7 +14,7 @@ public class DefaultCodeTargetTest public void Constructor_CreatesDefensiveCopy() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { @@ -33,7 +33,7 @@ public void Constructor_CreatesDefensiveCopy() public void CreateWriter_DesignTime_CreatesDesignTimeNodeWriter() { // Arrange - var options = RazorCodeGenerationOptions.CreateDesignTimeDefault(); + var options = RazorCodeGenerationOptions.DesignTimeDefault; var target = new DefaultCodeTarget(options, Enumerable.Empty()); // Act @@ -47,7 +47,7 @@ public void CreateWriter_DesignTime_CreatesDesignTimeNodeWriter() public void CreateWriter_Runtime_CreatesRuntimeNodeWriter() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = new DefaultCodeTarget(options, Enumerable.Empty()); // Act @@ -61,7 +61,7 @@ public void CreateWriter_Runtime_CreatesRuntimeNodeWriter() public void HasExtension_ReturnsTrue_WhenExtensionFound() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { @@ -82,7 +82,7 @@ public void HasExtension_ReturnsTrue_WhenExtensionFound() public void HasExtension_ReturnsFalse_WhenExtensionNotFound() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { @@ -103,7 +103,7 @@ public void HasExtension_ReturnsFalse_WhenExtensionNotFound() public void GetExtension_ReturnsExtension_WhenExtensionFound() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { @@ -124,7 +124,7 @@ public void GetExtension_ReturnsExtension_WhenExtensionFound() public void GetExtension_ReturnsFirstMatch_WhenExtensionFound() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { @@ -148,7 +148,7 @@ public void GetExtension_ReturnsFirstMatch_WhenExtensionFound() public void GetExtension_ReturnsNull_WhenExtensionNotFound() { // Arrange - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var extensions = new ICodeTargetExtension[] { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultDocumentWriterTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultDocumentWriterTest.cs index 1351dc789ff..9a9ad5d22b3 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultDocumentWriterTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DefaultDocumentWriterTest.cs @@ -20,7 +20,7 @@ public void WriteDocument_EndToEnd_WritesChecksumAndMarksAutoGenerated() var document = new DocumentIntermediateNode(); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -51,7 +51,7 @@ public void WriteDocument_SHA1_WritesChecksumAndMarksAutoGenerated() var document = new DocumentIntermediateNode(); var codeDocument = RazorCodeDocument.Create(sourceDocument); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -82,7 +82,7 @@ public void WriteDocument_SHA256_WritesChecksumAndMarksAutoGenerated() var document = new DocumentIntermediateNode(); var codeDocument = RazorCodeDocument.Create(sourceDocument); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -110,7 +110,7 @@ public void WriteDocument_Empty_SuppressChecksumTrue_DoesnotWriteChecksum() var document = new DocumentIntermediateNode(); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var optionsBuilder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false) + var optionsBuilder = new RazorCodeGenerationOptionsBuilder(designTime: false) { SuppressChecksum = true }; @@ -144,7 +144,7 @@ public void WriteDocument_WritesNamespace() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -192,7 +192,7 @@ public void WriteDocument_WritesClass() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -243,7 +243,7 @@ public void WriteDocument_WithNullableContext_WritesClass() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -292,7 +292,7 @@ public void WriteDocument_WritesClass_ConstrainedGenericTypeParameters() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -355,7 +355,7 @@ public void WriteDocument_WritesMethod() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -399,7 +399,7 @@ public void WriteDocument_WritesField() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); @@ -439,7 +439,7 @@ public void WriteDocument_WritesProperty() }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var options = RazorCodeGenerationOptions.CreateDefault(); + var options = RazorCodeGenerationOptions.Default; var target = CodeTarget.CreateDefault(codeDocument, options); var writer = new DefaultDocumentWriter(target, options); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DesignTimeNodeWriterTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DesignTimeNodeWriterTest.cs index 1724a5ad318..d34c08ea4b9 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DesignTimeNodeWriterTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/CodeGeneration/DesignTimeNodeWriterTest.cs @@ -58,7 +58,7 @@ public void WriteUsingDirective_WithSource_WritesContentWithLinePragmaAndMapping writer.WriteUsingDirective(context, node); // Assert - var mapping = Assert.Single(((DefaultCodeRenderingContext)context).SourceMappings); + var mapping = Assert.Single(context.GetSourceMappings()); Assert.Equal(expectedSourceMapping, mapping); var csharp = context.CodeWriter.GenerateCode(); Assert.Equal( @@ -94,7 +94,7 @@ public void WriteUsingDirective_WithSourceAndLineDirectives_WritesContentWithLin writer.WriteUsingDirective(context, node); // Assert - var mapping = Assert.Single(((DefaultCodeRenderingContext)context).SourceMappings); + var mapping = Assert.Single(context.GetSourceMappings()); Assert.Equal(expectedSourceMapping, mapping); var csharp = context.CodeWriter.GenerateCode(); Assert.Equal( @@ -587,7 +587,7 @@ public void LinePragma_Enhanced_Is_Adjusted_On_Windows(string fileName, string e csharp, ignoreLineEndingDifferences: true); - Assert.Single(((DefaultCodeRenderingContext)context).SourceMappings); + Assert.Single(context.GetSourceMappings()); } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Components/ComponentDuplicateAttributeDiagnosticPassTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Components/ComponentDuplicateAttributeDiagnosticPassTest.cs index 34743b31272..c542ab950b2 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Components/ComponentDuplicateAttributeDiagnosticPassTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Components/ComponentDuplicateAttributeDiagnosticPassTest.cs @@ -141,7 +141,7 @@ public void Execute_FindDuplicate_Multiple() var diagnostics = documentNode.GetAllDiagnostics(); var nodes = documentNode.FindDescendantNodes().Where(n => n.HasDiagnostics).ToArray(); - Assert.Equal(2, diagnostics.Count); + Assert.Equal(2, diagnostics.Length); Assert.Equal(2, nodes.Length); for (var i = 0; i < 2; i++) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultDocumentClassifierPassTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultDocumentClassifierPassTest.cs index 6936b9451e1..2b1a4822e1d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultDocumentClassifierPassTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultDocumentClassifierPassTest.cs @@ -23,7 +23,7 @@ public void Execute_IgnoresDocumentsWithDocumentKind() var documentNode = new DocumentIntermediateNode() { DocumentKind = "ignore", - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var pass = new DefaultDocumentClassifierPass(); @@ -43,7 +43,7 @@ public void Execute_CreatesClassStructure() // Arrange var documentNode = new DocumentIntermediateNode() { - Options = RazorCodeGenerationOptions.CreateDefault(), + Options = RazorCodeGenerationOptions.Default, }; var pass = new DefaultDocumentClassifierPass(); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorCSharpLoweringPhaseTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorCSharpLoweringPhaseTest.cs index 4a535879206..b8efdb27514 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorCSharpLoweringPhaseTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorCSharpLoweringPhaseTest.cs @@ -66,7 +66,7 @@ public void Execute_CollatesIRDocumentDiagnosticsFromSourceDocument() var phase = new DefaultRazorCSharpLoweringPhase(); var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase)); var codeDocument = TestRazorCodeDocument.Create("

()); + var expected = new RazorCSharpDocument(codeDocument, "", RazorCodeGenerationOptions.Default, diagnostics: []); codeDocument.Items[typeof(RazorCSharpDocument)] = expected; // Act @@ -129,7 +129,7 @@ public void SetCSharpDocument_SetsCSharpDocument() // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var expected = RazorCSharpDocument.Create(codeDocument, "", RazorCodeGenerationOptions.CreateDefault(), Array.Empty()); + var expected = new RazorCSharpDocument(codeDocument, "", RazorCodeGenerationOptions.Default, diagnostics: []); // Act codeDocument.SetCSharpDocument(expected); @@ -206,7 +206,7 @@ public void GetCodeGenerationOptions_ReturnsSuccessfully() // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var expected = RazorCodeGenerationOptions.CreateDefault(); + var expected = RazorCodeGenerationOptions.Default; codeDocument.Items[typeof(RazorCodeGenerationOptions)] = expected; // Act @@ -222,7 +222,7 @@ public void SetCodeGenerationOptions_SetsSuccessfully() // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var expected = RazorCodeGenerationOptions.CreateDefault(); + var expected = RazorCodeGenerationOptions.Default; // Act codeDocument.SetCodeGenerationOptions(expected); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/ChecksumUtilities.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/ChecksumUtilities.cs index 790b35abe3a..4b40a41f45f 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/ChecksumUtilities.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/ChecksumUtilities.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Immutable; using System.Globalization; -using System.Text; using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeRenderingContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeRenderingContext.cs index 4b005b08902..23cc201671f 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeRenderingContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeRenderingContext.cs @@ -1,53 +1,195 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Collections.Generic; +using System.Collections.Immutable; using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration; -public abstract class CodeRenderingContext : IDisposable +public sealed class CodeRenderingContext : IDisposable { - internal static readonly object NewLineString = "NewLineString"; + private readonly record struct ScopeInternal(IntermediateNodeWriter Writer); + + public RazorSourceDocument SourceDocument { get; } + public RazorCodeGenerationOptions Options { get; } + public CodeWriter CodeWriter { get; } + + private readonly DocumentIntermediateNode _documentNode; + + private readonly Stack _ancestorStack; + private readonly Stack _scopeStack; + + private readonly ImmutableArray.Builder _diagnostics; + private readonly ImmutableArray.Builder _sourceMappings; + private readonly ImmutableArray.Builder _linePragmas; + + private IntermediateNodeVisitor? _visitor; + public IntermediateNodeVisitor Visitor => _visitor.AssumeNotNull(); + + public string DocumentKind => _documentNode.DocumentKind; + + public CodeRenderingContext( + IntermediateNodeWriter nodeWriter, + RazorSourceDocument sourceDocument, + DocumentIntermediateNode documentNode, + RazorCodeGenerationOptions options) + { + ArgHelper.ThrowIfNull(nodeWriter); + ArgHelper.ThrowIfNull(sourceDocument); + ArgHelper.ThrowIfNull(documentNode); + ArgHelper.ThrowIfNull(options); + + SourceDocument = sourceDocument; + _documentNode = documentNode; + Options = options; + + _ancestorStack = StackPool.Default.Get(); + _scopeStack = StackPool.Default.Get(); + _scopeStack.Push(new(nodeWriter)); + + _diagnostics = ArrayBuilderPool.Default.Get(); + + foreach (var diagnostic in _documentNode.GetAllDiagnostics()) + { + _diagnostics.Add(diagnostic); + } + + _linePragmas = ArrayBuilderPool.Default.Get(); + _sourceMappings = ArrayBuilderPool.Default.Get(); + + CodeWriter = new CodeWriter(options); + } + + public void Dispose() + { + StackPool.Default.Return(_ancestorStack); + StackPool.Default.Return(_scopeStack); + + ArrayBuilderPool.Default.Return(_diagnostics); + ArrayBuilderPool.Default.Return(_linePragmas); + ArrayBuilderPool.Default.Return(_sourceMappings); + + CodeWriter.Dispose(); + } + + // This will be called by the document writer when the context is 'live'. + public void SetVisitor(IntermediateNodeVisitor visitor) + { + _visitor = visitor; + } - internal static readonly object SuppressUniqueIds = "SuppressUniqueIds"; + public IntermediateNodeWriter NodeWriter => _scopeStack.Peek().Writer; - public abstract IEnumerable Ancestors { get; } + public IntermediateNode? Parent + => _ancestorStack.Count == 0 ? null : _ancestorStack.Peek(); - public abstract CodeWriter CodeWriter { get; } + public void AddDiagnostic(RazorDiagnostic diagnostic) + { + _diagnostics.Add(diagnostic); + } + + public ImmutableArray GetDiagnostics() + => _diagnostics.ToImmutableOrderedBy(static d => d.Span.AbsoluteIndex); + + public void AddSourceMappingFor(IntermediateNode node) + { + ArgHelper.ThrowIfNull(node); + + if (node.Source == null) + { + return; + } + + AddSourceMappingFor(node.Source.Value); + } + + public void AddSourceMappingFor(SourceSpan source, int offset = 0) + { + if (SourceDocument.FilePath != null && + !string.Equals(SourceDocument.FilePath, source.FilePath, StringComparison.OrdinalIgnoreCase)) + { + // We don't want to generate line mappings for imports. + return; + } + + var currentLocation = CodeWriter.Location with + { + AbsoluteIndex = CodeWriter.Location.AbsoluteIndex + offset, + CharacterIndex = CodeWriter.Location.CharacterIndex + offset + }; + + var generatedLocation = new SourceSpan(currentLocation, source.Length); + var sourceMapping = new SourceMapping(source, generatedLocation); + + _sourceMappings.Add(sourceMapping); + } + + public ImmutableArray GetSourceMappings() + => _sourceMappings.DrainToImmutable(); - public abstract RazorDiagnosticCollection Diagnostics { get; } + public void RenderChildren(IntermediateNode node) + { + ArgHelper.ThrowIfNull(node); + + _ancestorStack.Push(node); - public abstract string DocumentKind { get; } + for (var i = 0; i < node.Children.Count; i++) + { + Visitor.Visit(node.Children[i]); + } - public abstract ItemCollection Items { get; } + _ancestorStack.Pop(); + } - public abstract IntermediateNodeWriter NodeWriter { get; } + public void RenderChildren(IntermediateNode node, IntermediateNodeWriter writer) + { + ArgHelper.ThrowIfNull(node); + ArgHelper.ThrowIfNull(writer); - public abstract RazorCodeGenerationOptions Options { get; } + _scopeStack.Push(new ScopeInternal(writer)); + _ancestorStack.Push(node); - public abstract IntermediateNode Parent { get; } + for (var i = 0; i < node.Children.Count; i++) + { + Visitor.Visit(node.Children[i]); + } - public abstract RazorSourceDocument SourceDocument { get; } + _ancestorStack.Pop(); + _scopeStack.Pop(); + } - public abstract void AddSourceMappingFor(IntermediateNode node); + public void RenderNode(IntermediateNode node) + { + ArgHelper.ThrowIfNull(node); - public abstract void AddSourceMappingFor(SourceSpan node, int offset = 0); + Visitor.Visit(node); + } - public abstract void RenderNode(IntermediateNode node); + public void RenderNode(IntermediateNode node, IntermediateNodeWriter writer) + { + ArgHelper.ThrowIfNull(node); + ArgHelper.ThrowIfNull(writer); - public abstract void RenderNode(IntermediateNode node, IntermediateNodeWriter writer); + _scopeStack.Push(new ScopeInternal(writer)); - public abstract void RenderChildren(IntermediateNode node); + Visitor.Visit(node); - public abstract void RenderChildren(IntermediateNode node, IntermediateNodeWriter writer); + _scopeStack.Pop(); + } - public virtual void AddLinePragma(LinePragma linePragma) + public void AddLinePragma(LinePragma linePragma) { + _linePragmas.Add(linePragma); } - public abstract void Dispose(); + public ImmutableArray GetLinePragmas() + => _linePragmas.DrainToImmutable(); + + public void PushAncestor(IntermediateNode node) + { + _ancestorStack.Push(node); + } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs index d2e2260ad5e..15f762cc291 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs @@ -43,13 +43,13 @@ public sealed partial class CodeWriter : IDisposable private int _currentLineCharacterIndex; public CodeWriter() - : this(Environment.NewLine, RazorCodeGenerationOptions.CreateDefault()) + : this(RazorCodeGenerationOptions.Default) { } - public CodeWriter(string newLine, RazorCodeGenerationOptions options) + public CodeWriter(RazorCodeGenerationOptions options) { - SetNewLine(newLine); + SetNewLine(options.NewLine); IndentWithTabs = options.IndentWithTabs; TabSize = options.IndentSize; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultCodeRenderingContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultCodeRenderingContext.cs deleted file mode 100644 index 0769b7045eb..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultCodeRenderingContext.cs +++ /dev/null @@ -1,227 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.AspNetCore.Razor.Language.Intermediate; -using Microsoft.AspNetCore.Razor.PooledObjects; - -namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration; - -internal class DefaultCodeRenderingContext : CodeRenderingContext -{ - private readonly Stack _ancestors; - private readonly RazorCodeDocument _codeDocument; - private readonly DocumentIntermediateNode _documentNode; - private readonly List _scopes; - - private readonly PooledObject.Builder> _sourceMappingsBuilder; - - public DefaultCodeRenderingContext( - IntermediateNodeWriter nodeWriter, - RazorCodeDocument codeDocument, - DocumentIntermediateNode documentNode, - RazorCodeGenerationOptions options) - { - if (nodeWriter == null) - { - throw new ArgumentNullException(nameof(nodeWriter)); - } - - if (codeDocument == null) - { - throw new ArgumentNullException(nameof(codeDocument)); - } - - if (documentNode == null) - { - throw new ArgumentNullException(nameof(documentNode)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - _codeDocument = codeDocument; - _documentNode = documentNode; - Options = options; - - _ancestors = new Stack(); - Diagnostics = new RazorDiagnosticCollection(); - Items = new ItemCollection(); - _sourceMappingsBuilder = ArrayBuilderPool.GetPooledObject(); - LinePragmas = new List(); - - var diagnostics = _documentNode.GetAllDiagnostics(); - for (var i = 0; i < diagnostics.Count; i++) - { - Diagnostics.Add(diagnostics[i]); - } - - // Set new line character to a specific string regardless of platform, for testing purposes. - var newLineString = codeDocument.Items[NewLineString] as string ?? Environment.NewLine; - CodeWriter = new CodeWriter(newLineString, options); - - Items[NewLineString] = codeDocument.Items[NewLineString]; - Items[SuppressUniqueIds] = codeDocument.Items[SuppressUniqueIds] ?? options.SuppressUniqueIds; - - _scopes = new List(); - _scopes.Add(new ScopeInternal(nodeWriter)); - } - - // This will be initialized by the document writer when the context is 'live'. - public IntermediateNodeVisitor Visitor { get; set; } - - public override IEnumerable Ancestors => _ancestors; - - internal Stack AncestorsInternal => _ancestors; - - public override CodeWriter CodeWriter { get; } - - public override RazorDiagnosticCollection Diagnostics { get; } - - public override string DocumentKind => _documentNode.DocumentKind; - - public override ItemCollection Items { get; } - - public ImmutableArray.Builder SourceMappings => _sourceMappingsBuilder.Object; - - internal List LinePragmas { get; } - - public override IntermediateNodeWriter NodeWriter => Current.Writer; - - public override RazorCodeGenerationOptions Options { get; } - - public override IntermediateNode Parent => _ancestors.Count == 0 ? null : _ancestors.Peek(); - - public override RazorSourceDocument SourceDocument => _codeDocument.Source; - - private ScopeInternal Current => _scopes[_scopes.Count - 1]; - - public override void AddSourceMappingFor(IntermediateNode node) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - if (node.Source == null) - { - return; - } - - AddSourceMappingFor(node.Source.Value); - } - - public override void AddSourceMappingFor(SourceSpan source, int offset = 0) - { - if (SourceDocument.FilePath != null && - !string.Equals(SourceDocument.FilePath, source.FilePath, StringComparison.OrdinalIgnoreCase)) - { - // We don't want to generate line mappings for imports. - return; - } - - var currentLocation = CodeWriter.Location with { AbsoluteIndex = CodeWriter.Location.AbsoluteIndex + offset, CharacterIndex = CodeWriter.Location.CharacterIndex + offset }; - - var generatedLocation = new SourceSpan(currentLocation, source.Length); - var sourceMapping = new SourceMapping(source, generatedLocation); - - SourceMappings.Add(sourceMapping); - } - - public override void RenderChildren(IntermediateNode node) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - _ancestors.Push(node); - - for (var i = 0; i < node.Children.Count; i++) - { - Visitor.Visit(node.Children[i]); - } - - _ancestors.Pop(); - } - - public override void RenderChildren(IntermediateNode node, IntermediateNodeWriter writer) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - _scopes.Add(new ScopeInternal(writer)); - _ancestors.Push(node); - - for (var i = 0; i < node.Children.Count; i++) - { - Visitor.Visit(node.Children[i]); - } - - _ancestors.Pop(); - _scopes.RemoveAt(_scopes.Count - 1); - } - - public override void RenderNode(IntermediateNode node) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - Visitor.Visit(node); - } - - public override void RenderNode(IntermediateNode node, IntermediateNodeWriter writer) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - _scopes.Add(new ScopeInternal(writer)); - - Visitor.Visit(node); - - _scopes.RemoveAt(_scopes.Count - 1); - } - - public override void AddLinePragma(LinePragma linePragma) - { - LinePragmas.Add(linePragma); - } - - public override void Dispose() - { - _sourceMappingsBuilder.Dispose(); - CodeWriter.Dispose(); - } - - private struct ScopeInternal - { - public ScopeInternal(IntermediateNodeWriter writer) - { - Writer = writer; - } - - public IntermediateNodeWriter Writer { get; } - } -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultDocumentWriter.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultDocumentWriter.cs index 72c3b39d0f1..550e32ca7ea 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultDocumentWriter.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/DefaultDocumentWriter.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Linq; using System.Security.Cryptography; @@ -10,66 +8,51 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration; -internal class DefaultDocumentWriter : DocumentWriter +internal class DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options) : DocumentWriter { - private readonly CodeTarget _codeTarget; - private readonly RazorCodeGenerationOptions _options; - - public DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options) - { - _codeTarget = codeTarget; - _options = options; - } + private readonly CodeTarget _codeTarget = codeTarget; + private readonly RazorCodeGenerationOptions _options = options; public override RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) { - if (codeDocument == null) - { - throw new ArgumentNullException(nameof(codeDocument)); - } - - if (documentNode == null) - { - throw new ArgumentNullException(nameof(documentNode)); - } + ArgHelper.ThrowIfNull(codeDocument); + ArgHelper.ThrowIfNull(documentNode); - using var context = new DefaultCodeRenderingContext( + using var context = new CodeRenderingContext( _codeTarget.CreateNodeWriter(), - codeDocument, + codeDocument.Source, documentNode, _options); - context.Visitor = new Visitor(_codeTarget, context); + + context.SetVisitor(new Visitor(_codeTarget, context)); context.Visitor.VisitDocument(documentNode); - var cSharp = context.CodeWriter.GenerateCode(); + var generatedCode = context.CodeWriter.GenerateCode(); - var allOrderedDiagnostics = context.Diagnostics.OrderBy(diagnostic => diagnostic.Span.AbsoluteIndex); - return new DefaultRazorCSharpDocument( + return new RazorCSharpDocument( codeDocument, - cSharp, + generatedCode, _options, - allOrderedDiagnostics.ToArray(), - context.SourceMappings.DrainToImmutable(), - context.LinePragmas.ToArray()); + context.GetDiagnostics(), + context.GetSourceMappings(), + context.GetLinePragmas()); } - private class Visitor : IntermediateNodeVisitor + private sealed class Visitor(CodeTarget codeTarget, CodeRenderingContext context) : IntermediateNodeVisitor { - private readonly DefaultCodeRenderingContext _context; - private readonly CodeTarget _target; - - public Visitor(CodeTarget target, DefaultCodeRenderingContext context) - { - _target = target; - _context = context; - } + private readonly CodeRenderingContext _context = context; + private readonly CodeTarget _codeTarget = codeTarget; - private DefaultCodeRenderingContext Context => _context; + private CodeWriter CodeWriter => _context.CodeWriter; + private IntermediateNodeWriter NodeWriter => _context.NodeWriter; + private RazorCodeGenerationOptions Options => _context.Options; public override void VisitDocument(DocumentIntermediateNode node) { - if (!Context.Options.SuppressChecksum) + var codeWriter = CodeWriter; + + if (!Options.SuppressChecksum) { // See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx // And https://github.com/dotnet/roslyn/blob/614299ff83da9959fa07131c6d0ffbc58873b6ae/src/Compilers/Core/Portable/PEWriter/DebugSourceDocument.cs#L67 @@ -77,7 +60,7 @@ public override void VisitDocument(DocumentIntermediateNode node) // We only support algorithms that the debugger understands, which is currently SHA1 and SHA256. string algorithmId; - var algorithm = Context.SourceDocument.Text.ChecksumAlgorithm; + var algorithm = _context.SourceDocument.Text.ChecksumAlgorithm; if (algorithm == CodeAnalysis.Text.SourceHashAlgorithm.Sha256) { algorithmId = "{8829d00f-11b8-4213-878b-770e8597ac16}"; @@ -88,80 +71,75 @@ public override void VisitDocument(DocumentIntermediateNode node) } else { - var supportedAlgorithms = string.Join(" ", new string[] - { - HashAlgorithmName.SHA1.Name, - HashAlgorithmName.SHA256.Name - }); + string?[] supportedAlgorithms = [HashAlgorithmName.SHA1.Name, HashAlgorithmName.SHA256.Name]; var message = Resources.FormatUnsupportedChecksumAlgorithm( algorithm, - supportedAlgorithms, - nameof(RazorCodeGenerationOptions) + "." + nameof(RazorCodeGenerationOptions.SuppressChecksum), + string.Join(" ", supportedAlgorithms), + $"{nameof(RazorCodeGenerationOptions)}.{nameof(RazorCodeGenerationOptions.SuppressChecksum)}", bool.TrueString); + throw new InvalidOperationException(message); } - var sourceDocument = Context.SourceDocument; + var sourceDocument = _context.SourceDocument; var checksum = ChecksumUtilities.BytesToString(sourceDocument.Text.GetChecksum()); - if (!string.IsNullOrEmpty(checksum)) + var filePath = sourceDocument.FilePath.AssumeNotNull(); + + if (checksum.Length > 0) { - Context.CodeWriter - .Write("#pragma checksum \"") - .Write(sourceDocument.FilePath) - .Write("\" \"") - .Write(algorithmId) - .Write("\" \"") - .Write(checksum) - .WriteLine("\""); + codeWriter.WriteLine($"#pragma checksum \"{filePath}\" \"{algorithmId}\" \"{checksum}\""); } } - Context.CodeWriter + codeWriter .WriteLine("// ") .WriteLine("#pragma warning disable 1591"); VisitDefault(node); - Context.CodeWriter.WriteLine("#pragma warning restore 1591"); + codeWriter.WriteLine("#pragma warning restore 1591"); } public override void VisitUsingDirective(UsingDirectiveIntermediateNode node) { - Context.NodeWriter.WriteUsingDirective(Context, node); + NodeWriter.WriteUsingDirective(_context, node); } public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node) { - using (Context.CodeWriter.BuildNamespace(node.Content, node.Source, Context)) + var codeWriter = CodeWriter; + + using (codeWriter.BuildNamespace(node.Content, node.Source, _context)) { if (node.Children.OfType().Any()) { // Tooling needs at least one line directive before using directives, otherwise Roslyn will // not offer to create a new one. The last using in the group will output a hidden line // directive after itself. - Context.CodeWriter.WriteLine("#line default"); + codeWriter.WriteLine("#line default"); } else { // If there are no using directives, we output the hidden directive here. - Context.CodeWriter.WriteLine("#line hidden"); + codeWriter.WriteLine("#line hidden"); } + VisitDefault(node); } } public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node) { - using (Context.CodeWriter.BuildClassDeclaration( + using (CodeWriter.BuildClassDeclaration( node.Modifiers, node.ClassName, node.BaseType, node.Interfaces, node.TypeParameters, - Context, - useNullableContext: !Context.Options.SuppressNullabilityEnforcement && node.Annotations[CommonAnnotations.NullableContext] is not null)) + _context, + useNullableContext: !Options.SuppressNullabilityEnforcement && node.Annotations[CommonAnnotations.NullableContext] is not null)) { VisitDefault(node); } @@ -169,100 +147,99 @@ public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node) { - Context.CodeWriter.WriteLine("#pragma warning disable 1998"); + var codeWriter = CodeWriter; + + codeWriter.WriteLine("#pragma warning disable 1998"); for (var i = 0; i < node.Modifiers.Count; i++) { - Context.CodeWriter.Write(node.Modifiers[i]); - Context.CodeWriter.Write(" "); + codeWriter.Write($"{node.Modifiers[i]} "); } - Context.CodeWriter.Write(node.ReturnType); - Context.CodeWriter.Write(" "); + codeWriter.Write($"{node.ReturnType} "); + codeWriter.Write($"{node.MethodName}("); - Context.CodeWriter.Write(node.MethodName); - Context.CodeWriter.Write("("); + var isFirst = true; for (var i = 0; i < node.Parameters.Count; i++) { var parameter = node.Parameters[i]; - for (var j = 0; j < parameter.Modifiers.Count; j++) + if (isFirst) { - Context.CodeWriter.Write(parameter.Modifiers[j]); - Context.CodeWriter.Write(" "); + isFirst = false; + } + else + { + codeWriter.Write(", "); } - Context.CodeWriter.Write(parameter.TypeName); - Context.CodeWriter.Write(" "); - - Context.CodeWriter.Write(parameter.ParameterName); - - if (i < node.Parameters.Count - 1) + for (var j = 0; j < parameter.Modifiers.Count; j++) { - Context.CodeWriter.Write(", "); + codeWriter.Write($"{parameter.Modifiers[j]} "); } + + codeWriter.Write($"{parameter.TypeName} {parameter.ParameterName}"); } - Context.CodeWriter.Write(")"); - Context.CodeWriter.WriteLine(); + codeWriter.WriteLine(")"); - using (Context.CodeWriter.BuildScope()) + using (codeWriter.BuildScope()) { VisitDefault(node); } - Context.CodeWriter.WriteLine("#pragma warning restore 1998"); + codeWriter.WriteLine("#pragma warning restore 1998"); } public override void VisitFieldDeclaration(FieldDeclarationIntermediateNode node) { - Context.CodeWriter.WriteField(node.SuppressWarnings, node.Modifiers, node.FieldType, node.FieldName); + CodeWriter.WriteField(node.SuppressWarnings, node.Modifiers, node.FieldType, node.FieldName); } public override void VisitPropertyDeclaration(PropertyDeclarationIntermediateNode node) { - Context.CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.PropertyType, node.PropertyName); + CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.PropertyType, node.PropertyName); } public override void VisitExtension(ExtensionIntermediateNode node) { - node.WriteNode(_target, Context); + node.WriteNode(_codeTarget, _context); } public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node) { - Context.NodeWriter.WriteCSharpExpression(Context, node); + NodeWriter.WriteCSharpExpression(_context, node); } public override void VisitCSharpCode(CSharpCodeIntermediateNode node) { - Context.NodeWriter.WriteCSharpCode(Context, node); + NodeWriter.WriteCSharpCode(_context, node); } public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node) { - Context.NodeWriter.WriteHtmlAttribute(Context, node); + NodeWriter.WriteHtmlAttribute(_context, node); } public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node) { - Context.NodeWriter.WriteHtmlAttributeValue(Context, node); + NodeWriter.WriteHtmlAttributeValue(_context, node); } public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node) { - Context.NodeWriter.WriteCSharpExpressionAttributeValue(Context, node); + NodeWriter.WriteCSharpExpressionAttributeValue(_context, node); } public override void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node) { - Context.NodeWriter.WriteCSharpCodeAttributeValue(Context, node); + NodeWriter.WriteCSharpCodeAttributeValue(_context, node); } public override void VisitHtml(HtmlContentIntermediateNode node) { - Context.NodeWriter.WriteHtmlContent(Context, node); + NodeWriter.WriteHtmlContent(_context, node); } public override void VisitTagHelper(TagHelperIntermediateNode node) @@ -272,67 +249,67 @@ public override void VisitTagHelper(TagHelperIntermediateNode node) public override void VisitComponent(ComponentIntermediateNode node) { - Context.NodeWriter.WriteComponent(Context, node); + NodeWriter.WriteComponent(_context, node); } public override void VisitComponentAttribute(ComponentAttributeIntermediateNode node) { - Context.NodeWriter.WriteComponentAttribute(Context, node); + NodeWriter.WriteComponentAttribute(_context, node); } public override void VisitComponentChildContent(ComponentChildContentIntermediateNode node) { - Context.NodeWriter.WriteComponentChildContent(Context, node); + NodeWriter.WriteComponentChildContent(_context, node); } public override void VisitComponentTypeArgument(ComponentTypeArgumentIntermediateNode node) { - Context.NodeWriter.WriteComponentTypeArgument(Context, node); + NodeWriter.WriteComponentTypeArgument(_context, node); } public override void VisitComponentTypeInferenceMethod(ComponentTypeInferenceMethodIntermediateNode node) { - Context.NodeWriter.WriteComponentTypeInferenceMethod(Context, node); + NodeWriter.WriteComponentTypeInferenceMethod(_context, node); } public override void VisitMarkupElement(MarkupElementIntermediateNode node) { - Context.NodeWriter.WriteMarkupElement(Context, node); + NodeWriter.WriteMarkupElement(_context, node); } public override void VisitMarkupBlock(MarkupBlockIntermediateNode node) { - Context.NodeWriter.WriteMarkupBlock(Context, node); + NodeWriter.WriteMarkupBlock(_context, node); } public override void VisitReferenceCapture(ReferenceCaptureIntermediateNode node) { - Context.NodeWriter.WriteReferenceCapture(Context, node); + NodeWriter.WriteReferenceCapture(_context, node); } public override void VisitSetKey(SetKeyIntermediateNode node) { - Context.NodeWriter.WriteSetKey(Context, node); + NodeWriter.WriteSetKey(_context, node); } public override void VisitSplat(SplatIntermediateNode node) { - Context.NodeWriter.WriteSplat(Context, node); + NodeWriter.WriteSplat(_context, node); } public override void VisitRenderMode(RenderModeIntermediateNode node) { - Context.NodeWriter.WriteRenderMode(Context, node); + NodeWriter.WriteRenderMode(_context, node); } public override void VisitFormName(FormNameIntermediateNode node) { - Context.NodeWriter.WriteFormName(Context, node); + NodeWriter.WriteFormName(_context, node); } public override void VisitDefault(IntermediateNode node) { - Context.RenderChildren(node); + _context.RenderChildren(node); } } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentNodeWriter.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentNodeWriter.cs index 01fc235d3ed..9e924a6b382 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentNodeWriter.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentNodeWriter.cs @@ -58,7 +58,7 @@ public sealed override void WriteCSharpCodeAttributeValue(CodeRenderingContext c // // We provide an error for this case just to be friendly. var content = string.Join("", node.Children.OfType().Select(t => t.Content)); - context.Diagnostics.Add(ComponentDiagnosticFactory.Create_CodeBlockInAttribute(node.Source, content)); + context.AddDiagnostic(ComponentDiagnosticFactory.Create_CodeBlockInAttribute(node.Source, content)); return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCSharpDocument.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCSharpDocument.cs deleted file mode 100644 index 381a092eba7..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCSharpDocument.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; - -namespace Microsoft.AspNetCore.Razor.Language; - -internal class DefaultRazorCSharpDocument : RazorCSharpDocument -{ - private readonly string _generatedCode; - private readonly RazorDiagnostic[] _diagnostics; - private readonly ImmutableArray _sourceMappings; - private readonly LinePragma[] _linePragmas; - private readonly RazorCodeGenerationOptions _options; - private readonly RazorCodeDocument _codeDocument; - - public DefaultRazorCSharpDocument( - RazorCodeDocument codeDocument, - string generatedCode, - RazorCodeGenerationOptions options, - RazorDiagnostic[] diagnostics, - ImmutableArray sourceMappings, - LinePragma[] linePragmas) - { - if (generatedCode == null) - { - throw new ArgumentNullException(nameof(generatedCode)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - _codeDocument = codeDocument; - _generatedCode = generatedCode; - _options = options; - - _diagnostics = diagnostics ?? Array.Empty(); - _sourceMappings = sourceMappings; - _linePragmas = linePragmas ?? Array.Empty(); - } - - public override IReadOnlyList Diagnostics => _diagnostics; - - public override string GeneratedCode => _generatedCode; - - public override ImmutableArray SourceMappings => _sourceMappings; - - internal override IReadOnlyList LinePragmas => _linePragmas; - - public override RazorCodeGenerationOptions Options => _options; - - public override RazorCodeDocument CodeDocument => _codeDocument; -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptions.cs deleted file mode 100644 index 76fe6018dd7..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptions.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -namespace Microsoft.AspNetCore.Razor.Language; - -internal class DefaultRazorCodeGenerationOptions : RazorCodeGenerationOptions -{ - public DefaultRazorCodeGenerationOptions( - bool indentWithTabs, - int indentSize, - bool designTime, - string rootNamespace, - bool suppressChecksum, - bool suppressMetadataAttributes, - bool suppressPrimaryMethodBody, - bool suppressNullabilityEnforcement, - bool omitMinimizedComponentAttributeValues, - bool supportLocalizedComponentNames, - bool useEnhancedLinePragma, - string suppressUniqueIds, - bool suppressAddComponentParameter, - bool remapLinePragmaPathsOnWindows) - { - IndentWithTabs = indentWithTabs; - IndentSize = indentSize; - DesignTime = designTime; - RootNamespace = rootNamespace; - SuppressChecksum = suppressChecksum; - SuppressMetadataAttributes = suppressMetadataAttributes; - SuppressPrimaryMethodBody = suppressPrimaryMethodBody; - SuppressNullabilityEnforcement = suppressNullabilityEnforcement; - OmitMinimizedComponentAttributeValues = omitMinimizedComponentAttributeValues; - SupportLocalizedComponentNames = supportLocalizedComponentNames; - UseEnhancedLinePragma = useEnhancedLinePragma; - SuppressUniqueIds = suppressUniqueIds; - SuppressAddComponentParameter = suppressAddComponentParameter; - RemapLinePragmaPathsOnWindows = remapLinePragmaPathsOnWindows; - } - - public override bool DesignTime { get; } - - public override bool IndentWithTabs { get; } - - public override int IndentSize { get; } - - public override string RootNamespace { get; } - - public override bool SuppressChecksum { get; } - - public override bool SuppressNullabilityEnforcement { get; } - - public override bool OmitMinimizedComponentAttributeValues { get; } - - public override bool UseEnhancedLinePragma { get; } -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsBuilder.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsBuilder.cs deleted file mode 100644 index 12816f28a9a..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsBuilder.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System; - -namespace Microsoft.AspNetCore.Razor.Language; - -internal class DefaultRazorCodeGenerationOptionsBuilder : RazorCodeGenerationOptionsBuilder -{ - private bool _designTime; - - public DefaultRazorCodeGenerationOptionsBuilder(RazorConfiguration configuration, string fileKind) - { - if (configuration == null) - { - throw new ArgumentNullException(nameof(configuration)); - } - - Configuration = configuration; - FileKind = fileKind; - } - - public DefaultRazorCodeGenerationOptionsBuilder(bool designTime) - { - _designTime = designTime; - } - - public override RazorConfiguration Configuration { get; } - - public override bool DesignTime => _designTime; - - public override string FileKind { get; } - - public override int IndentSize { get; set; } = 4; - - public override bool IndentWithTabs { get; set; } - - public override bool SuppressChecksum { get; set; } - - public override bool SuppressNullabilityEnforcement { get; set; } - - public override bool OmitMinimizedComponentAttributeValues { get; set; } - - public override bool SupportLocalizedComponentNames { get; set; } - - public override bool UseEnhancedLinePragma { get; set; } - - public override RazorCodeGenerationOptions Build() - { - return new DefaultRazorCodeGenerationOptions( - IndentWithTabs, - IndentSize, - DesignTime, - RootNamespace, - SuppressChecksum, - SuppressMetadataAttributes, - SuppressPrimaryMethodBody, - SuppressNullabilityEnforcement, - OmitMinimizedComponentAttributeValues, - SupportLocalizedComponentNames, - UseEnhancedLinePragma, - SuppressUniqueIds, - SuppressAddComponentParameter, - RemapLinePragmaPathsOnWindows) - { - SuppressMetadataSourceChecksumAttributes = SuppressMetadataSourceChecksumAttributes, - }; - } - - public override void SetDesignTime(bool designTime) - { - _designTime = designTime; - } -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs index feeb5b3a12b..549411af2f7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorCodeGenerationOptionsFactoryProjectFeature.cs @@ -17,9 +17,9 @@ protected override void OnInitialized() _configureOptions = ProjectEngine.EngineFeatures.OfType().ToArray(); } - public RazorCodeGenerationOptions Create(string fileKind, Action configure) + public RazorCodeGenerationOptions Create(Action configure) { - var builder = new DefaultRazorCodeGenerationOptionsBuilder(ProjectEngine.Configuration, fileKind); + var builder = new RazorCodeGenerationOptionsBuilder(ProjectEngine.Configuration); configure?.Invoke(builder); for (var i = 0; i < _configureOptions.Length; i++) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/DefaultTagHelperTargetExtension.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/DefaultTagHelperTargetExtension.cs index 59c1dcc7619..381812e40f4 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/DefaultTagHelperTargetExtension.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Extensions/DefaultTagHelperTargetExtension.cs @@ -101,7 +101,7 @@ public void WriteTagHelperBody(CodeRenderingContext context, DefaultTagHelperBod // Assign a unique ID for this instance of the source HTML tag. This must be unique // per call site, e.g. if the tag is on the view twice, there should be two IDs. - var uniqueId = (string)context.Items[CodeRenderingContext.SuppressUniqueIds]; + var uniqueId = context.Options.SuppressUniqueIds; if (uniqueId == null) { uniqueId = GetDeterministicId(context); @@ -584,13 +584,13 @@ internal void RenderTagHelperAttributeInline( else if (node is CSharpCodeIntermediateNode) { var diagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(span); - context.Diagnostics.Add(diagnostic); + context.AddDiagnostic(diagnostic); } else if (node is TemplateIntermediateNode) { var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName; var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(span, expectedTypeName); - context.Diagnostics.Add(diagnostic); + context.AddDiagnostic(diagnostic); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/IRazorCodeGenerationOptionsFactoryProjectFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/IRazorCodeGenerationOptionsFactoryProjectFeature.cs index 9865f4d792c..3c42ef62a00 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/IRazorCodeGenerationOptionsFactoryProjectFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/IRazorCodeGenerationOptionsFactoryProjectFeature.cs @@ -9,5 +9,5 @@ namespace Microsoft.AspNetCore.Razor.Language; internal interface IRazorCodeGenerationOptionsFactoryProjectFeature : IRazorProjectEngineFeature { - RazorCodeGenerationOptions Create(string fileKind, Action configure); + RazorCodeGenerationOptions Create(Action configure); } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/ExtensionIntermediateNode.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/ExtensionIntermediateNode.cs index df5d210c550..7495f8e2995 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/ExtensionIntermediateNode.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/ExtensionIntermediateNode.cs @@ -34,7 +34,7 @@ protected void ReportMissingCodeTargetExtension(CodeRenderingContex } var documentKind = context.DocumentKind ?? string.Empty; - context.Diagnostics.Add( + context.AddDiagnostic( RazorDiagnosticFactory.CreateCodeTarget_UnsupportedExtension( documentKind, typeof(TDependency))); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/IntermediateNodeExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/IntermediateNodeExtensions.cs index 72516dd6dcb..8cc6a373a85 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/IntermediateNodeExtensions.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Intermediate/IntermediateNodeExtensions.cs @@ -3,17 +3,15 @@ #nullable disable -using System; using System.Collections.Generic; -using System.Linq; +using System.Collections.Immutable; using Microsoft.AspNetCore.Razor.Language.Components; +using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language.Intermediate; public static class IntermediateNodeExtensions { - private static readonly IReadOnlyList EmptyDiagnostics = Array.Empty(); - public static bool IsImported(this IntermediateNode node) { return ReferenceEquals(node.Annotations[CommonAnnotations.Imported], CommonAnnotations.Imported); @@ -26,36 +24,32 @@ public static bool IsDesignTimePropertyAccessHelper(this IntermediateNode tagHel result; } - public static IReadOnlyList GetAllDiagnostics(this IntermediateNode node) + public static ImmutableArray GetAllDiagnostics(this IntermediateNode node) { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } - - HashSet diagnostics = null; - - AddAllDiagnostics(node); + ArgHelper.ThrowIfNull(node); - var allOrderedDiagnostics = diagnostics?.OrderBy(diagnostic => diagnostic.Span.AbsoluteIndex); + var diagnostics = new PooledHashSet(); + try + { + CollectDiagnostics(node, ref diagnostics); - return allOrderedDiagnostics?.ToList() ?? EmptyDiagnostics; + return diagnostics.OrderByAsArray(static d => d.Span.AbsoluteIndex); + } + finally + { + diagnostics.ClearAndFree(); + } - void AddAllDiagnostics(IntermediateNode n) + static void CollectDiagnostics(IntermediateNode node, ref PooledHashSet diagnostics) { - if (n.HasDiagnostics) + if (node.HasDiagnostics) { - if (diagnostics == null) - { - diagnostics = new HashSet(); - } - - diagnostics.UnionWith(n.Diagnostics); + diagnostics.UnionWith(node.Diagnostics); } - for (var i = 0; i < n.Children.Count; i++) + foreach (var childNode in node.Children) { - AddAllDiagnostics(n.Children[i]); + CollectDiagnostics(childNode, ref diagnostics); } } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCSharpDocument.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCSharpDocument.cs index fc16701d2f7..2a00090ac94 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCSharpDocument.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCSharpDocument.cs @@ -1,81 +1,38 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using Microsoft.AspNetCore.Razor.Language.CodeGeneration; namespace Microsoft.AspNetCore.Razor.Language; -public abstract class RazorCSharpDocument : IRazorGeneratedDocument +public sealed class RazorCSharpDocument : IRazorGeneratedDocument { - public abstract string GeneratedCode { get; } - - public abstract ImmutableArray SourceMappings { get; } - - public abstract IReadOnlyList Diagnostics { get; } - - public abstract RazorCodeGenerationOptions Options { get; } - - public abstract RazorCodeDocument CodeDocument { get; } - - internal virtual IReadOnlyList LinePragmas { get; } - - [Obsolete("For backwards compatibility only. Use the overload that takes a RazorCodeDocument")] - public static RazorCSharpDocument Create(string generatedCode, RazorCodeGenerationOptions options, IEnumerable diagnostics) - => Create(codeDocument: null, generatedCode, options, diagnostics); - - [Obsolete("For backwards compatibility only. Use the overload that takes a RazorCodeDocument")] - public static RazorCSharpDocument Create(string generatedCode, RazorCodeGenerationOptions options, IEnumerable diagnostics, ImmutableArray sourceMappings, IEnumerable linePragmas) - => Create(codeDocument: null, generatedCode, options, diagnostics, sourceMappings, linePragmas); - - public static RazorCSharpDocument Create(RazorCodeDocument codeDocument, string generatedCode, RazorCodeGenerationOptions options, IEnumerable diagnostics) - { - if (generatedCode == null) - { - throw new ArgumentNullException(nameof(generatedCode)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - - return new DefaultRazorCSharpDocument(codeDocument, generatedCode, options, diagnostics.ToArray(), sourceMappings: ImmutableArray.Empty, linePragmas: null); - } - - public static RazorCSharpDocument Create( + public RazorCodeDocument CodeDocument { get; } + public string GeneratedCode { get; } + public RazorCodeGenerationOptions Options { get; } + public ImmutableArray Diagnostics { get; } + public ImmutableArray SourceMappings { get; } + public ImmutableArray LinePragmas { get; } + + public RazorCSharpDocument( RazorCodeDocument codeDocument, string generatedCode, RazorCodeGenerationOptions options, - IEnumerable diagnostics, - ImmutableArray sourceMappings, - IEnumerable linePragmas) + ImmutableArray diagnostics, + ImmutableArray sourceMappings = default, + ImmutableArray linePragmas = default) { - if (generatedCode == null) - { - throw new ArgumentNullException(nameof(generatedCode)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgHelper.ThrowIfNull(codeDocument); + ArgHelper.ThrowIfNull(generatedCode); + ArgHelper.ThrowIfNull(options); - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } + CodeDocument = codeDocument; + GeneratedCode = generatedCode; + Options = options; - return new DefaultRazorCSharpDocument(codeDocument, generatedCode, options, diagnostics.ToArray(), sourceMappings, linePragmas.ToArray()); + Diagnostics = diagnostics.NullToEmpty(); + SourceMappings = sourceMappings.NullToEmpty(); + LinePragmas = linePragmas.NullToEmpty(); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptions.cs index a055dddf6e8..62d0985a558 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptions.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptions.cs @@ -1,94 +1,29 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; namespace Microsoft.AspNetCore.Razor.Language; -public abstract class RazorCodeGenerationOptions +public sealed class RazorCodeGenerationOptions( + RazorCodeGenerationOptionsFlags flags, + int indentSize, + string newLine, + string? rootNamespace, + string? suppressUniqueIds) { - public static RazorCodeGenerationOptions CreateDefault() - { - return new DefaultRazorCodeGenerationOptions( - indentWithTabs: false, - indentSize: 4, - designTime: false, - suppressChecksum: false, - rootNamespace: null, - suppressMetadataAttributes: false, - suppressPrimaryMethodBody: false, - suppressNullabilityEnforcement: false, - omitMinimizedComponentAttributeValues: false, - supportLocalizedComponentNames: false, - useEnhancedLinePragma: true, - suppressUniqueIds: null, - suppressAddComponentParameter: false, - remapLinePragmaPathsOnWindows: false); - } - - public static RazorCodeGenerationOptions CreateDesignTimeDefault() - { - return new DefaultRazorCodeGenerationOptions( - indentWithTabs: false, - indentSize: 4, - designTime: true, - rootNamespace: null, - suppressChecksum: false, - suppressMetadataAttributes: true, - suppressPrimaryMethodBody: false, - suppressNullabilityEnforcement: false, - omitMinimizedComponentAttributeValues: false, - supportLocalizedComponentNames: false, - useEnhancedLinePragma: true, - suppressUniqueIds: null, - suppressAddComponentParameter: false, - remapLinePragmaPathsOnWindows: true); - } - - public static RazorCodeGenerationOptions Create(Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - var builder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false); - configure(builder); - var options = builder.Build(); - - return options; - } - - public static RazorCodeGenerationOptions CreateDesignTime(Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - var builder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: true) - { - SuppressMetadataAttributes = true, - }; - - configure(builder); - var options = builder.Build(); - - return options; - } + private readonly RazorCodeGenerationOptionsFlags _flags = flags; - public abstract bool DesignTime { get; } + public bool DesignTime => _flags.HasFlag(RazorCodeGenerationOptionsFlags.DesignTime); - public abstract bool IndentWithTabs { get; } - - public abstract int IndentSize { get; } + public bool IndentWithTabs => _flags.HasFlag(RazorCodeGenerationOptionsFlags.IndentWithTabs); + public int IndentSize { get; } = indentSize; + public string NewLine { get; } = newLine; ///

/// Gets the root namespace for the generated code. /// - public virtual string RootNamespace { get; } + public string? RootNamespace { get; } = rootNamespace; /// /// Gets a value that indicates whether to suppress the default #pragma checksum directive in the @@ -99,7 +34,8 @@ public static RazorCodeGenerationOptions CreateDesignTime(Action#pragma checksum is required to enable debugging and should only be suppressed for testing /// purposes. /// - public abstract bool SuppressChecksum { get; } + public bool SuppressChecksum + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressChecksum); /// /// Gets a value that indicates whether to suppress the default metadata attributes in the generated @@ -117,7 +53,8 @@ public static RazorCodeGenerationOptions CreateDesignTime(ActionMicrosoft.AspNetCore.Razor.Runtime, or for testing purposes. /// /// - public virtual bool SuppressMetadataAttributes { get; protected set; } + public bool SuppressMetadataAttributes + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressMetadataAttributes); /// /// Gets a value that indicates whether to suppress the RazorSourceChecksumAttribute. @@ -126,45 +63,106 @@ public static RazorCodeGenerationOptions CreateDesignTime(Action /// - internal bool SuppressMetadataSourceChecksumAttributes { get; set; } + public bool SuppressMetadataSourceChecksumAttributes + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressMetadataSourceChecksumAttributes); /// /// Gets or sets a value that determines if an empty body is generated for the primary method. /// - public virtual bool SuppressPrimaryMethodBody { get; protected set; } + public bool SuppressPrimaryMethodBody + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressPrimaryMethodBody); /// /// Gets a value that determines if nullability type enforcement should be suppressed for user code. /// - public virtual bool SuppressNullabilityEnforcement { get; } + public bool SuppressNullabilityEnforcement + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressNullabilityEnforcement); /// /// Gets a value that determines if the components code writer may omit values for minimized attributes. /// - public virtual bool OmitMinimizedComponentAttributeValues { get; } + public bool OmitMinimizedComponentAttributeValues + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.OmitMinimizedComponentAttributeValues); /// /// Gets a value that determines if localized component names are to be supported. /// - public virtual bool SupportLocalizedComponentNames { get; set; } + public bool SupportLocalizedComponentNames + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SupportLocalizedComponentNames); /// /// Gets a value that determines if enhanced line pragmas are to be utilized. /// - public virtual bool UseEnhancedLinePragma { get; } + public bool UseEnhancedLinePragma + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.UseEnhancedLinePragma); /// /// Gets a value used for unique ids for testing purposes. Null for unique ids. /// - internal string SuppressUniqueIds { get; private protected init; } + public string? SuppressUniqueIds { get; } = suppressUniqueIds; /// /// Determines whether RenderTreeBuilder.AddComponentParameter should not be used. /// - internal bool SuppressAddComponentParameter { get; private protected init; } + public bool SuppressAddComponentParameter + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.SuppressAddComponentParameter); /// /// Determines if the file paths emitted as part of line pragmas should be mapped back to a valid path on windows. /// - public bool RemapLinePragmaPathsOnWindows { get; private protected init; } + public bool RemapLinePragmaPathsOnWindows + => _flags.HasFlag(RazorCodeGenerationOptionsFlags.RemapLinePragmaPathsOnWindows); + + public static RazorCodeGenerationOptions Default { get; } = new RazorCodeGenerationOptions( + flags: RazorCodeGenerationOptionsFlags.DefaultFlags, + indentSize: 4, + newLine: Environment.NewLine, + rootNamespace: null, + suppressUniqueIds: null); + + public static RazorCodeGenerationOptions DesignTimeDefault { get; } = new RazorCodeGenerationOptions( + flags: RazorCodeGenerationOptionsFlags.DefaultDesignTimeFlags, + indentSize: 4, + newLine: Environment.NewLine, + rootNamespace: null, + suppressUniqueIds: null); + + public static RazorCodeGenerationOptions Create(Action configure) + { + ArgHelper.ThrowIfNull(configure); + + var builder = new RazorCodeGenerationOptionsBuilder(designTime: false); + configure(builder); + var options = builder.Build(); + + return options; + } + + public static RazorCodeGenerationOptions CreateDesignTime(Action configure) + { + ArgHelper.ThrowIfNull(configure); + + var builder = new RazorCodeGenerationOptionsBuilder(designTime: true) + { + SuppressMetadataAttributes = true, + }; + + configure(builder); + var options = builder.Build(); + + return options; + } + + public RazorCodeGenerationOptionsBuilder ToBuilder() + { + var builder = new RazorCodeGenerationOptionsBuilder(_flags) + { + IndentSize = IndentSize, + NewLine = NewLine, + RootNamespace = RootNamespace, + SuppressUniqueIds = SuppressUniqueIds + }; + + return builder; + } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsBuilder.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsBuilder.cs index e80598b6177..4f35d92c094 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsBuilder.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsBuilder.cs @@ -1,26 +1,40 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable +using System; namespace Microsoft.AspNetCore.Razor.Language; -public abstract class RazorCodeGenerationOptionsBuilder +public sealed class RazorCodeGenerationOptionsBuilder { - public virtual RazorConfiguration Configuration => null; + private RazorCodeGenerationOptionsFlags _flags; + private string _newLine = Environment.NewLine; - public abstract bool DesignTime { get; } + public RazorConfiguration? Configuration { get; } - public virtual string FileKind => null; + public bool DesignTime => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.DesignTime); - public abstract int IndentSize { get; set; } + public int IndentSize { get; set; } = 4; - public abstract bool IndentWithTabs { get; set; } + public string NewLine + { + get => _newLine; + set + { + _newLine = value ?? Environment.NewLine; + } + } + + public bool IndentWithTabs + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.IndentWithTabs); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.IndentWithTabs, value); + } /// /// Gets or sets the root namespace of the generated code. /// - public virtual string RootNamespace { get; set; } + public string? RootNamespace { get; set; } /// /// Gets or sets a value that indicates whether to suppress the default #pragma checksum directive in the @@ -31,7 +45,11 @@ public abstract class RazorCodeGenerationOptionsBuilder /// The #pragma checksum is required to enable debugging and should only be suppressed for testing /// purposes. /// - public abstract bool SuppressChecksum { get; set; } + public bool SuppressChecksum + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressChecksum); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressChecksum, value); + } /// /// Gets or sets a value that indicates whether to suppress the default metadata attributes in the generated @@ -49,7 +67,11 @@ public abstract class RazorCodeGenerationOptionsBuilder /// a reference to Microsoft.AspNetCore.Razor.Runtime, or for testing purposes. /// /// - public virtual bool SuppressMetadataAttributes { get; set; } + public bool SuppressMetadataAttributes + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressMetadataAttributes); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressMetadataAttributes, value); + } /// /// Gets a value that indicates whether to suppress the RazorSourceChecksumAttribute. @@ -58,51 +80,110 @@ public abstract class RazorCodeGenerationOptionsBuilder /// edit are treated as rude edits by hot reload. /// /// - internal bool SuppressMetadataSourceChecksumAttributes { get; set; } + public bool SuppressMetadataSourceChecksumAttributes + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressMetadataSourceChecksumAttributes); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressMetadataSourceChecksumAttributes, value); + } /// /// Gets or sets a value that determines if an empty body is generated for the primary method. /// - public virtual bool SuppressPrimaryMethodBody { get; set; } + public bool SuppressPrimaryMethodBody + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressPrimaryMethodBody); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressPrimaryMethodBody, value); + } /// /// Gets or sets a value that determines if nullability type enforcement should be suppressed for user code. /// - public virtual bool SuppressNullabilityEnforcement { get; set; } + public bool SuppressNullabilityEnforcement + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressNullabilityEnforcement); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressNullabilityEnforcement, value); + } /// /// Gets or sets a value that determines if the components code writer may omit values for minimized attributes. /// - public virtual bool OmitMinimizedComponentAttributeValues { get; set; } + public bool OmitMinimizedComponentAttributeValues + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.OmitMinimizedComponentAttributeValues); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.OmitMinimizedComponentAttributeValues, value); + } /// /// Gets or sets a value that determines if localized component names are to be supported. /// - public virtual bool SupportLocalizedComponentNames { get; set; } + public bool SupportLocalizedComponentNames + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SupportLocalizedComponentNames); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SupportLocalizedComponentNames, value); + } /// /// Gets or sets a value that determines if enhanced line pragmas are to be utilized. /// - public virtual bool UseEnhancedLinePragma { get; set; } + public bool UseEnhancedLinePragma + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.UseEnhancedLinePragma); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.UseEnhancedLinePragma, value); + } /// /// Gets or sets a value that determines if unique ids are suppressed for testing. /// - internal string SuppressUniqueIds { get; set; } + public string? SuppressUniqueIds { get; set; } /// /// Determines whether RenderTreeBuilder.AddComponentParameter should not be used. /// - internal bool SuppressAddComponentParameter { get; set; } + public bool SuppressAddComponentParameter + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.SuppressAddComponentParameter); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.SuppressAddComponentParameter, value); + } /// /// Determines if the file paths emitted as part of line pragmas should be mapped back to a valid path on windows. /// - internal bool RemapLinePragmaPathsOnWindows { get; set; } + public bool RemapLinePragmaPathsOnWindows + { + get => _flags.IsFlagSet(RazorCodeGenerationOptionsFlags.RemapLinePragmaPathsOnWindows); + set => _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.RemapLinePragmaPathsOnWindows, value); + } + + public RazorCodeGenerationOptionsBuilder(RazorConfiguration configuration) + { + ArgHelper.ThrowIfNull(configuration); + + Configuration = configuration; + } + + public RazorCodeGenerationOptionsBuilder(RazorCodeGenerationOptionsFlags flags) + { + _flags = flags; + } + + public RazorCodeGenerationOptionsBuilder(bool designTime) + { + if (designTime) + { + _flags = RazorCodeGenerationOptionsFlags.DesignTime; + } + } - public abstract RazorCodeGenerationOptions Build(); + public RazorCodeGenerationOptions Build() + => new( + _flags, + IndentSize, + NewLine, + RootNamespace, + SuppressUniqueIds); - public virtual void SetDesignTime(bool designTime) + public void SetDesignTime(bool value) { + _flags.UpdateFlag(RazorCodeGenerationOptionsFlags.DesignTime, value); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsFlags.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsFlags.cs new file mode 100644 index 00000000000..f0c651e8e40 --- /dev/null +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeGenerationOptionsFlags.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.AspNetCore.Razor.Language; + +[Flags] +public enum RazorCodeGenerationOptionsFlags +{ + DesignTime = 1 << 0, + IndentWithTabs = 1 << 1, + SuppressChecksum = 1 << 2, + SuppressMetadataAttributes = 1 << 3, + SuppressMetadataSourceChecksumAttributes = 1 << 4, + SuppressPrimaryMethodBody = 1 << 5, + SuppressNullabilityEnforcement = 1 << 6, + OmitMinimizedComponentAttributeValues = 1 << 7, + SupportLocalizedComponentNames = 1 << 8, + UseEnhancedLinePragma = 1 << 9, + SuppressAddComponentParameter = 1 << 10, + RemapLinePragmaPathsOnWindows = 1 << 11, + + DefaultFlags = UseEnhancedLinePragma, + DefaultDesignTimeFlags = DesignTime | SuppressMetadataAttributes | UseEnhancedLinePragma | RemapLinePragmaPathsOnWindows +} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorProjectEngine.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorProjectEngine.cs index 81afcdf946c..3675b59bf42 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorProjectEngine.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorProjectEngine.cs @@ -185,7 +185,7 @@ internal RazorCodeDocument CreateCodeDocumentCore( ConfigureParserOptions(builder); configureParser?.Invoke(builder); }); - var codeGenerationOptions = GetRequiredFeature().Create(fileKind, builder => + var codeGenerationOptions = GetRequiredFeature().Create(builder => { ConfigureCodeGenerationOptions(builder); configureCodeGeneration?.Invoke(builder); @@ -261,7 +261,7 @@ private RazorCodeDocument CreateCodeDocumentDesignTimeCore( ConfigureDesignTimeParserOptions(builder); configureParser?.Invoke(builder); }); - var codeGenerationOptions = GetRequiredFeature().Create(fileKind, builder => + var codeGenerationOptions = GetRequiredFeature().Create(builder => { ConfigureDesignTimeCodeGenerationOptions(builder); configureCodeGeneration?.Invoke(builder); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.cs index f7bdfb0310e..0fe65e3eb60 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.cs @@ -313,7 +313,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) }) .WithLambdaComparer(static (a, b) => { - if (a.csharpDocument.Diagnostics.Count > 0 || b.csharpDocument.Diagnostics.Count > 0) + if (a.csharpDocument.Diagnostics.Length > 0 || b.csharpDocument.Diagnostics.Length > 0) { // if there are any diagnostics, treat the documents as unequal and force RegisterSourceOutput to be called uncached. return false; @@ -339,9 +339,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var hintName = GetIdentifierFromPath(filePath) + ".g.cs"; RazorSourceGeneratorEventSource.Log.AddSyntaxTrees(hintName); - for (var i = 0; i < csharpDocument.Diagnostics.Count; i++) + foreach (var razorDiagnostic in csharpDocument.Diagnostics) { - var razorDiagnostic = csharpDocument.Diagnostics[i]; var csharpDiagnostic = razorDiagnostic.AsDiagnostic(); context.ReportDiagnostic(csharpDiagnostic); } diff --git a/src/Compiler/perf/Microbenchmarks/CodeGenerationBenchmark.cs b/src/Compiler/perf/Microbenchmarks/CodeGenerationBenchmark.cs index 42bf5b84580..90a85e481e8 100644 --- a/src/Compiler/perf/Microbenchmarks/CodeGenerationBenchmark.cs +++ b/src/Compiler/perf/Microbenchmarks/CodeGenerationBenchmark.cs @@ -39,7 +39,7 @@ public void CodeGeneration_DesignTime_LargeStaticFile() var codeDocument = ProjectEngine.ProcessDesignTime(MSN); var generated = codeDocument.GetCSharpDocument(); - if (generated.Diagnostics.Count != 0) + if (generated.Diagnostics.Length > 0) { throw new Exception("Error!" + Environment.NewLine + string.Join(Environment.NewLine, generated.Diagnostics)); } @@ -51,7 +51,7 @@ public void CodeGeneration_Runtime_LargeStaticFile() var codeDocument = ProjectEngine.Process(MSN); var generated = codeDocument.GetCSharpDocument(); - if (generated.Diagnostics.Count != 0) + if (generated.Diagnostics.Length > 0) { throw new Exception("Error!" + Environment.NewLine + string.Join(Environment.NewLine, generated.Diagnostics)); } diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorDiagnosticsBenchmark.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorDiagnosticsBenchmark.cs index 9e50156d7f5..d6408537f53 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorDiagnosticsBenchmark.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorDiagnosticsBenchmark.cs @@ -10,7 +10,6 @@ using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.AspNetCore.Razor.LanguageServer.Hosting; @@ -58,14 +57,13 @@ public void Setup() var stringSourceDocument = RazorSourceDocument.Create(GetFileContents(), UTF8Encoding.UTF8, RazorSourceDocumentProperties.Default); var mockRazorCodeDocument = new Mock(MockBehavior.Strict); - var mockRazorCSharpDocument = RazorCSharpDocument.Create( + var mockRazorCSharpDocument = new RazorCSharpDocument( mockRazorCodeDocument.Object, GeneratedCode, - RazorCodeGenerationOptions.CreateDesignTimeDefault(), - Array.Empty(), + RazorCodeGenerationOptions.DesignTimeDefault, + diagnostics: [], SourceMappings, - new List() - ); + linePragmas: []); var itemCollection = new ItemCollection(); itemCollection[typeof(RazorCSharpDocument)] = mockRazorCSharpDocument; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ExternalAccess.LegacyEditor/RazorWrapperFactory.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ExternalAccess.LegacyEditor/RazorWrapperFactory.cs index 216ffd6c9ca..e2014f4b761 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ExternalAccess.LegacyEditor/RazorWrapperFactory.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ExternalAccess.LegacyEditor/RazorWrapperFactory.cs @@ -58,26 +58,6 @@ private static ImmutableArray WrapAll(ImmutableArray WrapAll(IReadOnlyList list, Func createWrapper) - where TInner : class - where TResult : class - { - var count = list.Count; - if (count == 0) - { - return ImmutableArray.Empty; - } - - using var builder = new PooledArrayBuilder(capacity: count); - - for (var i = 0; i < count; i++) - { - builder.Add(createWrapper(list[i])); - } - - return builder.DrainToImmutable(); - } - private static ImmutableArray WrapAll(IEnumerable items, Func createWrapper) where TInner : class where TResult : class diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs index 68d893f9b24..5550bd39c40 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs @@ -128,7 +128,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalDocumentDiagno var csharpDocument = codeDocument.GetCSharpDocument(); var diagnostics = csharpDocument.Diagnostics; - if (diagnostics.Count == 0) + if (diagnostics.Length == 0) { return null; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectEngineHost/UnsupportedCSharpLoweringPhase.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectEngineHost/UnsupportedCSharpLoweringPhase.cs index 53905d716e8..606a35ef44b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectEngineHost/UnsupportedCSharpLoweringPhase.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/ProjectEngineHost/UnsupportedCSharpLoweringPhase.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System.Linq; using Microsoft.AspNetCore.Razor.Language; namespace Microsoft.AspNetCore.Razor.ProjectEngineHost; @@ -15,12 +14,8 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument) var documentNode = codeDocument.GetDocumentIntermediateNode(); ThrowForMissingDocumentDependency(documentNode); - var cSharpDocument = RazorCSharpDocument.Create( - codeDocument, - UnsupportedDisclaimer, - documentNode.Options, - Enumerable.Empty()); - codeDocument.SetCSharpDocument(cSharpDocument); + var csharpDocument = new RazorCSharpDocument(codeDocument, UnsupportedDisclaimer, documentNode.Options, diagnostics: []); + codeDocument.SetCSharpDocument(csharpDocument); codeDocument.SetUnsupported(); } } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/DefaultCSharpCodeActionProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/DefaultCSharpCodeActionProviderTest.cs index 335e5df5f48..bd93514e88f 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/DefaultCSharpCodeActionProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/DefaultCSharpCodeActionProviderTest.cs @@ -326,11 +326,11 @@ private static RazorCodeActionContext CreateRazorCodeActionContext( var projectEngine = RazorProjectEngine.Create(builder => builder.AddTagHelpers(tagHelpers)); var codeDocument = projectEngine.ProcessDesignTime(sourceDocument, FileKinds.Component, importSources: default, tagHelpers); - var cSharpDocument = codeDocument.GetCSharpDocument(); + var csharpDocument = codeDocument.GetCSharpDocument(); var diagnosticDescriptor = new RazorDiagnosticDescriptor("RZ10012", "diagnostic", RazorDiagnosticSeverity.Error); var diagnostic = RazorDiagnostic.Create(diagnosticDescriptor, componentSourceSpan); - var cSharpDocumentWithDiagnostic = RazorCSharpDocument.Create(codeDocument, cSharpDocument.GeneratedCode, cSharpDocument.Options, new[] { diagnostic }); - codeDocument.SetCSharpDocument(cSharpDocumentWithDiagnostic); + var csharpDocumentWithDiagnostic = new RazorCSharpDocument(codeDocument, csharpDocument.GeneratedCode, csharpDocument.Options, [diagnostic]); + codeDocument.SetCSharpDocument(csharpDocumentWithDiagnostic); var documentSnapshot = Mock.Of(document => document.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) && diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/TypeAccessibilityCodeActionProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/TypeAccessibilityCodeActionProviderTest.cs index 7c3c0afff5d..610e0462269 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/TypeAccessibilityCodeActionProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/CSharp/TypeAccessibilityCodeActionProviderTest.cs @@ -457,11 +457,11 @@ private static RazorCodeActionContext CreateRazorCodeActionContext( }); var codeDocument = projectEngine.ProcessDesignTime(sourceDocument, FileKinds.Component, importSources: default, tagHelpers); - var cSharpDocument = codeDocument.GetCSharpDocument(); + var csharpDocument = codeDocument.GetCSharpDocument(); var diagnosticDescriptor = new RazorDiagnosticDescriptor("RZ10012", "diagnostic", RazorDiagnosticSeverity.Error); var diagnostic = RazorDiagnostic.Create(diagnosticDescriptor, componentSourceSpan); - var cSharpDocumentWithDiagnostic = RazorCSharpDocument.Create(codeDocument, cSharpDocument.GeneratedCode, cSharpDocument.Options, [diagnostic]); - codeDocument.SetCSharpDocument(cSharpDocumentWithDiagnostic); + var csharpDocumentWithDiagnostic = new RazorCSharpDocument(codeDocument, csharpDocument.GeneratedCode, csharpDocument.Options, [diagnostic]); + codeDocument.SetCSharpDocument(csharpDocumentWithDiagnostic); var documentSnapshot = Mock.Of(document => document.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) && diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Razor/ComponentAccessibilityCodeActionProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Razor/ComponentAccessibilityCodeActionProviderTest.cs index 7d4ca269ff6..56874c402da 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Razor/ComponentAccessibilityCodeActionProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Razor/ComponentAccessibilityCodeActionProviderTest.cs @@ -457,11 +457,11 @@ private static RazorCodeActionContext CreateRazorCodeActionContext(VSCodeActionP var projectEngine = RazorProjectEngine.Create(builder => builder.AddTagHelpers(tagHelpers)); var codeDocument = projectEngine.ProcessDesignTime(sourceDocument, FileKinds.Component, importSources: default, tagHelpers); - var cSharpDocument = codeDocument.GetCSharpDocument(); + var csharpDocument = codeDocument.GetCSharpDocument(); var diagnosticDescriptor = new RazorDiagnosticDescriptor("RZ10012", "diagnostic", RazorDiagnosticSeverity.Error); var diagnostic = RazorDiagnostic.Create(diagnosticDescriptor, componentSourceSpan); - var cSharpDocumentWithDiagnostic = RazorCSharpDocument.Create(codeDocument, cSharpDocument.GeneratedCode, cSharpDocument.Options, new[] { diagnostic }); - codeDocument.SetCSharpDocument(cSharpDocumentWithDiagnostic); + var csharpDocumentWithDiagnostic = new RazorCSharpDocument(codeDocument, csharpDocument.GeneratedCode, csharpDocument.Options, [diagnostic]); + codeDocument.SetCSharpDocument(csharpDocumentWithDiagnostic); var documentSnapshot = Mock.Of(document => document.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) && diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorDiagnosticsPublisherTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorDiagnosticsPublisherTest.cs index 4cdbc79137d..869786c9280 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorDiagnosticsPublisherTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorDiagnosticsPublisherTest.cs @@ -2,6 +2,8 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -523,10 +525,10 @@ public void ClearClosedDocuments_RestartsTimerIfDocumentsStillOpen() Assert.True(publisherAccessor.IsWaitingToClearClosedDocuments); } - private static RazorCodeDocument CreateCodeDocument(RazorDiagnostic[] diagnostics) + private static RazorCodeDocument CreateCodeDocument(IEnumerable diagnostics) { var codeDocument = TestRazorCodeDocument.Create("hello"); - var razorCSharpDocument = RazorCSharpDocument.Create(codeDocument, "hello", RazorCodeGenerationOptions.CreateDefault(), diagnostics); + var razorCSharpDocument = new RazorCSharpDocument(codeDocument, "hello", RazorCodeGenerationOptions.Default, diagnostics.ToImmutableArray()); codeDocument.SetCSharpDocument(razorCSharpDocument); return codeDocument; diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs index 17177a8e49c..086ac0c7c2a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/DocumentOnTypeFormattingEndpointTest.cs @@ -47,8 +47,7 @@ public async Task Handle_OnTypeFormatting_DocumentNotFound_ReturnsNull() @{ if(true){} }"; - var sourceMappings = new List { new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0)) }; - var codeDocument = CreateCodeDocument(content, sourceMappings); + var codeDocument = CreateCodeDocument(content, sourceMappings: [new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0))]); var uri = new Uri("file://path/test.razor"); var documentContext = CreateDocumentContext(new Uri("file://path/testDifferentFile.razor"), codeDocument); @@ -82,8 +81,7 @@ public async Task Handle_OnTypeFormatting_RemapFailed_ReturnsNull() @{ if(true){} }"; - var sourceMappings = new List { }; - var codeDocument = CreateCodeDocument(content, sourceMappings); + var codeDocument = CreateCodeDocument(content, sourceMappings: []); var uri = new Uri("file://path/test.razor"); var documentContext = CreateDocumentContext(uri, codeDocument); @@ -117,8 +115,7 @@ public async Task Handle_OnTypeFormatting_HtmlLanguageKind_ReturnsNull() @{ if(true){} }"; - var sourceMappings = new List { new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0)) }; - var codeDocument = CreateCodeDocument(content, sourceMappings); + var codeDocument = CreateCodeDocument(content, sourceMappings: [new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0))]); var uri = new Uri("file://path/test.razor"); var documentContext = CreateDocumentContext(uri, codeDocument); @@ -153,8 +150,7 @@ public async Task Handle_OnTypeFormatting_RazorLanguageKind_ReturnsNull() @{ if(true){} }"; - var sourceMappings = new List { new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0)) }; - var codeDocument = CreateCodeDocument(content, sourceMappings); + var codeDocument = CreateCodeDocument(content, sourceMappings: [new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0))]); var uri = new Uri("file://path/test.razor"); var documentContext = CreateDocumentContext(uri, codeDocument); @@ -189,8 +185,7 @@ public async Task Handle_OnTypeFormatting_UnexpectedTriggerCharacter_ReturnsNull @{ if(true){} }"; - var sourceMappings = new List { new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0)) }; - var codeDocument = CreateCodeDocument(content, sourceMappings); + var codeDocument = CreateCodeDocument(content, [new SourceMapping(new SourceSpan(17, 0), new SourceSpan(17, 0))]); var uri = new Uri("file://path/test.razor"); var documentContextFactory = CreateDocumentContextFactory(uri, codeDocument); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/FormattingLanguageServerTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/FormattingLanguageServerTestBase.cs index 25a4ba44e63..4403c977fbb 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/FormattingLanguageServerTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting_NetFx/FormattingLanguageServerTestBase.cs @@ -1,13 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.AspNetCore.Razor.Threading; using Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -20,13 +17,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting; public abstract class FormattingLanguageServerTestBase(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput) { - internal static RazorCodeDocument CreateCodeDocument(string content, IReadOnlyList sourceMappings) + internal static RazorCodeDocument CreateCodeDocument(string content, ImmutableArray sourceMappings) { var sourceDocument = TestRazorSourceDocument.Create(content); var codeDocument = RazorCodeDocument.Create(sourceDocument); var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.CreateDefault()); - var razorCSharpDocument = RazorCSharpDocument.Create( - codeDocument, content, RazorCodeGenerationOptions.CreateDefault(), Array.Empty(), sourceMappings.ToImmutableArray(), Array.Empty()); + var razorCSharpDocument = new RazorCSharpDocument( + codeDocument, content, RazorCodeGenerationOptions.Default, diagnostics: [], sourceMappings, linePragmas: []); codeDocument.SetSyntaxTree(syntaxTree); codeDocument.SetCSharpDocument(razorCSharpDocument); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorLanguageQueryEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorLanguageQueryEndpointTest.cs index 4d52de66276..0a68fcf4892 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorLanguageQueryEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorLanguageQueryEndpointTest.cs @@ -2,12 +2,9 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; @@ -90,9 +87,9 @@ public async Task Handle_ResolvesLanguageRequest_CSharp() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "@", - "/* CSharp */", - new[] { new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 12)) }); + razorSource: "@", + projectedCSharpSource: "/* CSharp */", + sourceMappings: [new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 12))]); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorLanguageQueryEndpoint(_documentMappingService, LoggerFactory); var request = new RazorLanguageQueryParams() @@ -120,9 +117,9 @@ public async Task Handle_Unsupported_ResolvesLanguageRequest_Html() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "@", - "/* CSharp */", - new[] { new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 12)) }); + razorSource: "@", + projectedCSharpSource: "/* CSharp */", + sourceMappings: [new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 12))]); codeDocument.SetUnsupported(); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorLanguageQueryEndpoint(_documentMappingService, LoggerFactory); @@ -145,16 +142,16 @@ public async Task Handle_Unsupported_ResolvesLanguageRequest_Html() Assert.Equal(1337, response.HostDocumentVersion); } - private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, IEnumerable sourceMappings) + private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, ImmutableArray sourceMappings) { - var codeDocument = CreateCodeDocument(razorSource, ImmutableArray.Empty); - var csharpDocument = RazorCSharpDocument.Create( + var codeDocument = CreateCodeDocument(razorSource, tagHelpers: []); + var csharpDocument = new RazorCSharpDocument( codeDocument, projectedCSharpSource, - RazorCodeGenerationOptions.CreateDefault(), - Enumerable.Empty(), - sourceMappings.ToImmutableArray(), - Enumerable.Empty()); + RazorCodeGenerationOptions.Default, + diagnostics: [], + sourceMappings, + linePragmas: []); codeDocument.SetCSharpDocument(csharpDocument); return codeDocument; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorMapToDocumentRangesEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorMapToDocumentRangesEndpointTest.cs index 271ebda9975..ef39684a793 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorMapToDocumentRangesEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Mapping/RazorMapToDocumentRangesEndpointTest.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; @@ -36,13 +35,9 @@ public async Task Handle_MapToDocumentRanges_CSharp() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "var __o = DateTime.Now", - [ - new SourceMapping( - new SourceSpan(4, 12), - new SourceSpan(10, 12)) - ]); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "var __o = DateTime.Now", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(10, 12))]); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorMapToDocumentRangesEndpoint(_documentMappingService); var request = new RazorMapToDocumentRangesParams() @@ -70,13 +65,9 @@ public async Task Handle_MapToDocumentRanges_CSharp_Unmapped() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "var __o = DateTime.Now", - [ - new SourceMapping( - new SourceSpan(4, 12), - new SourceSpan(10, 12)) - ]); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "var __o = DateTime.Now", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(10, 12))]); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorMapToDocumentRangesEndpoint(_documentMappingService); var request = new RazorMapToDocumentRangesParams() @@ -103,13 +94,9 @@ public async Task Handle_MapToDocumentRanges_CSharp_LeadingOverlapsUnmapped() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "var __o = DateTime.Now", - [ - new SourceMapping( - new SourceSpan(4, 12), - new SourceSpan(10, 12)) - ]); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "var __o = DateTime.Now", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(10, 12))]); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorMapToDocumentRangesEndpoint(_documentMappingService); var request = new RazorMapToDocumentRangesParams() @@ -136,13 +123,9 @@ public async Task Handle_MapToDocumentRanges_CSharp_TrailingOverlapsUnmapped() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "var __o = DateTime.Now", - [ - new SourceMapping( - new SourceSpan(4, 12), - new SourceSpan(10, 12)) - ]); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "var __o = DateTime.Now", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(10, 12))]); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorMapToDocumentRangesEndpoint(_documentMappingService); var request = new RazorMapToDocumentRangesParams() @@ -221,13 +204,9 @@ public async Task Handle_MapToDocumentRanges_Unsupported() // Arrange var documentPath = new Uri("C:/path/to/document.cshtml"); var codeDocument = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "var __o = DateTime.Now", - [ - new SourceMapping( - new SourceSpan(4, 12), - new SourceSpan(10, 12)) - ]); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "var __o = DateTime.Now", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(10, 12))]); codeDocument.SetUnsupported(); var documentContext = CreateDocumentContext(documentPath, codeDocument); var languageEndpoint = new RazorMapToDocumentRangesEndpoint(_documentMappingService); @@ -249,15 +228,15 @@ public async Task Handle_MapToDocumentRanges_Unsupported() Assert.Equal(1337, response.HostDocumentVersion); } - private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, IEnumerable sourceMappings) + private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, ImmutableArray sourceMappings) { var codeDocument = CreateCodeDocument(razorSource, tagHelpers: []); - var csharpDocument = RazorCSharpDocument.Create( + var csharpDocument = new RazorCSharpDocument( codeDocument, projectedCSharpSource, - RazorCodeGenerationOptions.CreateDefault(), + RazorCodeGenerationOptions.Default, diagnostics: [], - sourceMappings.ToImmutableArray(), + sourceMappings, linePragmas: []); codeDocument.SetCSharpDocument(csharpDocument); return codeDocument; diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorDocumentMappingServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorDocumentMappingServiceTest.cs index 8bd5c180295..041d32417a2 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorDocumentMappingServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/RazorDocumentMappingServiceTest.cs @@ -4,9 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer; @@ -21,15 +19,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer; -public class RazorDocumentMappingServiceTest : ToolingTestBase +public class RazorDocumentMappingServiceTest(ITestOutputHelper testOutput) : ToolingTestBase(testOutput) { - private readonly IFilePathService _filePathService; - - public RazorDocumentMappingServiceTest(ITestOutputHelper testOutput) - : base(testOutput) - { - _filePathService = new LSPFilePathService(TestLanguageServerFeatureOptions.Instance); - } + private readonly IFilePathService _filePathService = new LSPFilePathService(TestLanguageServerFeatureOptions.Instance); [Fact] public void TryMapToHostDocumentRange_Strict_StartOnlyMaps_ReturnsFalse() @@ -37,9 +29,9 @@ public void TryMapToHostDocumentRange_Strict_StartOnlyMaps_ReturnsFalse() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 10), new LinePosition(0, 19)); // Act @@ -60,9 +52,9 @@ public void TryMapToHostDocumentRange_Strict_EndOnlyMaps_ReturnsFalse() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 12)); // Act @@ -83,9 +75,9 @@ public void TryMapToHostDocumentRange_Strict_StartAndEndMap_ReturnsTrue() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 6), new LinePosition(0, 18)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -107,9 +99,9 @@ public void TryMapToHostDocumentRange_Inclusive_DirectlyMaps_ReturnsTrue() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 6), new LinePosition(0, 18)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -131,9 +123,9 @@ public void TryMapToHostDocumentRange_Inclusive_StartSinglyIntersects_ReturnsTru // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 10), new LinePosition(0, 19)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -155,9 +147,9 @@ public void TryMapToHostDocumentRange_Inclusive_EndSinglyIntersects_ReturnsTrue( // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 10)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -179,13 +171,12 @@ public void TryMapToHostDocumentRange_Inclusive_StartDoublyIntersects_ReturnsFal // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] - { + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [ new SourceMapping(new SourceSpan(4, 8), new SourceSpan(6, 8)), // DateTime new SourceMapping(new SourceSpan(12, 4), new SourceSpan(14, 4)) // .Now - }); + ]); var projectedRange = new LinePositionSpan(new LinePosition(0, 14), new LinePosition(0, 19)); // Act @@ -206,13 +197,12 @@ public void TryMapToHostDocumentRange_Inclusive_EndDoublyIntersects_ReturnsFalse // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] - { + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [ new SourceMapping(new SourceSpan(4, 8), new SourceSpan(6, 8)), // DateTime new SourceMapping(new SourceSpan(12, 4), new SourceSpan(14, 4)) // .Now - }); + ]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 14)); // Act @@ -233,9 +223,9 @@ public void TryMapToHostDocumentRange_Inclusive_OverlapsSingleMapping_ReturnsTru // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 19)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -257,13 +247,12 @@ public void TryMapToHostDocumentRange_Inclusive_OverlapsTwoMappings_ReturnsFalse // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] - { + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [ new SourceMapping(new SourceSpan(4, 8), new SourceSpan(6, 8)), // DateTime new SourceMapping(new SourceSpan(12, 4), new SourceSpan(14, 4)) // .Now - }); + ]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 19)); // Act @@ -284,9 +273,9 @@ public void TryMapToHostDocumentRange_Inferred_DirectlyMaps_ReturnsTrue() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "

@DateTime.Now

", - "__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12)) }); + razorSource: "

@DateTime.Now

", + projectedCSharpSource: "__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(4, 12), new SourceSpan(6, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 6), new LinePosition(0, 18)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 4), new LinePosition(0, 16)); @@ -308,9 +297,9 @@ public void TryMapToHostDocumentRange_Inferred_BeginningOfDocAndProjection_Retur // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "@

@DateTime.Now

", - "(__builder) => { };__o = DateTime.Now;", - new[] { new SourceMapping(new SourceSpan(26, 12), new SourceSpan(25, 12)) }); + razorSource: "@

@DateTime.Now

", + projectedCSharpSource: "(__builder) => { };__o = DateTime.Now;", + sourceMappings: [new SourceMapping(new SourceSpan(26, 12), new SourceSpan(25, 12))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 19)); // Act @@ -326,17 +315,17 @@ public void TryMapToHostDocumentRange_Inferred_BeginningOfDocAndProjection_Retur } [Fact] - public void TryMapToHostDocumentRange_Inferred_InbetweenProjections_ReturnsTrue() + public void TryMapToHostDocumentRange_Inferred_InBetweenProjections_ReturnsTrue() { // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "@{ var abc = @ }", - " var abc = (__builder) => { } ", - new[] { + razorSource: "@{ var abc = @ }", + projectedCSharpSource: " var abc = (__builder) => { } ", + sourceMappings: [ new SourceMapping(new SourceSpan(2, 11), new SourceSpan(0, 11)), - new SourceMapping(new SourceSpan(35, 1), new SourceSpan(30, 1)), - }); + new SourceMapping(new SourceSpan(35, 1), new SourceSpan(30, 1)) + ]); var projectedRange = new LinePositionSpan(new LinePosition(0, 12), new LinePosition(0, 29)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 13), new LinePosition(0, 35)); @@ -353,14 +342,14 @@ public void TryMapToHostDocumentRange_Inferred_InbetweenProjections_ReturnsTrue( } [Fact] - public void TryMapToHostDocumentRange_Inferred_InbetweenProjectionAndEndOfDoc_ReturnsTrue() + public void TryMapToHostDocumentRange_Inferred_InBetweenProjectionAndEndOfDoc_ReturnsTrue() { // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "@{ var abc = @", - " var abc = (__builder) => { }", - new[] { new SourceMapping(new SourceSpan(2, 11), new SourceSpan(0, 11)), }); + razorSource: "@{ var abc = @", + projectedCSharpSource: " var abc = (__builder) => { }", + sourceMappings: [new SourceMapping(new SourceSpan(2, 11), new SourceSpan(0, 11))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 12), new LinePosition(0, 29)); var expectedOriginalRange = new LinePositionSpan(new LinePosition(0, 13), new LinePosition(0, 35)); @@ -382,9 +371,9 @@ public void TryMapToHostDocumentRange_Inferred_OutsideDoc_ReturnsFalse() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "@{ var abc = @", - " var abc = (__builder) => { }", - new[] { new SourceMapping(new SourceSpan(2, 11), new SourceSpan(0, 11)), }); + razorSource: "@{ var abc = @", + projectedCSharpSource: " var abc = (__builder) => { }", + sourceMappings: [new SourceMapping(new SourceSpan(2, 11), new SourceSpan(0, 11))]); var projectedRange = new LinePositionSpan(new LinePosition(2, 12), new LinePosition(2, 29)); // Act @@ -392,14 +381,14 @@ public void TryMapToHostDocumentRange_Inferred_OutsideDoc_ReturnsFalse() codeDoc.GetCSharpDocument(), projectedRange, MappingBehavior.Inferred, - out var originalRange); + out _); // Assert Assert.False(result); } [Fact] - public void TryMapToHostDocumentRange_Inferred_OutOfOrderMappings_DoesntThrow() + public void TryMapToHostDocumentRange_Inferred_OutOfOrderMappings_DoesNotThrow() { // Real world repo is something like: // @@ -418,9 +407,9 @@ public void TryMapToHostDocumentRange_Inferred_OutOfOrderMappings_DoesntThrow() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "@{ var abc = @", - " var abc = (__builder) => { }", - new SourceMapping[] { new(new(30, 1), new (2, 1)), new(new(28, 2), new(30, 2)), }); + razorSource: "@{ var abc = @", + projectedCSharpSource: " var abc = (__builder) => { }", + sourceMappings: [new(new(30, 1), new(2, 1)), new(new(28, 2), new(30, 2))]); var projectedRange = new LinePositionSpan(new LinePosition(0, 25), new LinePosition(0, 25)); // Act @@ -431,7 +420,7 @@ public void TryMapToHostDocumentRange_Inferred_OutOfOrderMappings_DoesntThrow() out var originalRange); // Assert - // We're really just happy this doesn't throw an exception. The behaviour is to map to the end of the file + // We're really just happy this doesn't throw an exception. The behavior is to map to the end of the file Assert.True(result); Assert.Equal(0, originalRange.Start.Line); Assert.Equal(31, originalRange.Start.Character); @@ -445,21 +434,19 @@ public void TryMapToGeneratedDocumentPosition_NotMatchingAnyMapping() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "test razor source", - "test C# source", - new[] { new SourceMapping(new SourceSpan(2, 100), new SourceSpan(0, 100)) }); + razorSource: "test razor source", + projectedCSharpSource: "test C# source", + sourceMappings: [new SourceMapping(new SourceSpan(2, 100), new SourceSpan(0, 100))]); // Act var result = service.TryMapToGeneratedDocumentPosition( codeDoc.GetCSharpDocument(), - 1, - out var projectedPosition, - out var projectedPositionIndex); + hostDocumentIndex: 1, + out _, + out _); // Assert Assert.False(result); - Assert.Equal(default, projectedPosition); - Assert.Equal(default, projectedPositionIndex); } [Fact] @@ -468,28 +455,24 @@ public void TryMapToGeneratedDocumentPosition_CSharp_OnLeadingEdge() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "Line 1\nLine 2 @{ var abc;\nvar def; }", - "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", + projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act - if (service.TryMapToGeneratedDocumentPosition( + var result = service.TryMapToGeneratedDocumentPosition( codeDoc.GetCSharpDocument(), - 16, + hostDocumentIndex: 16, out var projectedPosition, - out var projectedPositionIndex)) - { - Assert.Equal(2, projectedPosition.Line); - Assert.Equal(0, projectedPosition.Character); - Assert.Equal(11, projectedPositionIndex); - } - else - { - Assert.Fail($"{nameof(service.TryMapToGeneratedDocumentPosition)} should have returned true"); - } + out var projectedPositionIndex); + + Assert.True(result); + Assert.Equal(2, projectedPosition.Line); + Assert.Equal(0, projectedPosition.Character); + Assert.Equal(11, projectedPositionIndex); } [Fact] @@ -498,28 +481,24 @@ public void TryMapToGeneratedDocumentPosition_CSharp_InMiddle() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "Line 1\nLine 2 @{ var abc;\nvar def; }", - "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", + projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act & Assert - if (service.TryMapToGeneratedDocumentPosition( + var result = service.TryMapToGeneratedDocumentPosition( codeDoc.GetCSharpDocument(), - 28, + hostDocumentIndex: 28, out var projectedPosition, - out var projectedPositionIndex)) - { - Assert.Equal(3, projectedPosition.Line); - Assert.Equal(2, projectedPosition.Character); - Assert.Equal(23, projectedPositionIndex); - } - else - { - Assert.Fail("TryMapToGeneratedDocumentPosition should have been true"); - } + out var projectedPositionIndex); + + Assert.True(result); + Assert.Equal(3, projectedPosition.Line); + Assert.Equal(2, projectedPosition.Character); + Assert.Equal(23, projectedPositionIndex); } [Fact] @@ -528,28 +507,24 @@ public void TryMapToGeneratedDocumentPosition_CSharp_OnTrailingEdge() // Arrange var service = new LspDocumentMappingService(_filePathService, new TestDocumentContextFactory(), LoggerFactory); var codeDoc = CreateCodeDocumentWithCSharpProjection( - "Line 1\nLine 2 @{ var abc;\nvar def; }", - "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", + projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act & Assert - if (service.TryMapToGeneratedDocumentPosition( + var result = service.TryMapToGeneratedDocumentPosition( codeDoc.GetCSharpDocument(), - 35, + hostDocumentIndex: 35, out var projectedPosition, - out var projectedPositionIndex)) - { - Assert.Equal(3, projectedPosition.Line); - Assert.Equal(9, projectedPosition.Character); - Assert.Equal(30, projectedPositionIndex); - } - else - { - Assert.Fail("TryMapToGeneratedDocumentPosition should have returned true"); - } + out var projectedPositionIndex); + + Assert.True(result); + Assert.Equal(3, projectedPosition.Line); + Assert.Equal(9, projectedPosition.Character); + Assert.Equal(30, projectedPositionIndex); } [Fact] @@ -560,19 +535,17 @@ public void TryMapToHostDocumentPosition_NotMatchingAnyMapping() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "test razor source", projectedCSharpSource: "projectedCSharpSource: test C# source", - new[] { new SourceMapping(new SourceSpan(2, 100), new SourceSpan(2, 100)) }); + sourceMappings: [new SourceMapping(new SourceSpan(2, 100), new SourceSpan(2, 100))]); // Act var result = service.TryMapToHostDocumentPosition( codeDoc.GetCSharpDocument(), - 1, - out var hostDocumentPosition, - out var hostDocumentIndex); + generatedDocumentIndex: 1, + out _, + out _); // Assert Assert.False(result); - Assert.Equal(default, hostDocumentPosition); - Assert.Equal(default, hostDocumentIndex); } [Fact] @@ -583,26 +556,22 @@ public void TryMapToHostDocumentPosition_CSharp_OnLeadingEdge() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act & Assert - if (service.TryMapToHostDocumentPosition( + var result = service.TryMapToHostDocumentPosition( codeDoc.GetCSharpDocument(), - 11, // @{| + generatedDocumentIndex: 11, // @{| out var hostDocumentPosition, - out var hostDocumentIndex)) - { - Assert.Equal(1, hostDocumentPosition.Line); - Assert.Equal(9, hostDocumentPosition.Character); - Assert.Equal(16, hostDocumentIndex); - } - else - { - Assert.Fail($"{nameof(service.TryMapToHostDocumentPosition)} should have returned true"); - } + out var hostDocumentIndex); + + Assert.True(result); + Assert.Equal(1, hostDocumentPosition.Line); + Assert.Equal(9, hostDocumentPosition.Character); + Assert.Equal(16, hostDocumentIndex); } [Fact] @@ -613,26 +582,22 @@ public void TryMapToHostDocumentPosition_CSharp_InMiddle() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act & Assert - if (service.TryMapToHostDocumentPosition( + var result = service.TryMapToHostDocumentPosition( codeDoc.GetCSharpDocument(), - 21, // |var def + generatedDocumentIndex: 21, // |var def out var hostDocumentPosition, - out var hostDocumentIndex)) - { - Assert.Equal(2, hostDocumentPosition.Line); - Assert.Equal(0, hostDocumentPosition.Character); - Assert.Equal(26, hostDocumentIndex); - } - else - { - Assert.Fail($"{nameof(service.TryMapToHostDocumentPosition)} should have returned true"); - } + out var hostDocumentIndex); + + Assert.True(result); + Assert.Equal(2, hostDocumentPosition.Line); + Assert.Equal(0, hostDocumentPosition.Character); + Assert.Equal(26, hostDocumentIndex); } [Fact] @@ -643,26 +608,22 @@ public void TryMapToHostDocumentPosition_CSharp_OnTrailingEdge() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); // Act & Assert - if (service.TryMapToHostDocumentPosition( + var result = service.TryMapToHostDocumentPosition( codeDoc.GetCSharpDocument(), - 30, // def; |} + generatedDocumentIndex: 30, // def; |} out var hostDocumentPosition, - out var hostDocumentIndex)) - { - Assert.Equal(2, hostDocumentPosition.Line); - Assert.Equal(9, hostDocumentPosition.Character); - Assert.Equal(35, hostDocumentIndex); - } - else - { - Assert.Fail($"{nameof(service.TryMapToHostDocumentPosition)} should have returned true"); - } + out var hostDocumentIndex); + + Assert.True(result); + Assert.Equal(2, hostDocumentPosition.Line); + Assert.Equal(9, hostDocumentPosition.Character); + Assert.Equal(35, hostDocumentIndex); } [Fact] @@ -673,27 +634,23 @@ public void TryMapToGeneratedDocumentRange_CSharp() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 19), new SourceSpan(11, 19)) - }); + ]); var range = new LinePositionSpan(new LinePosition(1, 10), new LinePosition(1, 13)); // Act & Assert - if (service.TryMapToGeneratedDocumentRange( + var result = service.TryMapToGeneratedDocumentRange( codeDoc.GetCSharpDocument(), range, // |var| abc - out var projectedRange)) - { - Assert.Equal(2, projectedRange.Start.Line); - Assert.Equal(1, projectedRange.Start.Character); - Assert.Equal(2, projectedRange.End.Line); - Assert.Equal(4, projectedRange.End.Character); - } - else - { - Assert.Fail($"{nameof(service.TryMapToGeneratedDocumentRange)} should have returned true"); - } + out var projectedRange); + + Assert.True(result); + Assert.Equal(2, projectedRange.Start.Line); + Assert.Equal(1, projectedRange.Start.Character); + Assert.Equal(2, projectedRange.End.Line); + Assert.Equal(4, projectedRange.End.Character); } [Fact] @@ -704,20 +661,17 @@ public void TryMapToGeneratedDocumentRange_CSharp_MissingSourceMappings() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { - new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), - }); + sourceMappings: [new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1))]); var range = new LinePositionSpan(new LinePosition(1, 10), new LinePosition(1, 13)); // Act var result = service.TryMapToGeneratedDocumentRange( codeDoc.GetCSharpDocument(), range, // |var| abc - out var projectedRange); + out _); // Assert Assert.False(result); - Assert.Equal(default, projectedRange); } [Fact] @@ -728,22 +682,21 @@ public void TryMapToGeneratedDocumentRange_CSharp_End_LessThan_Start() var codeDoc = CreateCodeDocumentWithCSharpProjection( razorSource: "Line 1\nLine 2 @{ var abc;\nvar def; }", projectedCSharpSource: "\n// Prefix\n var abc;\nvar def; \n// Suffix", - new[] { + sourceMappings: [ new SourceMapping(new SourceSpan(0, 1), new SourceSpan(0, 1)), new SourceMapping(new SourceSpan(16, 3), new SourceSpan(11, 3)), new SourceMapping(new SourceSpan(19, 10), new SourceSpan(5, 10)) - }); + ]); var range = new LinePositionSpan(new LinePosition(1, 10), new LinePosition(1, 13)); // Act var result = service.TryMapToGeneratedDocumentRange( codeDoc.GetCSharpDocument(), range, // |var| abc - out var projectedRange); + out _); // Assert Assert.False(result); - Assert.Equal(default, projectedRange); } [Fact] @@ -1076,16 +1029,16 @@ private static RazorCodeDocument CreateCodeDocument(string text, IReadOnlyList sourceMappings) + private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, ImmutableArray sourceMappings) { - var codeDocument = CreateCodeDocument(razorSource, Array.Empty()); - var csharpDocument = RazorCSharpDocument.Create( + var codeDocument = CreateCodeDocument(razorSource, tagHelpers: []); + var csharpDocument = new RazorCSharpDocument( codeDocument, projectedCSharpSource, - RazorCodeGenerationOptions.CreateDefault(), - Enumerable.Empty(), - sourceMappings.ToImmutableArray(), - Enumerable.Empty()); + RazorCodeGenerationOptions.Default, + diagnostics: [], + sourceMappings, + linePragmas: []); codeDocument.SetCSharpDocument(csharpDocument); return codeDocument; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Language/IntegrationTests/RazorToolingIntegrationTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Language/IntegrationTests/RazorToolingIntegrationTestBase.cs index d473acb5ccc..8d4d088e7d9 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Language/IntegrationTests/RazorToolingIntegrationTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Language/IntegrationTests/RazorToolingIntegrationTestBase.cs @@ -10,7 +10,6 @@ using System.Reflection; using System.Runtime.InteropServices; using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common.Mef; @@ -117,7 +116,7 @@ private RazorProjectEngine CreateProjectEngine(RazorConfiguration configuration, if (LineEnding != null) { - b.Phases.Insert(0, new ForceLineEndingPhase(LineEnding)); + b.Features.Add(new SetNewLineOptionFeature(LineEnding)); } b.Features.Add(new DefaultTypeNameFeature()); @@ -430,20 +429,13 @@ public void Configure(RazorCodeGenerationOptionsBuilder options) } } - private class ForceLineEndingPhase : RazorEnginePhaseBase + private sealed class SetNewLineOptionFeature(string newLine) : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature { - public ForceLineEndingPhase(string lineEnding) - { - LineEnding = lineEnding; - } + public int Order { get; } - public string LineEnding { get; } - - protected override void ExecuteCore(RazorCodeDocument codeDocument) + public void Configure(RazorCodeGenerationOptionsBuilder options) { - var field = typeof(CodeRenderingContext).GetField("NewLineString", BindingFlags.Static | BindingFlags.NonPublic); - var key = field.GetValue(null); - codeDocument.Items[key] = LineEnding; + options.NewLine = newLine; } } diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/CodeGeneration/TestCodeRenderingContext.cs b/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/CodeGeneration/TestCodeRenderingContext.cs index e4f695cc133..b884acf51ef 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/CodeGeneration/TestCodeRenderingContext.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/CodeGeneration/TestCodeRenderingContext.cs @@ -15,32 +15,14 @@ public static CodeRenderingContext CreateDesignTime( RazorSourceDocument source = null, IntermediateNodeWriter nodeWriter = null) { + nodeWriter ??= new RuntimeNodeWriter(); + source ??= TestRazorSourceDocument.Create(); var documentNode = new DocumentIntermediateNode(); - var options = RazorCodeGenerationOptions.CreateDesignTimeDefault(); - if (source == null) - { - source = TestRazorSourceDocument.Create(); - } - - var codeDocument = RazorCodeDocument.Create(source); - if (newLineString != null) - { - codeDocument.Items[CodeRenderingContext.NewLineString] = newLineString; - } - - if (suppressUniqueIds != null) - { - codeDocument.Items[CodeRenderingContext.SuppressUniqueIds] = suppressUniqueIds; - } - - if (nodeWriter == null) - { - nodeWriter = new DesignTimeNodeWriter(); - } + var options = ConfigureOptions(RazorCodeGenerationOptions.DesignTimeDefault, newLineString, suppressUniqueIds); - var context = new DefaultCodeRenderingContext(nodeWriter, codeDocument, documentNode, options); - context.Visitor = new RenderChildrenVisitor(context); + var context = new CodeRenderingContext(nodeWriter, source, documentNode, options); + context.SetVisitor(new RenderChildrenVisitor(context.CodeWriter)); return context; } @@ -51,47 +33,45 @@ public static CodeRenderingContext CreateRuntime( RazorSourceDocument source = null, IntermediateNodeWriter nodeWriter = null) { + nodeWriter ??= new RuntimeNodeWriter(); + source ??= TestRazorSourceDocument.Create(); var documentNode = new DocumentIntermediateNode(); - var options = RazorCodeGenerationOptions.CreateDefault(); - if (source == null) - { - source = TestRazorSourceDocument.Create(); - } + var options = ConfigureOptions(RazorCodeGenerationOptions.Default, newLineString, suppressUniqueIds); + + var context = new CodeRenderingContext(nodeWriter, source, documentNode, options); + context.SetVisitor(new RenderChildrenVisitor(context.CodeWriter)); + + return context; + } - var codeDocument = RazorCodeDocument.Create(source); - if (newLineString != null) + private static RazorCodeGenerationOptions ConfigureOptions(RazorCodeGenerationOptions options, string newLine, string suppressUniqueIds) + { + if (newLine is null && suppressUniqueIds is null) { - codeDocument.Items[CodeRenderingContext.NewLineString] = newLineString; + return options; } - if (suppressUniqueIds != null) + var builder = options.ToBuilder(); + + if (newLine is not null) { - codeDocument.Items[CodeRenderingContext.SuppressUniqueIds] = suppressUniqueIds; + builder.NewLine = newLine; } - if (nodeWriter == null) + if (suppressUniqueIds is not null) { - nodeWriter = new RuntimeNodeWriter(); + builder.SuppressUniqueIds = suppressUniqueIds; } - var context = new DefaultCodeRenderingContext(nodeWriter, codeDocument, documentNode, options); - context.Visitor = new RenderChildrenVisitor(context); - - return context; + return builder.Build(); } - private class RenderChildrenVisitor : IntermediateNodeVisitor + private class RenderChildrenVisitor(CodeWriter writer) : IntermediateNodeVisitor { - private readonly CodeRenderingContext _context; - public RenderChildrenVisitor(CodeRenderingContext context) - { - _context = context; - } - public override void VisitDefault(IntermediateNode node) { - _context.CodeWriter.WriteLine("Render Children"); + writer.WriteLine("Render Children"); } } } diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntegrationTestBase.cs b/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntegrationTestBase.cs index ae9ba577a3b..9ec2db725da 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntegrationTestBase.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/IntegrationTestBase.cs @@ -10,7 +10,6 @@ using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Language.Intermediate; using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.AspNetCore.Razor.Language.Syntax; @@ -299,7 +298,7 @@ private RazorProjectEngine CreateProjectEngine(RazorConfiguration configuration, { return RazorProjectEngine.Create(configuration, FileSystem, b => { - b.Phases.Insert(0, new ConfigureCodeRenderingPhase(LineEnding)); + b.Features.Add(new ConfigureCodeGenerationOptionsFeature(LineEnding)); b.RegisterExtensions(); @@ -782,19 +781,14 @@ private static string NormalizeNewLines(string content, string lineEnding) return Regex.Replace(content, "(?(ref this T value, T flag) + where T : unmanaged, Enum + { + var v = (T*)Unsafe.AsPointer(ref value); + + if (sizeof(T) == sizeof(byte)) + { + *(byte*)v |= *(byte*)&flag; + return; + } + else if (sizeof(T) == sizeof(ushort)) + { + *(ushort*)v |= *(ushort*)&flag; + return; + } + else if (sizeof(T) == sizeof(uint)) + { + *(uint*)v |= *(uint*)&flag; + return; + } + else if (sizeof(T) == sizeof(ulong)) + { + *(ulong*)v |= *(ulong*)&flag; + return; + } + + Debug.Fail("Unexpected enum underlying type."); + } + + // Note: This is written to allow the JIT to inline only the correct branch depending on the size of T. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void ClearFlag(ref this T value, T flag) + where T : unmanaged, Enum + { + var v = (T*)Unsafe.AsPointer(ref value); + + if (sizeof(T) == sizeof(byte)) + { + *(byte*)v &= (byte)~*(byte*)&flag; + return; + } + else if (sizeof(T) == sizeof(ushort)) + { + *(ushort*)v &= (ushort)~*(ushort*)&flag; + return; + } + else if (sizeof(T) == sizeof(uint)) + { + *(uint*)v &= ~*(uint*)&flag; + return; + } + else if (sizeof(T) == sizeof(ulong)) + { + *(ulong*)v &= ~*(ulong*)&flag; + return; + } + + Debug.Fail("Unexpected enum underlying type."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void UpdateFlag(ref this T value, T flag, bool set) + where T : unmanaged, Enum + { + if (set) + { + value.SetFlag(flag); + } + else + { + value.ClearFlag(flag); + } + } + + // Note: This is written to allow the JIT to inline only the correct branch depending on the size of T. + // This is somewhat faster than Enum.HasFlag(...) when running on .NET Framework. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsFlagSet(this T value, T flags) + where T : unmanaged, Enum + { + if (sizeof(T) == sizeof(byte)) + { + var f = *(byte*)&flags; + return (*(byte*)&value & f) == f; + } + else if (sizeof(T) == sizeof(ushort)) + { + var f = *(ushort*)&flags; + return (*(ushort*)&value & f) == f; + } + else if (sizeof(T) == sizeof(uint)) + { + var f = *(uint*)&flags; + return (*(uint*)&value & f) == f; + } + else if (sizeof(T) == sizeof(ulong)) + { + var f = *(ulong*)&flags; + return (*(ulong*)&value & f) == f; + } + + Debug.Fail("Unexpected enum underlying type."); + return false; + } + + // Note: This is written to allow the JIT to inline only the correct branch depending on the size of T. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsFlagClear(this T value, T flags) + where T : unmanaged, Enum + { + if (sizeof(T) == sizeof(byte)) + { + var f = *(byte*)&flags; + return (*(byte*)&value & f) == 0; + } + else if (sizeof(T) == sizeof(ushort)) + { + var f = *(ushort*)&flags; + return (*(ushort*)&value & f) == 0; + } + else if (sizeof(T) == sizeof(uint)) + { + var f = *(uint*)&flags; + return (*(uint*)&value & f) == 0; + } + else if (sizeof(T) == sizeof(ulong)) + { + var f = *(ulong*)&flags; + return (*(ulong*)&value & f) == 0; + } + + Debug.Fail("Unexpected enum underlying type."); + return false; + } +} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledHashSet`1.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledHashSet`1.cs index c5ac61e1248..ff006967ea4 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledHashSet`1.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledHashSet`1.cs @@ -67,10 +67,13 @@ public readonly bool Contains(T item) => _set?.Contains(item) ?? false; public readonly T[] ToArray() - => _set?.ToArray() ?? Array.Empty(); + => _set?.ToArray() ?? []; public readonly ImmutableArray ToImmutableArray() - => _set?.ToImmutableArray() ?? ImmutableArray.Empty; + => _set?.ToImmutableArray() ?? []; + + public readonly ImmutableArray OrderByAsArray(Func keySelector) + => _set?.OrderByAsArray(keySelector) ?? []; public void UnionWith(IList? other) {