From 5d9bc16c7030c122aea29e357d8da0fce8b436e9 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Mon, 18 Dec 2023 15:02:29 +0100 Subject: [PATCH 1/4] Allow complex content in component parameters --- .../ComponentComplexAttributeContentPass.cs | 5 --- .../ComponentDesignTimeNodeWriter.cs | 11 ------- .../Components/ComponentRuntimeNodeWriter.cs | 25 +++------------ .../RazorSourceGeneratorComponentTests.cs | 32 +++++++++++++++++++ .../Views_Home_Index.html | 1 + 5 files changed, 38 insertions(+), 36 deletions(-) create mode 100644 src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/TestFiles/RazorSourceGeneratorComponentTests/MixedContent_StringParameter/Views_Home_Index.html diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentComplexAttributeContentPass.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentComplexAttributeContentPass.cs index 2f0cad8f2b5..a17bbe407ef 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentComplexAttributeContentPass.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentComplexAttributeContentPass.cs @@ -85,11 +85,6 @@ private static void ProcessAttribute(IntermediateNode parent, IntermediateNode n // We don't support this. issueDiagnostic = true; } - else if (node.Children.Count > 1) - { - // This is the common case for 'mixed' content - issueDiagnostic = true; - } if (issueDiagnostic) { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs index ff951d615a6..11e00480166 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs @@ -758,12 +758,6 @@ private void WritePropertyAccess(CodeRenderingContext context, ComponentAttribut private void WriteComponentAttributeInnards(CodeRenderingContext context, ComponentAttributeIntermediateNode node, bool canTypeCheck) { - if (node.Children.Count > 1) - { - Debug.Assert(node.HasDiagnostics, "We should have reported an error for mixed content."); - // We render the children anyway, so tooling works. - } - // We limit component attributes to simple cases. However there is still a lot of complexity // to handle here, since there are a few different cases for how an attribute might be structured. // @@ -1131,11 +1125,6 @@ private void WriteSplatInnards(CodeRenderingContext context, SplatIntermediateNo public sealed override void WriteFormName(CodeRenderingContext context, FormNameIntermediateNode node) { - if (node.Children.Count > 1) - { - Debug.Assert(node.HasDiagnostics, "We should have reported an error for mixed content."); - } - foreach (var token in node.FindDescendantNodes()) { if (token.IsCSharp) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs index 84efec4faae..4d7a066a8b2 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs @@ -630,12 +630,6 @@ public override void WriteComponentAttribute(CodeRenderingContext context, Compo private void WriteComponentAttributeInnards(CodeRenderingContext context, ComponentAttributeIntermediateNode node, bool canTypeCheck) { - if (node.Children.Count > 1) - { - Debug.Assert(node.HasDiagnostics, "We should have reported an error for mixed content."); - // We render the children anyway, so tooling works. - } - if (node.AttributeStructure == AttributeStructure.Minimized) { // Minimized attributes always map to 'true' @@ -650,7 +644,6 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon else { // See comments in ComponentDesignTimeNodeWriter for a description of the cases that are possible. - var tokens = GetCSharpTokens(node); if ((node.BoundAttribute?.IsDelegateProperty() ?? false) || (node.BoundAttribute?.IsChildContentProperty() ?? false)) { @@ -662,9 +655,9 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.Write("("); } - for (var i = 0; i < tokens.Count; i++) + foreach (var token in GetCSharpTokens(node)) { - WriteCSharpToken(context, tokens[i]); + WriteCSharpToken(context, token); } if (canTypeCheck) @@ -711,9 +704,9 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.Write("this"); context.CodeWriter.Write(", "); - for (var i = 0; i < tokens.Count; i++) + foreach (var token in GetCSharpTokens(node)) { - WriteCSharpToken(context, tokens[i]); + WriteCSharpToken(context, token); } context.CodeWriter.Write(")"); @@ -742,10 +735,7 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.Write("("); } - for (var i = 0; i < tokens.Count; i++) - { - WriteCSharpToken(context, tokens[i]); - } + WriteAttributeValue(context, node.FindDescendantNodes()); if (canTypeCheck && NeedsTypeCheck(node)) { @@ -945,11 +935,6 @@ private void WriteSplatInnards(CodeRenderingContext context, SplatIntermediateNo public sealed override void WriteFormName(CodeRenderingContext context, FormNameIntermediateNode node) { - if (node.Children.Count > 1) - { - Debug.Assert(node.HasDiagnostics, "We should have reported an error for mixed content."); - } - // string __formName = expression; context.CodeWriter.Write("string "); context.CodeWriter.Write(_scopeStack.FormNameVarName); diff --git a/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorComponentTests.cs b/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorComponentTests.cs index 6af7ad1ca12..544d6b0f293 100644 --- a/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorComponentTests.cs +++ b/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorComponentTests.cs @@ -753,4 +753,36 @@ public async Task UnrecognizedComponentName() Diagnostic("RZ10023").WithLocation(7, 18)); // Attribute '@rendermode' is only valid when used on a component. Assert.Single(result.GeneratedSources); } + + [Fact, WorkItem("https://github.com/dotnet/razor/issues/7684")] + public async Task MixedContent_StringParameter() + { + // Arrange + var project = CreateTestProject(new() + { + ["Views/Home/Index.cshtml"] = """ + @(await Html.RenderComponentAsync(RenderMode.Static)) + """, + ["Shared/Component1.razor"] = """ + @{ var x = 42; } + + """, + ["Shared/Component2.razor"] = """ + Got: |@Param| + @code { + [Parameter] public string? Param { get; set; } + } + """, + }); + var compilation = await project.GetCompilationAsync(); + var driver = await GetDriverAsync(project); + + // Act + var result = RunGenerator(compilation!, ref driver, out compilation); + + // Assert + result.Diagnostics.Verify(); + Assert.Equal(3, result.GeneratedSources.Length); + await VerifyRazorPageMatchesBaselineAsync(compilation, "Views_Home_Index"); + } } diff --git a/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/TestFiles/RazorSourceGeneratorComponentTests/MixedContent_StringParameter/Views_Home_Index.html b/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/TestFiles/RazorSourceGeneratorComponentTests/MixedContent_StringParameter/Views_Home_Index.html new file mode 100644 index 00000000000..bdaf9319d2e --- /dev/null +++ b/src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/TestFiles/RazorSourceGeneratorComponentTests/MixedContent_StringParameter/Views_Home_Index.html @@ -0,0 +1 @@ +Got: |start literal 42 end| From 498b08d22cb05df32d83cc8a62b93ee579936ca1 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Mon, 18 Dec 2023 15:46:07 +0100 Subject: [PATCH 2/4] Consolidate design-time with runtime codegen --- .../Components/ComponentDesignTimeNodeWriter.cs | 16 +++++----------- .../src/Components/ComponentRuntimeNodeWriter.cs | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs index 11e00480166..91ac6d83e99 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs @@ -782,9 +782,6 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon // // Or a CSharpExpressionIntermediateNode when the attribute has an explicit transition like: // - // - // Of a list of tokens directly in the attribute. - var tokens = GetCSharpTokens(node); if ((node.BoundAttribute?.IsDelegateProperty() ?? false) || (node.BoundAttribute?.IsChildContentProperty() ?? false)) @@ -799,9 +796,9 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon } context.CodeWriter.WriteLine(); - for (var i = 0; i < tokens.Count; i++) + foreach (var token in GetCSharpTokens(node)) { - WriteCSharpToken(context, tokens[i]); + WriteCSharpToken(context, token); } if (canTypeCheck) @@ -855,9 +852,9 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.WriteLine(); - for (var i = 0; i < tokens.Count; i++) + foreach (var token in GetCSharpTokens(node)) { - WriteCSharpToken(context, tokens[i]); + WriteCSharpToken(context, token); } context.CodeWriter.Write(")"); @@ -889,10 +886,7 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.Write("("); } - for (var i = 0; i < tokens.Count; i++) - { - WriteCSharpToken(context, tokens[i]); - } + ComponentRuntimeNodeWriter.WriteAttributeValue(context, node.FindDescendantNodes()); if (canTypeCheck && NeedsTypeCheck(node)) { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs index 4d7a066a8b2..30b332ec80e 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs @@ -1096,7 +1096,7 @@ private static string GetHtmlContent(HtmlContentIntermediateNode node) // Only the mixed case is complicated, we want to turn it into code that will concatenate // the values into a string at runtime. - private static void WriteAttributeValue(CodeRenderingContext context, IReadOnlyList tokens) + internal static void WriteAttributeValue(CodeRenderingContext context, IReadOnlyList tokens) { if (tokens == null) { From 3aa7aff57e4a13b6d2a4ffa9d32a98c3bedd4c88 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Mon, 18 Dec 2023 15:57:49 +0100 Subject: [PATCH 3/4] Update tests --- .../ComponentCodeGenerationTestBase.cs | 28 +++++++++---------- ...ComponentDiagnosticRazorIntegrationTest.cs | 8 ++---- ...nentRenderModeAttributeIntegrationTests.cs | 2 +- .../ComponentTemplateIntegrationTest.cs | 3 +- .../TestComponent.codegen.cs | 4 +-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 11 ++------ .../TestComponent.codegen.cs | 4 +-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 11 ++------ .../TestComponent.codegen.cs | 5 ++-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 16 ++--------- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.codegen.cs | 4 +-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 2 +- .../TestComponent.codegen.cs | 4 +-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 2 +- .../TestComponent.codegen.cs | 5 ++-- .../TestComponent.diagnostics.txt | 1 - .../TestComponent.mappings.txt | 2 +- .../TestComponent.diagnostics.txt | 1 - 24 files changed, 43 insertions(+), 76 deletions(-) delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt delete mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs index f81c9003b8c..13b8078c852 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs @@ -9954,11 +9954,15 @@ public enum MyEnum AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); var result = CompileToAssembly(generated, throwOnFailure: false); + // Error reported twice due to https://github.com/dotnet/roslyn/issues/71303. result.Diagnostics.Verify( + // x:\dir\subdir\Test\TestComponent.cshtml(1,31): error CS0119: 'TestComponent.MyEnum' is a type, which is not valid in the given context + // MyEnum + Diagnostic(ErrorCode.ERR_BadSKunknown, "MyEnum").WithArguments("Test.TestComponent.MyEnum", "type").WithLocation(1, 31), // x:\dir\subdir\Test\TestComponent.cshtml(1,31): error CS0119: 'TestComponent.MyEnum' is a type, which is not valid in the given context // MyEnum Diagnostic(ErrorCode.ERR_BadSKunknown, "MyEnum").WithArguments("Test.TestComponent.MyEnum", "type").WithLocation(1, 31)); - Assert.NotEmpty(generated.Diagnostics); + Assert.Empty(generated.Diagnostics); } [IntegrationTestFact, WorkItem("https://github.com/dotnet/razor/issues/9346")] @@ -9994,11 +9998,15 @@ public enum MyEnum AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); var result = CompileToAssembly(generated, throwOnFailure: false); + // Error reported twice due to https://github.com/dotnet/roslyn/issues/71303. result.Diagnostics.Verify( + // x:\dir\subdir\Test\TestComponent.cshtml(1,31): error CS0119: 'TestComponent.MyEnum' is a type, which is not valid in the given context + // MyEnum + Diagnostic(ErrorCode.ERR_BadSKunknown, "MyEnum").WithArguments("Test.TestComponent.MyEnum", "type").WithLocation(1, 31), // x:\dir\subdir\Test\TestComponent.cshtml(1,31): error CS0119: 'TestComponent.MyEnum' is a type, which is not valid in the given context // MyEnum Diagnostic(ErrorCode.ERR_BadSKunknown, "MyEnum").WithArguments("Test.TestComponent.MyEnum", "type").WithLocation(1, 31)); - Assert.NotEmpty(generated.Diagnostics); + Assert.Empty(generated.Diagnostics); } [IntegrationTestFact, WorkItem("https://github.com/dotnet/razor/issues/9346")] @@ -10030,18 +10038,8 @@ public class MyComponent : ComponentBase AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); var result = CompileToAssembly(generated, throwOnFailure: false); - result.Diagnostics.Verify( - // x:\dir\subdir\Test\TestComponent.cshtml(1,32): error CS1003: Syntax error, ',' expected - // x - Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(",").WithLocation(1, 32), - DesignTime - // (23,91): error CS1501: No overload for method 'TypeCheck' takes 2 arguments - // __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( - ? Diagnostic(ErrorCode.ERR_BadArgCount, "TypeCheck").WithArguments("TypeCheck", "2").WithLocation(23, 91) - // (17,138): error CS1501: No overload for method 'TypeCheck' takes 2 arguments - // __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( - : Diagnostic(ErrorCode.ERR_BadArgCount, "TypeCheck").WithArguments("TypeCheck", "2").WithLocation(17, 138)); - Assert.NotEmpty(generated.Diagnostics); + result.Diagnostics.Verify(); + Assert.Empty(generated.Diagnostics); } [IntegrationTestFact] @@ -10659,7 +10657,7 @@ @using Microsoft.AspNetCore.Components.Web { result.Diagnostics.Verify(); } - Assert.NotEmpty(generated.Diagnostics); + Assert.Empty(generated.Diagnostics); } [IntegrationTestFact, WorkItem("https://github.com/dotnet/razor/issues/9077")] diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs index 6610bd4816e..de108eebed0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs @@ -92,7 +92,7 @@ @tagHelperPrefix th } [Fact] - public void DirectiveAttribute_ComplexContent_ReportsError() + public void DirectiveAttribute_ComplexContent_Works() { // Arrange & Act var generated = CompileToCSharp(@" @@ -102,11 +102,7 @@ public void DirectiveAttribute_ComplexContent_ReportsError() }"); // Assert - var diagnostic = Assert.Single(generated.Diagnostics); - Assert.Equal("RZ9986", diagnostic.Id); - Assert.Equal( - "Component attributes do not support complex content (mixed C# and markup). Attribute: '@key', text: 'Foo @Text'", - diagnostic.GetMessage(CultureInfo.CurrentCulture)); + Assert.Empty(generated.Diagnostics); } [Fact] diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentRenderModeAttributeIntegrationTests.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentRenderModeAttributeIntegrationTests.cs index 195361db37a..a7aec10a0a8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentRenderModeAttributeIntegrationTests.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentRenderModeAttributeIntegrationTests.cs @@ -19,7 +19,7 @@ public class ComponentRenderModeAttributeIntegrationTests : RazorIntegrationTest public void RenderMode_Attribute_With_Diagnostics() { var generated = CompileToCSharp($$""" - <{{ComponentName}} @rendermode="@Microsoft.AspNetCore.Components.Web.RenderMode.Server)" /> + <{{ComponentName}} @rendermode="@{Microsoft.AspNetCore.Components.Web.RenderMode.Server}" /> """, throwOnFailure: true); // Assert diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentTemplateIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentTemplateIntegrationTest.cs index 0d179dbb115..4f1d2e84e23 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentTemplateIntegrationTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentTemplateIntegrationTest.cs @@ -64,8 +64,7 @@ public class MyComponent : ComponentBase // Assert Assert.Collection( generated.Diagnostics, - d => Assert.Equal("RZ9986", d.Id), - d => Assert.Equal("RZ1005", d.Id)); + d => Assert.Equal("RZ1005", d.Id)); // "<" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid. } [Fact] diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs index 5c5d677112f..eea4de2d596 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs @@ -20,7 +20,7 @@ private void __RazorDirectiveTokenHelpers__() { #pragma warning disable 1998 protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { - __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" MyEnum @@ -28,7 +28,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - ); + ) + "."); __builder.AddAttribute(-1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { } )); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt deleted file mode 100644 index 9c22e6e9370..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'MyEnum.' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt index 2b544bc65e5..a148e12a4c5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt @@ -1,11 +1,6 @@ -Source Location: (30:0,30 [6] x:\dir\subdir\Test\TestComponent.cshtml) -|MyEnum| -Generated Location: (1056:25,30 [6] ) -|MyEnum| - -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| -Generated Location: (1470:38,13 [14] ) +Generated Location: (1478:38,13 [14] ) |StringProperty| Source Location: (52:2,7 [67] x:\dir\subdir\Test\TestComponent.cshtml) @@ -16,7 +11,7 @@ Source Location: (52:2,7 [67] x:\dir\subdir\Test\TestComponent.cshtml) Two } | -Generated Location: (1892:56,7 [67] ) +Generated Location: (1900:56,7 [67] ) | public enum MyEnum { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs index 5c5d677112f..6d9e51326d8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs @@ -20,7 +20,7 @@ private void __RazorDirectiveTokenHelpers__() { #pragma warning disable 1998 protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { - __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" MyEnum @@ -28,7 +28,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - ); + ) + "+"); __builder.AddAttribute(-1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { } )); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt deleted file mode 100644 index 3400e31d1e7..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'MyEnum+' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt index 2b544bc65e5..a148e12a4c5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt @@ -1,11 +1,6 @@ -Source Location: (30:0,30 [6] x:\dir\subdir\Test\TestComponent.cshtml) -|MyEnum| -Generated Location: (1056:25,30 [6] ) -|MyEnum| - -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| -Generated Location: (1470:38,13 [14] ) +Generated Location: (1478:38,13 [14] ) |StringProperty| Source Location: (52:2,7 [67] x:\dir\subdir\Test\TestComponent.cshtml) @@ -16,7 +11,7 @@ Source Location: (52:2,7 [67] x:\dir\subdir\Test\TestComponent.cshtml) Two } | -Generated Location: (1892:56,7 [67] ) +Generated Location: (1900:56,7 [67] ) | public enum MyEnum { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs index ca6db6e8871..9dab150b9e8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs @@ -20,7 +20,7 @@ private void __RazorDirectiveTokenHelpers__() { #pragma warning disable 1998 protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { - __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" x @@ -28,6 +28,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable + ) + " html" + " " + ( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" "string" @@ -35,7 +36,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - ); + )); __builder.AddAttribute(-1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { } )); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt deleted file mode 100644 index 7062ba171f1..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'x html "string"' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt index 6299965f810..24d76a47458 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt @@ -1,23 +1,13 @@ -Source Location: (30:0,30 [1] x:\dir\subdir\Test\TestComponent.cshtml) -|x| -Generated Location: (1056:25,30 [1] ) -|x| - -Source Location: (39:0,39 [8] x:\dir\subdir\Test\TestComponent.cshtml) -|"string"| -Generated Location: (1218:32,39 [8] ) -|"string"| - -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| -Generated Location: (1634:45,13 [14] ) +Generated Location: (1671:46,13 [14] ) |StringProperty| Source Location: (63:2,7 [18] x:\dir\subdir\Test\TestComponent.cshtml) | int x = 1; | -Generated Location: (2056:63,7 [18] ) +Generated Location: (2093:64,7 [18] ) | int x = 1; | diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt deleted file mode 100644 index 85314d2ebd4..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(2,54): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: '@formname', text: 'start "literal" x end' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs index be4f5c3ce01..dded3f8a47d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.codegen.cs @@ -14,7 +14,7 @@ public partial class TestComponent : global::Microsoft.AspNetCore.Components.Com protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { __builder.OpenComponent(0); - __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" MyEnum @@ -22,7 +22,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - )); + ) + ".")); __builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt deleted file mode 100644 index 9c22e6e9370..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'MyEnum.' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt index b6062b8d7df..41e40b191f5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt @@ -6,7 +6,7 @@ Two } | -Generated Location: (1151:30,7 [67] ) +Generated Location: (1159:30,7 [67] ) | public enum MyEnum { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs index be4f5c3ce01..112aa24b1e0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.codegen.cs @@ -14,7 +14,7 @@ public partial class TestComponent : global::Microsoft.AspNetCore.Components.Com protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { __builder.OpenComponent(0); - __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" MyEnum @@ -22,7 +22,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - )); + ) + "+")); __builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt deleted file mode 100644 index 3400e31d1e7..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'MyEnum+' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt index b6062b8d7df..41e40b191f5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt @@ -6,7 +6,7 @@ Two } | -Generated Location: (1151:30,7 [67] ) +Generated Location: (1159:30,7 [67] ) | public enum MyEnum { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs index 608bf107ffb..1f00a684d03 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.codegen.cs @@ -14,7 +14,7 @@ public partial class TestComponent : global::Microsoft.AspNetCore.Components.Com protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { __builder.OpenComponent(0); - __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( + __builder.AddComponentParameter(1, "StringProperty", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" x @@ -22,6 +22,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable + ) + " html" + " " + ( #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" "string" @@ -29,7 +30,7 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. #line default #line hidden #nullable disable - )); + ))); __builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt deleted file mode 100644 index 7062ba171f1..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(1,30): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: 'StringProperty', text: 'x html "string"' diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt index 4cf862ba92c..ae139e462a4 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt @@ -2,7 +2,7 @@ | int x = 1; | -Generated Location: (1315:37,7 [18] ) +Generated Location: (1352:38,7 [18] ) | int x = 1; | diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt deleted file mode 100644 index 85314d2ebd4..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/FormName_MixedValue/TestComponent.diagnostics.txt +++ /dev/null @@ -1 +0,0 @@ -x:\dir\subdir\Test\TestComponent.cshtml(2,54): Error RZ9986: Component attributes do not support complex content (mixed C# and markup). Attribute: '@formname', text: 'start "literal" x end' From ec61ff1d81557133e0daf4515b00afaf75a3e440 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Wed, 20 Dec 2023 13:00:09 +0100 Subject: [PATCH 4/4] Write C# tokens with mappings in design-time --- .../ComponentDesignTimeNodeWriter.cs | 7 +- .../src/Components/ComponentNodeWriter.cs | 95 +++++++++++++++++++ .../Components/ComponentRuntimeNodeWriter.cs | 95 +------------------ .../TestComponent.mappings.txt | 7 +- .../TestComponent.mappings.txt | 7 +- .../TestComponent.mappings.txt | 12 ++- 6 files changed, 124 insertions(+), 99 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs index 91ac6d83e99..bbef4d60075 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Language.Extensions; @@ -17,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components; // Based on the DesignTimeNodeWriter from Razor repo. -internal class ComponentDesignTimeNodeWriter : ComponentNodeWriter +internal sealed class ComponentDesignTimeNodeWriter : ComponentNodeWriter { private readonly ScopeStack _scopeStack = new ScopeStack(); @@ -886,7 +885,7 @@ private void WriteComponentAttributeInnards(CodeRenderingContext context, Compon context.CodeWriter.Write("("); } - ComponentRuntimeNodeWriter.WriteAttributeValue(context, node.FindDescendantNodes()); + WriteAttributeValue(context, node.FindDescendantNodes()); if (canTypeCheck && NeedsTypeCheck(node)) { @@ -1230,7 +1229,7 @@ public override void WriteRenderMode(CodeRenderingContext context, RenderModeInt }); } - private void WriteCSharpToken(CodeRenderingContext context, IntermediateToken token) + protected override void WriteCSharpToken(CodeRenderingContext context, IntermediateToken token) { if (string.IsNullOrWhiteSpace(token.Content)) { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs index 897de949229..1814ab64869 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs @@ -455,6 +455,101 @@ protected static void WriteAddComponentRenderMode(CodeRenderingContext context, context.CodeWriter.WriteLine(); } + protected abstract void WriteCSharpToken(CodeRenderingContext context, IntermediateToken token); + + // There are a few cases here, we need to handle: + // - Pure HTML + // - Pure CSharp + // - Mixed HTML and CSharp + // + // Only the mixed case is complicated, we want to turn it into code that will concatenate + // the values into a string at runtime. + protected void WriteAttributeValue(CodeRenderingContext context, IReadOnlyList tokens) + { + if (tokens == null) + { + throw new ArgumentNullException(nameof(tokens)); + } + + var writer = context.CodeWriter; + var hasHtml = false; + var hasCSharp = false; + for (var i = 0; i < tokens.Count; i++) + { + if (tokens[i].IsCSharp) + { + hasCSharp |= true; + } + else + { + hasHtml |= true; + } + } + + if (hasHtml && hasCSharp) + { + // If it's a C# expression, we have to wrap it in parens, otherwise things like ternary + // expressions don't compose with concatenation. However, this is a little complicated + // because C# tokens themselves aren't guaranteed to be distinct expressions. We want + // to treat all contiguous C# tokens as a single expression. + var insideCSharp = false; + for (var i = 0; i < tokens.Count; i++) + { + var token = tokens[i]; + if (token.IsCSharp) + { + if (!insideCSharp) + { + if (i != 0) + { + writer.Write(" + "); + } + + writer.Write("("); + insideCSharp = true; + } + + WriteCSharpToken(context, token); + } + else + { + if (insideCSharp) + { + writer.Write(")"); + insideCSharp = false; + } + + if (i != 0) + { + writer.Write(" + "); + } + + writer.WriteStringLiteral(token.Content); + } + } + + if (insideCSharp) + { + writer.Write(")"); + } + } + else if (hasCSharp) + { + foreach (var token in tokens) + { + WriteCSharpToken(context, token); + } + } + else if (hasHtml) + { + writer.WriteStringLiteral(string.Join("", tokens.Select(t => t.Content))); + } + else + { + throw new InvalidOperationException("Found attribute whose value is neither HTML nor CSharp"); + } + } + protected class TypeInferenceMethodParameter { public string SeqName { get; private set; } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs index 30b332ec80e..2321660c8bf 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components; /// /// Generates the C# code corresponding to Razor source document contents. /// -internal class ComponentRuntimeNodeWriter : ComponentNodeWriter +internal sealed class ComponentRuntimeNodeWriter : ComponentNodeWriter { private readonly List _currentAttributeValues = new List(); private readonly ScopeStack _scopeStack = new ScopeStack(); @@ -1088,98 +1088,9 @@ private static string GetHtmlContent(HtmlContentIntermediateNode node) return builder.ToString(); } - // There are a few cases here, we need to handle: - // - Pure HTML - // - Pure CSharp - // - Mixed HTML and CSharp - // - // Only the mixed case is complicated, we want to turn it into code that will concatenate - // the values into a string at runtime. - - internal static void WriteAttributeValue(CodeRenderingContext context, IReadOnlyList tokens) + protected override void WriteCSharpToken(CodeRenderingContext context, IntermediateToken token) { - if (tokens == null) - { - throw new ArgumentNullException(nameof(tokens)); - } - - var writer = context.CodeWriter; - var hasHtml = false; - var hasCSharp = false; - for (var i = 0; i < tokens.Count; i++) - { - if (tokens[i].IsCSharp) - { - hasCSharp |= true; - } - else - { - hasHtml |= true; - } - } - - if (hasHtml && hasCSharp) - { - // If it's a C# expression, we have to wrap it in parens, otherwise things like ternary - // expressions don't compose with concatenation. However, this is a little complicated - // because C# tokens themselves aren't guaranteed to be distinct expressions. We want - // to treat all contiguous C# tokens as a single expression. - var insideCSharp = false; - for (var i = 0; i < tokens.Count; i++) - { - var token = tokens[i]; - if (token.IsCSharp) - { - if (!insideCSharp) - { - if (i != 0) - { - writer.Write(" + "); - } - - writer.Write("("); - insideCSharp = true; - } - - WriteCSharpToken(context, token); - } - else - { - if (insideCSharp) - { - writer.Write(")"); - insideCSharp = false; - } - - if (i != 0) - { - writer.Write(" + "); - } - - writer.WriteStringLiteral(token.Content); - } - } - - if (insideCSharp) - { - writer.Write(")"); - } - } - else if (hasCSharp) - { - foreach (var token in tokens) - { - WriteCSharpToken(context, token); - } - } - else if (hasHtml) - { - writer.WriteStringLiteral(string.Join("", tokens.Select(t => t.Content))); - } - else - { - throw new InvalidOperationException("Found attribute whose value is neither HTML nor CSharp"); - } + WriteCSharpToken(context, token, includeLinePragma: true); } private static void WriteCSharpToken(CodeRenderingContext context, IntermediateToken token, bool includeLinePragma = true) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt index a148e12a4c5..2d3be03cec7 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute/TestComponent.mappings.txt @@ -1,4 +1,9 @@ -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (30:0,30 [6] x:\dir\subdir\Test\TestComponent.cshtml) +|MyEnum| +Generated Location: (1057:25,30 [6] ) +|MyEnum| + +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| Generated Location: (1478:38,13 [14] ) |StringProperty| diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt index a148e12a4c5..2d3be03cec7 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_02/TestComponent.mappings.txt @@ -1,4 +1,9 @@ -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (30:0,30 [6] x:\dir\subdir\Test\TestComponent.cshtml) +|MyEnum| +Generated Location: (1057:25,30 [6] ) +|MyEnum| + +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| Generated Location: (1478:38,13 [14] ) |StringProperty| diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt index 24d76a47458..0e0ad07c9ff 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_ComplexContentInAttribute_03/TestComponent.mappings.txt @@ -1,4 +1,14 @@ -Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) +Source Location: (30:0,30 [1] x:\dir\subdir\Test\TestComponent.cshtml) +|x| +Generated Location: (1057:25,30 [1] ) +|x| + +Source Location: (39:0,39 [8] x:\dir\subdir\Test\TestComponent.cshtml) +|"string"| +Generated Location: (1254:33,39 [8] ) +|"string"| + +Source Location: (13:0,13 [14] x:\dir\subdir\Test\TestComponent.cshtml) |StringProperty| Generated Location: (1671:46,13 [14] ) |StringProperty|