diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorImportProjectFeature.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorImportProjectFeature.cs
index af943fad46..4259df00c4 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorImportProjectFeature.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorImportProjectFeature.cs
@@ -14,12 +14,15 @@ namespace Microsoft.AspNetCore.Blazor.Razor
{
private const string ImportsFileName = "_ViewImports.cshtml";
- private const string DefaultUsingImportContent = @"
-@using System
-@using System.Collections.Generic
-@using System.Linq
-@using System.Threading.Tasks
-";
+ private static readonly char[] PathSeparators = new char[]{ '/', '\\' };
+
+ // Using explicit newlines here to avoid fooling our baseline tests
+ private const string DefaultUsingImportContent =
+ "\r\n" +
+ "@using System\r\n" +
+ "@using System.Collections.Generic\r\n" +
+ "@using System.Linq\r\n" +
+ "@using System.Threading.Tasks\r\n";
public RazorProjectEngine ProjectEngine { get; set; }
@@ -40,9 +43,13 @@ namespace Microsoft.AspNetCore.Blazor.Razor
// the namespace through from the project.
if (projectItem.PhysicalPath != null && projectItem.FilePath != null)
{
+ // Avoiding the path-specific APIs here, we want to handle all styles of paths
+ // on all platforms
var trimLength = projectItem.FilePath.Length + (projectItem.FilePath.StartsWith("/") ? 0 : 1);
var baseDirectory = projectItem.PhysicalPath.Substring(0, projectItem.PhysicalPath.Length - trimLength);
- var baseNamespace = Path.GetFileName(baseDirectory);
+
+ var lastSlash = baseDirectory.LastIndexOfAny(PathSeparators);
+ var baseNamespace = lastSlash == -1 ? baseDirectory : baseDirectory.Substring(lastSlash + 1);
if (!string.IsNullOrEmpty(baseNamespace))
{
imports.Add(new VirtualProjectItem($@"@addTagHelper ""*, {baseNamespace}"""));
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentBodyExtensionNode.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentBodyExtensionNode.cs
index 4ab7c24842..ad116f49e0 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentBodyExtensionNode.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentBodyExtensionNode.cs
@@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Blazor.Razor
{
- public sealed class ComponentBodyExtensionNode : ExtensionIntermediateNode
+ internal sealed class ComponentBodyExtensionNode : ExtensionIntermediateNode
{
public ComponentBodyExtensionNode()
{
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentDocumentClassifierPass.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentDocumentClassifierPass.cs
index 0e2e51493f..35151fcac9 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentDocumentClassifierPass.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentDocumentClassifierPass.cs
@@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor
callBase.Children.Add(new IntermediateToken
{
Kind = TokenKind.CSharp,
- Content = $"base.{BlazorApi.BlazorComponent.BuildRenderTree}(builder);" + Environment.NewLine
+ Content = $"base.{BlazorApi.BlazorComponent.BuildRenderTree}(builder);"
});
method.Children.Insert(0, callBase);
}
@@ -108,7 +108,9 @@ namespace Microsoft.AspNetCore.Blazor.Razor
// the namespace through from the project.
var trimLength = relativePath.Length + (relativePath.StartsWith("/") ? 0 : 1);
var baseDirectory = filePath.Substring(0, filePath.Length - trimLength);
- var baseNamespace = Path.GetFileName(baseDirectory);
+
+ var lastSlash = baseDirectory.LastIndexOfAny(PathSeparators);
+ var baseNamespace = lastSlash == -1 ? baseDirectory : baseDirectory.Substring(lastSlash + 1);
if (string.IsNullOrEmpty(baseNamespace))
{
@namespace = null;
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/PageDirectivePass.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/PageDirectivePass.cs
index b3e5b8bc6f..8d5ac68a87 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/PageDirectivePass.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/PageDirectivePass.cs
@@ -78,30 +78,5 @@ namespace Microsoft.AspNetCore.Blazor.Razor
}
}
}
-
- private class RouteAttributeExtensionNode : ExtensionIntermediateNode
- {
- public RouteAttributeExtensionNode(string template)
- {
- Template = template;
- }
-
- public string Template { get; }
-
- public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
-
- public override void Accept(IntermediateNodeVisitor visitor) => AcceptExtensionNode(this, visitor);
-
- public override void WriteNode(CodeTarget target, CodeRenderingContext context)
- {
- context.CodeWriter.Write("[");
- context.CodeWriter.Write(BlazorApi.RouteAttribute.FullTypeName);
- context.CodeWriter.Write("(\"");
- context.CodeWriter.Write(Template);
- context.CodeWriter.Write("\")");
- context.CodeWriter.Write("]");
- context.CodeWriter.WriteLine();
- }
- }
}
}
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/RouteAttributeExtensionNode.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/RouteAttributeExtensionNode.cs
new file mode 100644
index 0000000000..2760803d18
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/RouteAttributeExtensionNode.cs
@@ -0,0 +1,33 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+
+namespace Microsoft.AspNetCore.Blazor.Razor
+{
+ internal class RouteAttributeExtensionNode : ExtensionIntermediateNode
+ {
+ public RouteAttributeExtensionNode(string template)
+ {
+ Template = template;
+ }
+
+ public string Template { get; }
+
+ public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
+
+ public override void Accept(IntermediateNodeVisitor visitor) => AcceptExtensionNode(this, visitor);
+
+ public override void WriteNode(CodeTarget target, CodeRenderingContext context)
+ {
+ context.CodeWriter.Write("[");
+ context.CodeWriter.Write(BlazorApi.RouteAttribute.FullTypeName);
+ context.CodeWriter.Write("(\"");
+ context.CodeWriter.Write(Template);
+ context.CodeWriter.Write("\")");
+ context.CodeWriter.Write("]");
+ context.CodeWriter.WriteLine();
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationRazorIntegrationTest.cs
deleted file mode 100644
index 1932146b63..0000000000
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationRazorIntegrationTest.cs
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.CodeAnalysis.CSharp;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Blazor.Build.Test
-{
- public class DesignTimeCodeGenerationRazorIntegrationTest : RazorIntegrationTestBase
- {
- internal override bool DesignTime => true;
-
- internal override bool UseTwoPhaseCompilation => true;
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithParameters()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class SomeType
- {
- }
-
- public class MyComponent : BlazorComponent
- {
- public int IntProperty { get; set; }
- public bool BoolProperty { get; set; }
- public string StringProperty { get; set; }
- public SomeType ObjectProperty { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- __o =
-#line 3 ""x:\dir\subdir\Test\TestComponent.cshtml""
- 123
-
-#line default
-#line hidden
- ;
- __o =
-#line 4 ""x:\dir\subdir\Test\TestComponent.cshtml""
- true
-
-#line default
-#line hidden
- ;
- __o =
-#line 6 ""x:\dir\subdir\Test\TestComponent.cshtml""
- new SomeType()
-
-#line default
-#line hidden
- ;
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithExplicitStringParameter()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public string StringProperty { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- __o =
-#line 2 ""x:\dir\subdir\Test\TestComponent.cshtml""
- 42.ToString()
-
-#line default
-#line hidden
- ;
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithNonPropertyAttributes()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- __o =
-#line 2 ""x:\dir\subdir\Test\TestComponent.cshtml""
- 43.ToString()
-
-#line default
-#line hidden
- ;
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithLambdaEventHandler()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using System;
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public UIEventHandler OnClick { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
- { Increment(); })""/>
-
-@functions {
- private int counter;
- private void Increment() {
- counter++;
- }
-}");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- __o = new Microsoft.AspNetCore.Blazor.UIEventHandler(
-#line 2 ""x:\dir\subdir\Test\TestComponent.cshtml""
- (e) => { Increment(); }
-
-#line default
-#line hidden
- );
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
-#line 4 ""x:\dir\subdir\Test\TestComponent.cshtml""
-
- private int counter;
- private void Increment() {
- counter++;
- }
-
-#line default
-#line hidden
- }
-}
-#pragma warning restore 1591
-
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithExplicitEventHandler()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using System;
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public UIEventHandler OnClick { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-@using Microsoft.AspNetCore.Blazor
-
-
-@functions {
- private int counter;
- private void Increment(UIEventArgs e) {
- counter++;
- }
-}");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-#line 2 ""x:\dir\subdir\Test\TestComponent.cshtml""
-using Microsoft.AspNetCore.Blazor;
-
-#line default
-#line hidden
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- __o = new Microsoft.AspNetCore.Blazor.UIEventHandler(
-#line 3 ""x:\dir\subdir\Test\TestComponent.cshtml""
- Increment
-
-#line default
-#line hidden
- );
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
-#line 5 ""x:\dir\subdir\Test\TestComponent.cshtml""
-
- private int counter;
- private void Increment(UIEventArgs e) {
- counter++;
- }
-
-#line default
-#line hidden
- }
-}
-#pragma warning restore 1591
-
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithChildContent()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public string MyAttr { get; set; }
-
- public RenderFragment ChildContent { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-Some textNested text");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 219
- private void __RazorDirectiveTokenHelpers__() {
- ((System.Action)(() => {
-global::System.Object __typeHelper = ""*, TestAssembly"";
- }
- ))();
- }
- #pragma warning restore 219
- #pragma warning disable 0414
- private static System.Object __o = null;
- #pragma warning restore 0414
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.AddAttribute(-1, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- }
- ));
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
- }
-}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs
new file mode 100644
index 0000000000..ada82614ea
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs
@@ -0,0 +1,209 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.CodeAnalysis.CSharp;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Blazor.Build.Test
+{
+ public class DesignTimeCodeGenerationTest : RazorBaselineIntegrationTestBase
+ {
+ internal override bool DesignTime => true;
+
+ internal override bool UseTwoPhaseCompilation => true;
+
+ [Fact]
+ public void ChildComponent_WithParameters()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class SomeType
+ {
+ }
+
+ public class MyComponent : BlazorComponent
+ {
+ public int IntProperty { get; set; }
+ public bool BoolProperty { get; set; }
+ public string StringProperty { get; set; }
+ public SomeType ObjectProperty { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithExplicitStringParameter()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public string StringProperty { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithNonPropertyAttributes()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithLambdaEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public UIEventHandler OnClick { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+ { Increment(); })""/>
+
+@functions {
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithExplicitEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public UIEventHandler OnClick { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+@using Microsoft.AspNetCore.Blazor
+
+
+@functions {
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithChildContent()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public string MyAttr { get; set; }
+
+ public RenderFragment ChildContent { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+Some textNested text");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Microsoft.AspNetCore.Blazor.Build.Test.csproj b/test/Microsoft.AspNetCore.Blazor.Build.Test/Microsoft.AspNetCore.Blazor.Build.Test.csproj
index 6e2c4fc345..e9da46fddd 100644
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/Microsoft.AspNetCore.Blazor.Build.Test.csproj
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Microsoft.AspNetCore.Blazor.Build.Test.csproj
@@ -4,6 +4,18 @@
netcoreapp2.0
false
+
+
+ $(DefaultItemExcludes);TestFiles\**\*
+
+
+
+
+
+
+
+
+ GENERATE_BASELINES;$(DefineConstants)
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/InitializeTestFileAttribute.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/InitializeTestFileAttribute.cs
new file mode 100644
index 0000000000..2add553f5b
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/InitializeTestFileAttribute.cs
@@ -0,0 +1,29 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Reflection;
+using Microsoft.AspNetCore.Blazor.Build.Test;
+using Xunit.Sdk;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class IntializeTestFileAttribute : BeforeAfterTestAttribute
+ {
+ public override void Before(MethodInfo methodUnderTest)
+ {
+ if (typeof(RazorBaselineIntegrationTestBase).GetTypeInfo().IsAssignableFrom(methodUnderTest.DeclaringType.GetTypeInfo()))
+ {
+ var typeName = methodUnderTest.DeclaringType.Name;
+ RazorBaselineIntegrationTestBase.DirectoryPath = $"TestFiles/{typeName}/{methodUnderTest.Name}";
+ }
+ }
+
+ public override void After(MethodInfo methodUnderTest)
+ {
+ if (typeof(RazorBaselineIntegrationTestBase).GetTypeInfo().IsAssignableFrom(methodUnderTest.DeclaringType.GetTypeInfo()))
+ {
+ RazorBaselineIntegrationTestBase.DirectoryPath = null;
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeSerializer.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeSerializer.cs
new file mode 100644
index 0000000000..891a4849ed
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeSerializer.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public static class IntermediateNodeSerializer
+ {
+ public static string Serialize(IntermediateNode node)
+ {
+ using (var writer = new StringWriter())
+ {
+ var walker = new Walker(writer);
+ walker.Visit(node);
+
+ return writer.ToString();
+ }
+ }
+
+ private class Walker : IntermediateNodeWalker
+ {
+ private readonly IntermediateNodeWriter _visitor;
+ private readonly TextWriter _writer;
+
+ public Walker(TextWriter writer)
+ {
+ _visitor = new IntermediateNodeWriter(writer);
+ _writer = writer;
+ }
+
+ public TextWriter Writer { get; }
+
+ public override void VisitDefault(IntermediateNode node)
+ {
+ _visitor.Visit(node);
+ _writer.WriteLine();
+
+ _visitor.Depth++;
+ base.VisitDefault(node);
+ _visitor.Depth--;
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeVerifier.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeVerifier.cs
new file mode 100644
index 0000000000..a75da6a2fc
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeVerifier.cs
@@ -0,0 +1,275 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using Xunit.Sdk;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public static class IntermediateNodeVerifier
+ {
+ public static void Verify(IntermediateNode node, string[] baseline)
+ {
+ var walker = new Walker(baseline);
+ walker.Visit(node);
+ walker.AssertReachedEndOfBaseline();
+ }
+
+ private class Walker : IntermediateNodeWalker
+ {
+ private readonly string[] _baseline;
+ private readonly IntermediateNodeWriter _visitor;
+ private readonly StringWriter _writer;
+
+ private int _index;
+
+ public Walker(string[] baseline)
+ {
+ _writer = new StringWriter();
+
+ _visitor = new IntermediateNodeWriter(_writer);
+ _baseline = baseline;
+
+ }
+
+ public TextWriter Writer { get; }
+
+ public override void VisitDefault(IntermediateNode node)
+ {
+ var expected = _index < _baseline.Length ? _baseline[_index++] : null;
+
+ // Write the node as text for comparison
+ _writer.GetStringBuilder().Clear();
+ _visitor.Visit(node);
+ var actual = _writer.GetStringBuilder().ToString();
+
+ AssertNodeEquals(node, Ancestors, expected, actual);
+
+ _visitor.Depth++;
+ base.VisitDefault(node);
+ _visitor.Depth--;
+ }
+
+ public void AssertReachedEndOfBaseline()
+ {
+ // Since we're walking the nodes of our generated code there's the chance that our baseline is longer.
+ Assert.True(_baseline.Length == _index, "Not all lines of the baseline were visited!");
+ }
+
+ private void AssertNodeEquals(IntermediateNode node, IEnumerable ancestors, string expected, string actual)
+ {
+ if (string.Equals(expected, actual))
+ {
+ // YAY!!! everything is great.
+ return;
+ }
+
+ if (expected == null)
+ {
+ var message = "The node is missing from baseline.";
+ throw new IntermediateNodeBaselineException(node, Ancestors.ToArray(), expected, actual, message);
+ }
+
+ int charsVerified = 0;
+ AssertNestingEqual(node, ancestors, expected, actual, ref charsVerified);
+ AssertNameEqual(node, ancestors, expected, actual, ref charsVerified);
+ AssertDelimiter(node, expected, actual, true, ref charsVerified);
+ AssertLocationEqual(node, ancestors, expected, actual, ref charsVerified);
+ AssertDelimiter(node, expected, actual, false, ref charsVerified);
+ AssertContentEqual(node, ancestors, expected, actual, ref charsVerified);
+
+ throw new InvalidOperationException("We can't figure out HOW these two things are different. This is a bug.");
+ }
+
+ private void AssertNestingEqual(IntermediateNode node, IEnumerable ancestors, string expected, string actual, ref int charsVerified)
+ {
+ var i = 0;
+ for (; i < expected.Length; i++)
+ {
+ if (expected[i] != ' ')
+ {
+ break;
+ }
+ }
+
+ var failed = false;
+ var j = 0;
+ for (; j < i; j++)
+ {
+ if (actual.Length <= j || actual[j] != ' ')
+ {
+ failed = true;
+ break;
+ }
+ }
+
+ if (actual.Length <= j + 1 || actual[j] == ' ')
+ {
+ failed = true;
+ }
+
+ if (failed)
+ {
+ var message = "The node is at the wrong level of nesting. This usually means a child is missing.";
+ throw new IntermediateNodeBaselineException(node, ancestors.ToArray(), expected, actual, message);
+ }
+
+ charsVerified = j;
+ }
+
+ private void AssertNameEqual(IntermediateNode node, IEnumerable ancestors, string expected, string actual, ref int charsVerified)
+ {
+ var expectedName = GetName(expected, charsVerified);
+ var actualName = GetName(actual, charsVerified);
+
+ if (!string.Equals(expectedName, actualName))
+ {
+ var message = $"Node names are not equal.";
+ throw new IntermediateNodeBaselineException(node, ancestors.ToArray(), expected, actual, message);
+ }
+
+ charsVerified += expectedName.Length;
+ }
+
+ // Either both strings need to have a delimiter next or neither should.
+ private void AssertDelimiter(IntermediateNode node, string expected, string actual, bool required, ref int charsVerified)
+ {
+ if (charsVerified == expected.Length && required)
+ {
+ throw new InvalidOperationException($"Baseline text is not well-formed: '{expected}'.");
+ }
+
+ if (charsVerified == actual.Length && required)
+ {
+ throw new InvalidOperationException($"Baseline text is not well-formed: '{actual}'.");
+ }
+
+ if (charsVerified == expected.Length && charsVerified == actual.Length)
+ {
+ return;
+ }
+
+ var expectedDelimiter = expected.IndexOf(" - ", charsVerified);
+ if (expectedDelimiter != charsVerified && expectedDelimiter != -1)
+ {
+ throw new InvalidOperationException($"Baseline text is not well-formed: '{actual}'.");
+ }
+
+ var actualDelimiter = actual.IndexOf(" - ", charsVerified);
+ if (actualDelimiter != charsVerified && actualDelimiter != -1)
+ {
+ throw new InvalidOperationException($"Baseline text is not well-formed: '{actual}'.");
+ }
+
+ Assert.Equal(expectedDelimiter, actualDelimiter);
+
+ charsVerified += 3;
+ }
+
+ private void AssertLocationEqual(IntermediateNode node, IEnumerable ancestors, string expected, string actual, ref int charsVerified)
+ {
+ var expectedLocation = GetLocation(expected, charsVerified);
+ var actualLocation = GetLocation(actual, charsVerified);
+
+ if (!string.Equals(expectedLocation, actualLocation))
+ {
+ var message = $"Locations are not equal.";
+ throw new IntermediateNodeBaselineException(node, ancestors.ToArray(), expected, actual, message);
+ }
+
+ charsVerified += expectedLocation.Length;
+ }
+
+ private void AssertContentEqual(IntermediateNode node, IEnumerable ancestors, string expected, string actual, ref int charsVerified)
+ {
+ var expectedContent = GetContent(expected, charsVerified);
+ var actualContent = GetContent(actual, charsVerified);
+
+ if (!string.Equals(expectedContent, actualContent))
+ {
+ var message = $"Contents are not equal.";
+ throw new IntermediateNodeBaselineException(node, ancestors.ToArray(), expected, actual, message);
+ }
+
+ charsVerified += expectedContent.Length;
+ }
+
+ private string GetName(string text, int start)
+ {
+ var delimiter = text.IndexOf(" - ", start);
+ if (delimiter == -1)
+ {
+ throw new InvalidOperationException($"Baseline text is not well-formed: '{text}'.");
+ }
+
+ return text.Substring(start, delimiter - start);
+ }
+
+ private string GetLocation(string text, int start)
+ {
+ var delimiter = text.IndexOf(" - ", start);
+ return delimiter == -1 ? text.Substring(start) : text.Substring(start, delimiter - start);
+ }
+
+ private string GetContent(string text, int start)
+ {
+ return start == text.Length ? string.Empty : text.Substring(start);
+ }
+
+ private class IntermediateNodeBaselineException : XunitException
+ {
+ public IntermediateNodeBaselineException(IntermediateNode node, IntermediateNode[] ancestors, string expected, string actual, string userMessage)
+ : base(Format(node, ancestors, expected, actual, userMessage))
+ {
+ Node = node;
+ Expected = expected;
+ Actual = actual;
+ }
+
+ public IntermediateNode Node { get; }
+
+ public string Actual { get; }
+
+ public string Expected { get; }
+
+ private static string Format(IntermediateNode node, IntermediateNode[] ancestors, string expected, string actual, string userMessage)
+ {
+ var builder = new StringBuilder();
+ builder.AppendLine(userMessage);
+ builder.AppendLine();
+
+ if (expected != null)
+ {
+ builder.Append("Expected: ");
+ builder.AppendLine(expected);
+ }
+
+ if (actual != null)
+ {
+ builder.Append("Actual: ");
+ builder.AppendLine(actual);
+ }
+
+ if (ancestors != null)
+ {
+ builder.AppendLine();
+ builder.AppendLine("Path:");
+
+ foreach (var ancestor in ancestors)
+ {
+ builder.AppendLine(ancestor.ToString());
+ }
+ }
+
+ return builder.ToString();
+ }
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeWriter.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeWriter.cs
new file mode 100644
index 0000000000..7e3fb814ba
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/IntermediateNodeWriter.cs
@@ -0,0 +1,292 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Microsoft.AspNetCore.Blazor.Razor;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ // Serializes single IR nodes (shallow).
+ public class IntermediateNodeWriter :
+ IntermediateNodeVisitor,
+ IExtensionIntermediateNodeVisitor,
+ IExtensionIntermediateNodeVisitor,
+ IExtensionIntermediateNodeVisitor,
+ IExtensionIntermediateNodeVisitor,
+ IExtensionIntermediateNodeVisitor
+ {
+ private readonly TextWriter _writer;
+
+ public IntermediateNodeWriter(TextWriter writer)
+ {
+ _writer = writer;
+ }
+
+ public int Depth { get; set; }
+
+ public override void VisitDefault(IntermediateNode node)
+ {
+ WriteBasicNode(node);
+ }
+
+ public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
+ {
+ WriteContentNode(node, string.Join(" ", node.Modifiers), node.ClassName, node.BaseType, string.Join(", ", node.Interfaces ?? new List()));
+ }
+
+ public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node)
+ {
+ WriteContentNode(node, node.Prefix);
+ }
+
+ public override void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node)
+ {
+ WriteContentNode(node, node.Prefix);
+ }
+
+ public override void VisitToken(IntermediateToken node)
+ {
+ WriteContentNode(node, node.Kind.ToString(), node.Content);
+ }
+
+ public override void VisitMalformedDirective(MalformedDirectiveIntermediateNode node)
+ {
+ WriteContentNode(node, node.DirectiveName);
+ }
+
+ public override void VisitDirective(DirectiveIntermediateNode node)
+ {
+ WriteContentNode(node, node.DirectiveName);
+ }
+
+ public override void VisitDirectiveToken(DirectiveTokenIntermediateNode node)
+ {
+ WriteContentNode(node, node.Content);
+ }
+
+ public override void VisitFieldDeclaration(FieldDeclarationIntermediateNode node)
+ {
+ WriteContentNode(node, string.Join(" ", node.Modifiers), node.FieldType, node.FieldName);
+ }
+
+ public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node)
+ {
+ WriteContentNode(node, node.Prefix, node.Suffix);
+ }
+
+ public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node)
+ {
+ WriteContentNode(node, node.Prefix);
+ }
+
+ public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
+ {
+ WriteContentNode(node, node.Content);
+ }
+
+ public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node)
+ {
+ WriteContentNode(node, string.Join(" ", node.Modifiers), node.ReturnType, node.MethodName);
+ }
+
+ public override void VisitUsingDirective(UsingDirectiveIntermediateNode node)
+ {
+ WriteContentNode(node, node.Content);
+ }
+
+ public override void VisitTagHelper(TagHelperIntermediateNode node)
+ {
+ WriteContentNode(node, node.TagName, string.Format("{0}.{1}", nameof(TagMode), node.TagMode));
+ }
+
+ public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node)
+ {
+ WriteContentNode(node, node.AttributeName, node.BoundAttribute.DisplayName, string.Format("HtmlAttributeValueStyle.{0}", node.AttributeStructure));
+ }
+
+ public override void VisitTagHelperHtmlAttribute(TagHelperHtmlAttributeIntermediateNode node)
+ {
+ WriteContentNode(node, node.AttributeName, string.Format("HtmlAttributeValueStyle.{0}", node.AttributeStructure));
+ }
+
+ public override void VisitExtension(ExtensionIntermediateNode node)
+ {
+ // This will be called for nodes that are internal implementation details of Razor,
+ // like the design time directive nodes.
+ if (node.GetType().Assembly == typeof(RazorCodeDocument).Assembly)
+ {
+ WriteBasicNode(node);
+ }
+ else
+ {
+ throw new InvalidOperationException("Unknown node type: " + node.GetType());
+ }
+ }
+
+ protected void WriteBasicNode(IntermediateNode node)
+ {
+ WriteIndent();
+ WriteName(node);
+ WriteSeparator();
+ WriteSourceRange(node);
+ }
+
+ protected void WriteContentNode(IntermediateNode node, params string[] content)
+ {
+ WriteIndent();
+ WriteName(node);
+ WriteSeparator();
+ WriteSourceRange(node);
+
+ for (var i = 0; i < content.Length; i++)
+ {
+ WriteSeparator();
+ WriteContent(content[i]);
+ }
+ }
+
+ protected void WriteIndent()
+ {
+ for (var i = 0; i < Depth; i++)
+ {
+ for (var j = 0; j < 4; j++)
+ {
+ _writer.Write(' ');
+ }
+ }
+ }
+
+ protected void WriteSeparator()
+ {
+ _writer.Write(" - ");
+ }
+
+ protected void WriteNewLine()
+ {
+ _writer.WriteLine();
+ }
+
+ protected void WriteName(IntermediateNode node)
+ {
+ var typeName = node.GetType().Name;
+ if (typeName.EndsWith("IntermediateNode"))
+ {
+ _writer.Write(typeName.Substring(0, typeName.Length - "IntermediateNode".Length));
+ }
+ else
+ {
+ _writer.Write(typeName);
+ }
+ }
+
+ protected void WriteSourceRange(IntermediateNode node)
+ {
+ if (node.Source != null)
+ {
+ WriteSourceRange(node.Source.Value);
+ }
+ }
+
+ protected void WriteSourceRange(SourceSpan sourceRange)
+ {
+ _writer.Write("(");
+ _writer.Write(sourceRange.AbsoluteIndex);
+ _writer.Write(":");
+ _writer.Write(sourceRange.LineIndex);
+ _writer.Write(",");
+ _writer.Write(sourceRange.CharacterIndex);
+ _writer.Write(" [");
+ _writer.Write(sourceRange.Length);
+ _writer.Write("] ");
+
+ if (sourceRange.FilePath != null)
+ {
+ var fileName = sourceRange.FilePath.Substring(sourceRange.FilePath.LastIndexOf('/') + 1);
+ _writer.Write(fileName);
+ }
+
+ _writer.Write(")");
+ }
+
+ protected void WriteDiagnostics(IntermediateNode node)
+ {
+ if (node.HasDiagnostics)
+ {
+ _writer.Write("| ");
+ for (var i = 0; i < node.Diagnostics.Count; i++)
+ {
+ var diagnostic = node.Diagnostics[i];
+ _writer.Write("{");
+ WriteSourceRange(diagnostic.Span);
+ _writer.Write(": ");
+ _writer.Write(diagnostic.Severity);
+ _writer.Write(" ");
+ _writer.Write(diagnostic.Id);
+ _writer.Write(": ");
+
+ // Purposefully not writing out the entire message to ensure readable IR and because messages
+ // can span multiple lines. Not using string.GetHashCode because we can't have any collisions.
+ using (var md5 = MD5.Create())
+ {
+ var diagnosticMessage = diagnostic.GetMessage();
+ var messageBytes = Encoding.UTF8.GetBytes(diagnosticMessage);
+ var messageHash = md5.ComputeHash(messageBytes);
+ var stringHashBuilder = new StringBuilder();
+
+ for (var j = 0; j < messageHash.Length; j++)
+ {
+ stringHashBuilder.Append(messageHash[j].ToString("x2"));
+ }
+
+ var stringHash = stringHashBuilder.ToString();
+ _writer.Write(stringHash);
+ }
+ _writer.Write("} ");
+ }
+ }
+ }
+
+ protected void WriteContent(string content)
+ {
+ if (content == null)
+ {
+ return;
+ }
+
+ // We explicitly escape newlines in node content so that the IR can be compared line-by-line. The escaped
+ // newline cannot be platform specific so we need to drop the windows \r.
+ // Also, escape our separator so we can search for ` - `to find delimiters.
+ _writer.Write(content.Replace("\r", string.Empty).Replace("\n", "\\n").Replace(" - ", "\\-"));
+ }
+
+ void IExtensionIntermediateNodeVisitor.VisitExtension(ComponentOpenExtensionNode node)
+ {
+ WriteContentNode(node, node.TypeName);
+ }
+
+ void IExtensionIntermediateNodeVisitor.VisitExtension(ComponentAttributeExtensionNode node)
+ {
+ WriteContentNode(node, node.AttributeName, node.PropertyName);
+ }
+
+ void IExtensionIntermediateNodeVisitor.VisitExtension(ComponentBodyExtensionNode node)
+ {
+ WriteBasicNode(node);
+ }
+
+ void IExtensionIntermediateNodeVisitor.VisitExtension(ComponentCloseExtensionNode node)
+ {
+ WriteBasicNode(node);
+ }
+
+ void IExtensionIntermediateNodeVisitor.VisitExtension(RouteAttributeExtensionNode node)
+ {
+ WriteContentNode(node, node.Template);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/RazorDiagnosticSerializer.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/RazorDiagnosticSerializer.cs
new file mode 100644
index 0000000000..bb92350872
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/RazorDiagnosticSerializer.cs
@@ -0,0 +1,13 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorDiagnosticSerializer
+ {
+ public static string Serialize(RazorDiagnostic diagnostic)
+ {
+ return diagnostic.ToString();
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/SourceMappingsSerializer.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/SourceMappingsSerializer.cs
new file mode 100644
index 0000000000..b5b44afa12
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/SourceMappingsSerializer.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Text;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public static class SourceMappingsSerializer
+ {
+ public static string Serialize(RazorCSharpDocument csharpDocument, RazorSourceDocument sourceDocument)
+ {
+ var builder = new StringBuilder();
+ var charBuffer = new char[sourceDocument.Length];
+ sourceDocument.CopyTo(0, charBuffer, 0, sourceDocument.Length);
+ var sourceContent = new string(charBuffer);
+
+ for (var i = 0; i < csharpDocument.SourceMappings.Count; i++)
+ {
+ var sourceMapping = csharpDocument.SourceMappings[i];
+
+ builder.Append("Source Location: ");
+ AppendMappingLocation(builder, sourceMapping.OriginalSpan, sourceContent);
+
+ builder.Append("Generated Location: ");
+ AppendMappingLocation(builder, sourceMapping.GeneratedSpan, csharpDocument.GeneratedCode);
+
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+ private static void AppendMappingLocation(StringBuilder builder, SourceSpan location, string content)
+ {
+ builder
+ .AppendLine(location.ToString())
+ .Append("|");
+
+ for (var i = 0; i < location.Length; i++)
+ {
+ builder.Append(content[location.AbsoluteIndex + i]);
+ }
+
+ builder.AppendLine("|");
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestFile.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestFile.cs
new file mode 100644
index 0000000000..70d5cacd70
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestFile.cs
@@ -0,0 +1,89 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Reflection;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TestFile
+ {
+ private TestFile(string resourceName, Assembly assembly)
+ {
+ Assembly = assembly;
+ ResourceName = Assembly.GetName().Name + "." + resourceName.Replace('/', '.').Replace('\\', '.');
+ }
+
+ public Assembly Assembly { get; }
+
+ public string ResourceName { get; }
+
+ public static TestFile Create(string resourceName, Type type)
+ {
+ return new TestFile(resourceName, type.GetTypeInfo().Assembly);
+ }
+
+ public static TestFile Create(string resourceName, Assembly assembly)
+ {
+ return new TestFile(resourceName, assembly);
+ }
+
+ public Stream OpenRead()
+ {
+ var stream = Assembly.GetManifestResourceStream(ResourceName);
+ if (stream == null)
+ {
+ Assert.True(false, string.Format("Manifest resource: {0} not found", ResourceName));
+ }
+
+ return stream;
+ }
+
+ public bool Exists()
+ {
+ var resourceNames = Assembly.GetManifestResourceNames();
+ foreach (var resourceName in resourceNames)
+ {
+ // Resource names are case-sensitive.
+ if (string.Equals(ResourceName, resourceName, StringComparison.Ordinal))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public string ReadAllText()
+ {
+ using (var reader = new StreamReader(OpenRead()))
+ {
+ // The .Replace() calls normalize line endings, in case you get \n instead of \r\n
+ // since all the unit tests rely on the assumption that the files will have \r\n endings.
+ return reader.ReadToEnd().Replace("\r", "").Replace("\n", "\r\n");
+ }
+ }
+
+ ///
+ /// Saves the file to the specified path.
+ ///
+ public void Save(string filePath)
+ {
+ var directory = Path.GetDirectoryName(filePath);
+ if (!Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ using (var outStream = File.Create(filePath))
+ {
+ using (var inStream = OpenRead())
+ {
+ inStream.CopyTo(outStream);
+ }
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestProject.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestProject.cs
new file mode 100644
index 0000000000..dd0015aac0
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/Razor/TestProject.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public static class TestProject
+ {
+ public static string GetProjectDirectory(Type type)
+ {
+ var solutionDir = GetSolutionRootDirectory("Blazor");
+
+ var assemblyName = type.Assembly.GetName().Name;
+ var projectDirectory = Path.Combine(solutionDir, "test", assemblyName);
+ if (!Directory.Exists(projectDirectory))
+ {
+ throw new InvalidOperationException(
+$@"Could not locate project directory for type {type.FullName}.
+Directory probe path: {projectDirectory}.");
+ }
+
+ return projectDirectory;
+ }
+
+ public static string GetSolutionRootDirectory(string solution)
+ {
+ var applicationBasePath = AppContext.BaseDirectory;
+ var directoryInfo = new DirectoryInfo(applicationBasePath);
+
+ do
+ {
+ var projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, $"{solution}.sln"));
+ if (projectFileInfo.Exists)
+ {
+ return projectFileInfo.DirectoryName;
+ }
+
+ directoryInfo = directoryInfo.Parent;
+ }
+ while (directoryInfo.Parent != null);
+
+ throw new Exception($"Solution file {solution}.sln could not be found in {applicationBasePath} or its parent directories.");
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorBaselineIntegrationTestBase.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorBaselineIntegrationTestBase.cs
new file mode 100644
index 0000000000..1eda107ac9
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorBaselineIntegrationTestBase.cs
@@ -0,0 +1,179 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Microsoft.AspNetCore.Razor.Language;
+using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
+using Xunit;
+using Xunit.Sdk;
+
+namespace Microsoft.AspNetCore.Blazor.Build.Test
+{
+ [IntializeTestFile]
+ public abstract class RazorBaselineIntegrationTestBase : RazorIntegrationTestBase
+ {
+ private static readonly AsyncLocal _directoryPath = new AsyncLocal();
+
+ protected RazorBaselineIntegrationTestBase()
+ {
+ TestProjectRoot = TestProject.GetProjectDirectory(GetType());
+ }
+
+ // Used by the test framework to set the directory for test files.
+ public static string DirectoryPath
+ {
+ get { return _directoryPath.Value; }
+ set { _directoryPath.Value = value; }
+ }
+
+#if GENERATE_BASELINES
+ protected bool GenerateBaselines { get; set; } = true;
+#else
+ protected bool GenerateBaselines { get; set; } = false;
+#endif
+
+ protected string TestProjectRoot { get; }
+
+ // For consistent line endings because the character counts are going to be recorded in files.
+ internal override string LineEnding => "\r\n";
+
+ internal override bool NormalizeSourceLineEndings => true;
+
+ internal override string PathSeparator => "\\";
+
+ // Force consistent paths since they are going to be recorded in files.
+ internal override string WorkingDirectory => ArbitraryWindowsPath;
+
+ protected void AssertDocumentNodeMatchesBaseline(RazorCodeDocument codeDocument)
+ {
+ var document = codeDocument.GetDocumentIntermediateNode();
+ var baselineFilePath = GetBaselineFilePath(codeDocument, ".ir.txt");
+
+ if (GenerateBaselines)
+ {
+ var baselineFullPath = Path.Combine(TestProjectRoot, baselineFilePath);
+ Directory.CreateDirectory(Path.GetDirectoryName(baselineFullPath));
+ File.WriteAllText(baselineFullPath, IntermediateNodeSerializer.Serialize(document));
+
+ return;
+ }
+
+ var irFile = TestFile.Create(baselineFilePath, GetType().Assembly);
+ if (!irFile.Exists())
+ {
+ throw new XunitException($"The resource {baselineFilePath} was not found.");
+ }
+
+ // Normalize newlines by splitting into an array.
+ var baseline = irFile.ReadAllText().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+ IntermediateNodeVerifier.Verify(document, baseline);
+ }
+
+ protected void AssertCSharpDocumentMatchesBaseline(RazorCodeDocument codeDocument)
+ {
+ var document = codeDocument.GetCSharpDocument();
+
+ var baselineFilePath = GetBaselineFilePath(codeDocument, ".codegen.cs");
+ var baselineDiagnosticsFilePath = GetBaselineFilePath(codeDocument, ".diagnostics.txt");
+ var baselineMappingsFilePath = GetBaselineFilePath(codeDocument, ".mappings.txt");
+
+ var serializedMappings = SourceMappingsSerializer.Serialize(document, codeDocument.Source);
+
+ if (GenerateBaselines)
+ {
+ var baselineFullPath = Path.Combine(TestProjectRoot, baselineFilePath);
+ Directory.CreateDirectory(Path.GetDirectoryName(baselineFullPath));
+ File.WriteAllText(baselineFullPath, document.GeneratedCode);
+
+ var baselineDiagnosticsFullPath = Path.Combine(TestProjectRoot, baselineDiagnosticsFilePath);
+ var lines = document.Diagnostics.Select(RazorDiagnosticSerializer.Serialize).ToArray();
+ if (lines.Any())
+ {
+ File.WriteAllLines(baselineDiagnosticsFullPath, lines);
+ }
+ else if (File.Exists(baselineDiagnosticsFullPath))
+ {
+ File.Delete(baselineDiagnosticsFullPath);
+ }
+
+ var baselineMappingsFullPath = Path.Combine(TestProjectRoot, baselineMappingsFilePath);
+ var text = SourceMappingsSerializer.Serialize(document, codeDocument.Source);
+ if (!string.IsNullOrEmpty(text))
+ {
+ File.WriteAllText(baselineMappingsFullPath, text);
+ }
+ else if (File.Exists(baselineMappingsFullPath))
+ {
+ File.Delete(baselineMappingsFullPath);
+ }
+
+ return;
+ }
+
+ var codegenFile = TestFile.Create(baselineFilePath, GetType().Assembly);
+ if (!codegenFile.Exists())
+ {
+ throw new XunitException($"The resource {baselineFilePath} was not found.");
+ }
+
+ var baseline = codegenFile.ReadAllText();
+
+ // Normalize newlines to match those in the baseline.
+ var actualCode = document.GeneratedCode.Replace("\r", "").Replace("\n", "\r\n");
+ Assert.Equal(baseline, actualCode);
+
+ var baselineDiagnostics = string.Empty;
+ var diagnosticsFile = TestFile.Create(baselineDiagnosticsFilePath, GetType().Assembly);
+ if (diagnosticsFile.Exists())
+ {
+ baselineDiagnostics = diagnosticsFile.ReadAllText();
+ }
+
+ var actualDiagnostics = string.Concat(document.Diagnostics.Select(d => RazorDiagnosticSerializer.Serialize(d) + "\r\n"));
+ Assert.Equal(baselineDiagnostics, actualDiagnostics);
+
+ var baselineMappings = string.Empty;
+ var mappingsFile = TestFile.Create(baselineMappingsFilePath, GetType().Assembly);
+ if (mappingsFile.Exists())
+ {
+ baselineMappings = mappingsFile.ReadAllText();
+ }
+
+ var actualMappings = SourceMappingsSerializer.Serialize(document, codeDocument.Source);
+ actualMappings = actualMappings.Replace("\r", "").Replace("\n", "\r\n");
+ Assert.Equal(baselineMappings, actualMappings);
+ }
+
+ private string GetBaselineFilePath(RazorCodeDocument codeDocument, string extension)
+ {
+ if (codeDocument == null)
+ {
+ throw new ArgumentNullException(nameof(codeDocument));
+ }
+
+ if (extension == null)
+ {
+ throw new ArgumentNullException(nameof(extension));
+ }
+
+ var lastSlash = codeDocument.Source.FilePath.LastIndexOfAny(new []{ '/', '\\' });
+ var fileName = lastSlash == -1 ? null : codeDocument.Source.FilePath.Substring(lastSlash + 1);
+ if (string.IsNullOrEmpty(fileName))
+ {
+ var message = "Integration tests require a filename";
+ throw new InvalidOperationException(message);
+ }
+
+ if (DirectoryPath == null)
+ {
+ var message = $"{nameof(AssertDocumentNodeMatchesBaseline)} should only be called from an integration test..";
+ throw new InvalidOperationException(message);
+ }
+
+ return Path.Combine(DirectoryPath, Path.ChangeExtension(fileName, extension));
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorIntegrationTestBase.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorIntegrationTestBase.cs
index 975d7d97c5..1d1d30d5aa 100644
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorIntegrationTestBase.cs
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorIntegrationTestBase.cs
@@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Blazor.Rendering;
using Microsoft.AspNetCore.Blazor.RenderTree;
using Microsoft.AspNetCore.Blazor.Test.Helpers;
using Microsoft.AspNetCore.Razor.Language;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;
@@ -60,11 +61,11 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
Configuration = BlazorExtensionInitializer.DefaultConfiguration;
FileSystem = new VirtualRazorProjectFileSystem();
+ PathSeparator = Path.DirectorySeparatorChar.ToString();
WorkingDirectory = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ArbitraryWindowsPath : ArbitraryMacLinuxPath;
DefaultBaseNamespace = "Test"; // Matches the default working directory
DefaultFileName = "TestComponent.cshtml";
-
}
internal List AdditionalRazorItems { get; }
@@ -81,6 +82,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
internal virtual VirtualRazorProjectFileSystem FileSystem { get; }
+ // Used to force a specific style of line-endings for testing. This matters
+ // for the baseline tests that exercise line mappings. Even though we normalize
+ // newlines for testing, the difference between platforms affects the data through
+ // the *count* of characters written.
+ internal virtual string LineEnding { get; }
+
+ internal virtual string PathSeparator { get; }
+
+ internal virtual bool NormalizeSourceLineEndings { get; }
+
internal virtual bool UseTwoPhaseCompilation { get; }
internal virtual string WorkingDirectory { get; }
@@ -92,6 +103,11 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Turn off checksums, we're testing code generation.
b.Features.Add(new SuppressChecksum());
+ if (LineEnding != null)
+ {
+ b.Phases.Insert(0, new ForceLineEndingPhase(LineEnding));
+ }
+
BlazorExtensionInitializer.Register(b);
b.Features.Add(new CompilationTagHelperFeature());
@@ -102,20 +118,27 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
});
}
- internal RazorProjectItem CreateProjectItem(string chtmlRelativePath, string cshtmlContent)
+ internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent)
{
+ var fullPath = WorkingDirectory + PathSeparator + cshtmlRelativePath;
+
// FilePaths in Razor are **always** are of the form '/a/b/c.cshtml'
- var filePath = chtmlRelativePath.Replace('\\', '/');
+ var filePath = cshtmlRelativePath.Replace('\\', '/');
if (!filePath.StartsWith('/'))
{
filePath = '/' + filePath;
}
+ if (NormalizeSourceLineEndings)
+ {
+ cshtmlContent = cshtmlContent.Replace("\r", "").Replace("\n", LineEnding);
+ }
+
return new VirtualProjectItem(
WorkingDirectory,
filePath,
- Path.Combine(WorkingDirectory, chtmlRelativePath),
- chtmlRelativePath,
+ fullPath,
+ cshtmlRelativePath,
Encoding.UTF8.GetBytes(cshtmlContent.TrimStart()));
}
@@ -400,5 +423,22 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
options.SuppressChecksum = true;
}
}
+
+ private class ForceLineEndingPhase : RazorEnginePhaseBase
+ {
+ public ForceLineEndingPhase(string lineEnding)
+ {
+ LineEnding = lineEnding;
+ }
+
+ public string LineEnding { get; }
+
+ protected override void ExecuteCore(RazorCodeDocument codeDocument)
+ {
+ var field = typeof(CodeRenderingContext).GetField("NewLineString", BindingFlags.Static | BindingFlags.NonPublic);
+ var key = field.GetValue(null);
+ codeDocument.Items[key] = LineEnding;
+ }
+ }
}
}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationRazorIntegrationTest.cs
deleted file mode 100644
index b6d346e3cc..0000000000
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationRazorIntegrationTest.cs
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.CodeAnalysis.CSharp;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Blazor.Build.Test
-{
- public class RuntimeCodeGenerationRazorIntegrationTest : RazorIntegrationTestBase
- {
- internal override bool UseTwoPhaseCompilation => true;
-
- [Fact]
- public void CodeGeneration_ChildComponent_Simple()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithParameters()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class SomeType
- {
- }
-
- public class MyComponent : BlazorComponent
- {
- public int IntProperty { get; set; }
- public bool BoolProperty { get; set; }
- public string StringProperty { get; set; }
- public SomeType ObjectProperty { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""IntProperty"", 123);
- builder.AddAttribute(2, ""BoolProperty"", true);
- builder.AddAttribute(3, ""StringProperty"", ""My string"");
- builder.AddAttribute(4, ""ObjectProperty"", new SomeType());
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithExplicitStringParameter()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public string StringProperty { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""StringProperty"", 42.ToString());
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithNonPropertyAttributes()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""some-attribute"", ""foo"");
- builder.AddAttribute(2, ""another-attribute"", 43.ToString());
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithLambdaEventHandler()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using System;
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public UIEventHandler OnClick { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
- { Increment(); })""/>
-
-@functions {
- private int counter;
- private void Increment() {
- counter++;
- }
-}");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""OnClick"", new Microsoft.AspNetCore.Blazor.UIEventHandler(e => { Increment(); }));
- builder.CloseComponent();
- builder.AddContent(2, ""\n\n"");
- }
- #pragma warning restore 1998
-#line 4 ""x:\dir\subdir\Test\TestComponent.cshtml""
-
- private int counter;
- private void Increment() {
- counter++;
- }
-
-#line default
-#line hidden
- }
-}
-#pragma warning restore 1591
-
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithExplicitEventHandler()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using System;
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public UIEventHandler OnClick { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-@using Microsoft.AspNetCore.Blazor
-
-
-@functions {
- private int counter;
- private void Increment(UIEventArgs e) {
- counter++;
- }
-}");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Blazor;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""OnClick"", new Microsoft.AspNetCore.Blazor.UIEventHandler(Increment));
- builder.CloseComponent();
- builder.AddContent(2, ""\n\n"");
- }
- #pragma warning restore 1998
-#line 5 ""x:\dir\subdir\Test\TestComponent.cshtml""
-
- private int counter;
- private void Increment(UIEventArgs e) {
- counter++;
- }
-
-#line default
-#line hidden
- }
-}
-#pragma warning restore 1591
-
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithChildContent()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor;
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- public string MyAttr { get; set; }
-
- public RenderFragment ChildContent { get; set; }
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-Some textNested text");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.AddAttribute(1, ""MyAttr"", ""abc"");
- builder.AddAttribute(2, ""ChildContent"", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
- builder2.AddContent(3, ""Some text"");
- builder2.OpenElement(4, ""some-child"");
- builder2.AddAttribute(5, ""a"", ""1"");
- builder2.AddContent(6, ""Nested text"");
- builder2.CloseElement();
- }
- ));
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
-
- [Fact]
- public void CodeGeneration_ChildComponent_WithPageDirective()
- {
- // Arrange
- AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
-using Microsoft.AspNetCore.Blazor.Components;
-
-namespace Test
-{
- public class MyComponent : BlazorComponent
- {
- }
-}
-"));
-
- // Act
- var generated = CompileToCSharp(@"
-@addTagHelper *, TestAssembly
-@page ""/MyPage""
-@page ""/AnotherRoute/{id}""
-");
-
- // Assert
- CompileToAssembly(generated);
-
- AssertSourceEquals(@"
-//
-#pragma warning disable 1591
-namespace Test
-{
- #line hidden
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- [Microsoft.AspNetCore.Blazor.Components.RouteAttribute(""/MyPage"")]
- [Microsoft.AspNetCore.Blazor.Components.RouteAttribute(""/AnotherRoute/{id}"")]
- public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
- {
- #pragma warning disable 1998
- protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
- {
- base.BuildRenderTree(builder);
-
- builder.OpenComponent(0);
- builder.CloseComponent();
- }
- #pragma warning restore 1998
- }
-}
-#pragma warning restore 1591
-", generated);
- }
- }
-}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs
new file mode 100644
index 0000000000..4fcb674424
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs
@@ -0,0 +1,262 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.CodeAnalysis.CSharp;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Blazor.Build.Test
+{
+ public class RuntimeCodeGenerationTest : RazorBaselineIntegrationTestBase
+ {
+ internal override bool UseTwoPhaseCompilation => true;
+
+ [Fact]
+ public void ChildComponent_Simple()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithParameters()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class SomeType
+ {
+ }
+
+ public class MyComponent : BlazorComponent
+ {
+ public int IntProperty { get; set; }
+ public bool BoolProperty { get; set; }
+ public string StringProperty { get; set; }
+ public SomeType ObjectProperty { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithExplicitStringParameter()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public string StringProperty { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithNonPropertyAttributes()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+
+ [Fact]
+ public void ChildComponent_WithLambdaEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public UIEventHandler OnClick { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+ { Increment(); })""/>
+
+@functions {
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithExplicitEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public UIEventHandler OnClick { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+@using Microsoft.AspNetCore.Blazor
+
+
+@functions {
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithChildContent()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ public string MyAttr { get; set; }
+
+ public RenderFragment ChildContent { get; set; }
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+Some textNested text");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
+ [Fact]
+ public void ChildComponent_WithPageDirective()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@"
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class MyComponent : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+@page ""/MyPage""
+@page ""/AnotherRoute/{id}""
+");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs
new file mode 100644
index 0000000000..8d0d5acaf9
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs
@@ -0,0 +1,34 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt
new file mode 100644
index 0000000000..f0b4051ba4
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt
@@ -0,0 +1,36 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (31:1,0 [91] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.StartTagAndEndTag
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - MyAttr - MyAttr
+ HtmlContent - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - abc
+ ComponentBodyExtensionNode -
+ HtmlContent - (57:1,26 [51] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (57:1,26 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Some text
+ IntermediateToken - (66:1,35 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
+ IntermediateToken - (84:1,53 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Nested text
+ IntermediateToken - (95:1,64 [13] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.mappings.txt
new file mode 100644
index 0000000000..668ac0d88d
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (468:14,38 [15] )
+|*, TestAssembly|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..74c44a2766
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Blazor;
+
+#line default
+#line hidden
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o = new Microsoft.AspNetCore.Blazor.UIEventHandler(
+#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
+ Increment
+
+#line default
+#line hidden
+ );
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+#line 5 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..6ff5148994
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt
@@ -0,0 +1,36 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ UsingDirective - (32:1,1 [33] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ HtmlContent - (65:1,34 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (65:1,34 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (67:2,0 [35] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (89:2,22 [10] x:\dir\subdir\Test\TestComponent.cshtml) - OnClick - OnClick
+ CSharpExpression - (90:2,23 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (90:2,23 [9] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Increment
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
+ HtmlContent - (102:2,35 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (102:2,35 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private int counter;\n private void Increment(UIEventArgs e) {\n counter++;\n }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..6eef624b0a
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,30 @@
+Source Location: (32:1,1 [33] x:\dir\subdir\Test\TestComponent.cshtml)
+|using Microsoft.AspNetCore.Blazor|
+Generated Location: (257:10,0 [33] )
+|using Microsoft.AspNetCore.Blazor|
+
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (586:19,38 [15] )
+|*, TestAssembly|
+
+Source Location: (90:2,23 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+|Increment|
+Generated Location: (1154:33,23 [9] )
+|Increment|
+
+Source Location: (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+|
+Generated Location: (1471:44,12 [100] )
+|
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs
new file mode 100644
index 0000000000..a0420ed317
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs
@@ -0,0 +1,41 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o =
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+ 42.ToString()
+
+#line default
+#line hidden
+ ;
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt
new file mode 100644
index 0000000000..0380ac1501
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt
@@ -0,0 +1,29 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (31:1,0 [49] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (60:1,29 [16] x:\dir\subdir\Test\TestComponent.cshtml) - StringProperty - StringProperty
+ CSharpExpression - (62:1,31 [13] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (62:1,31 [13] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 42.ToString()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.mappings.txt
new file mode 100644
index 0000000000..9a791ad2fc
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (468:14,38 [15] )
+|*, TestAssembly|
+
+Source Location: (62:1,31 [13] x:\dir\subdir\Test\TestComponent.cshtml)
+|42.ToString()|
+Generated Location: (997:28,31 [13] )
+|42.ToString()|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..d45fa03550
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,50 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o = new Microsoft.AspNetCore.Blazor.UIEventHandler(
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+ (e) => { Increment(); }
+
+#line default
+#line hidden
+ );
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..ca734b9c0c
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt
@@ -0,0 +1,33 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (31:1,0 [51] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (53:1,22 [26] x:\dir\subdir\Test\TestComponent.cshtml) - OnClick - OnClick
+ CSharpExpression - (54:1,23 [25] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (55:1,24 [23] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - (e) => { Increment(); }
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
+ HtmlContent - (82:1,51 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (82:1,51 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (98:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (98:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private int counter;\n private void Increment() {\n counter++;\n }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..fa813c7e57
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,25 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (468:14,38 [15] )
+|*, TestAssembly|
+
+Source Location: (55:1,24 [23] x:\dir\subdir\Test\TestComponent.cshtml)
+|(e) => { Increment(); }|
+Generated Location: (1037:28,24 [23] )
+|(e) => { Increment(); }|
+
+Source Location: (98:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+|
+Generated Location: (1368:39,12 [87] )
+|
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs
new file mode 100644
index 0000000000..1d555000f4
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs
@@ -0,0 +1,41 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o =
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+ 43.ToString()
+
+#line default
+#line hidden
+ ;
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt
new file mode 100644
index 0000000000..c363ad02c7
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt
@@ -0,0 +1,32 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (31:1,0 [72] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - - some-attribute -
+ HtmlContent - (60:1,29 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (60:1,29 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - foo
+ ComponentAttributeExtensionNode - - another-attribute -
+ CSharpExpression - (84:1,53 [16] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (86:1,55 [13] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 43.ToString()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.mappings.txt
new file mode 100644
index 0000000000..8a335fba9a
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (468:14,38 [15] )
+|*, TestAssembly|
+
+Source Location: (86:1,55 [13] x:\dir\subdir\Test\TestComponent.cshtml)
+|43.ToString()|
+Generated Location: (1021:28,55 [13] )
+|43.ToString()|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs
new file mode 100644
index 0000000000..41b46504de
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs
@@ -0,0 +1,55 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o =
+#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
+ 123
+
+#line default
+#line hidden
+ ;
+ __o =
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+ true
+
+#line default
+#line hidden
+ ;
+ __o =
+#line 6 "x:\dir\subdir\Test\TestComponent.cshtml"
+ new SomeType()
+
+#line default
+#line hidden
+ ;
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt
new file mode 100644
index 0000000000..19fe768a08
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt
@@ -0,0 +1,35 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ TagHelper - (31:1,0 [132] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (63:2,17 [3] x:\dir\subdir\Test\TestComponent.cshtml) - IntProperty - IntProperty
+ IntermediateToken - (63:2,17 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
+ ComponentAttributeExtensionNode - (87:3,18 [4] x:\dir\subdir\Test\TestComponent.cshtml) - BoolProperty - BoolProperty
+ IntermediateToken - (87:3,18 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true
+ ComponentAttributeExtensionNode - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml) - StringProperty - StringProperty
+ HtmlContent - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - My string
+ ComponentAttributeExtensionNode - (146:5,20 [14] x:\dir\subdir\Test\TestComponent.cshtml) - ObjectProperty - ObjectProperty
+ IntermediateToken - (146:5,20 [14] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - new SomeType()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.mappings.txt
new file mode 100644
index 0000000000..124512fd1d
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.mappings.txt
@@ -0,0 +1,20 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (468:14,38 [15] )
+|*, TestAssembly|
+
+Source Location: (63:2,17 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|123|
+Generated Location: (983:28,17 [3] )
+|123|
+
+Source Location: (87:3,18 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+|true|
+Generated Location: (1123:35,18 [4] )
+|true|
+
+Source Location: (146:5,20 [14] x:\dir\subdir\Test\TestComponent.cshtml)
+|new SomeType()|
+Generated Location: (1266:42,20 [14] )
+|new SomeType()|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.codegen.cs
new file mode 100644
index 0000000000..c610a9fcd4
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.codegen.cs
@@ -0,0 +1,22 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.ir.txt
new file mode 100644
index 0000000000..40d2d35287
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_Simple/TestComponent.ir.txt
@@ -0,0 +1,14 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [15] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs
new file mode 100644
index 0000000000..cc5be25397
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs
@@ -0,0 +1,31 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "MyAttr", "abc");
+ builder.AddAttribute(2, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ builder2.AddContent(3, "Some text");
+ builder2.OpenElement(4, "some-child");
+ builder2.AddAttribute(5, "a", "1");
+ builder2.AddContent(6, "Nested text");
+ builder2.CloseElement();
+ }
+ ));
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt
new file mode 100644
index 0000000000..a63d748600
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt
@@ -0,0 +1,24 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [91] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.StartTagAndEndTag
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - MyAttr - MyAttr
+ HtmlContent - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (52:1,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - abc
+ ComponentBodyExtensionNode -
+ HtmlContent - (57:1,26 [51] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (57:1,26 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Some text
+ IntermediateToken - (66:1,35 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
+ IntermediateToken - (84:1,53 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Nested text
+ IntermediateToken - (95:1,64 [13] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..39f6e9449f
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,34 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Blazor;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "OnClick", new Microsoft.AspNetCore.Blazor.UIEventHandler(Increment));
+ builder.CloseComponent();
+ builder.AddContent(2, "\n\n");
+ }
+ #pragma warning restore 1998
+#line 5 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..5eed086f14
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.ir.txt
@@ -0,0 +1,22 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ UsingDirective - (32:1,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (67:2,0 [35] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (89:2,22 [10] x:\dir\subdir\Test\TestComponent.cshtml) - OnClick - OnClick
+ CSharpExpression - (90:2,23 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (90:2,23 [9] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Increment
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
+ HtmlContent - (102:2,35 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (102:2,35 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private int counter;\n private void Increment(UIEventArgs e) {\n counter++;\n }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..49ff888e0e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (118:4,12 [100] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+|
+Generated Location: (910:23,12 [100] )
+|
+ private int counter;
+ private void Increment(UIEventArgs e) {
+ counter++;
+ }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs
new file mode 100644
index 0000000000..832e0fa0cc
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.codegen.cs
@@ -0,0 +1,23 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "StringProperty", 42.ToString());
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt
new file mode 100644
index 0000000000..e7f36263ff
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithExplicitStringParameter/TestComponent.ir.txt
@@ -0,0 +1,17 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [49] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (60:1,29 [16] x:\dir\subdir\Test\TestComponent.cshtml) - StringProperty - StringProperty
+ CSharpExpression - (62:1,31 [13] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (62:1,31 [13] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 42.ToString()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..6e6a31c77d
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,33 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "OnClick", new Microsoft.AspNetCore.Blazor.UIEventHandler(e => { Increment(); }));
+ builder.CloseComponent();
+ builder.AddContent(2, "\n\n");
+ }
+ #pragma warning restore 1998
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..3c8ad18a83
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.ir.txt
@@ -0,0 +1,21 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [49] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (53:1,22 [24] x:\dir\subdir\Test\TestComponent.cshtml) - OnClick - OnClick
+ CSharpExpression - (54:1,23 [23] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (55:1,24 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - e => { Increment(); }
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
+ HtmlContent - (80:1,49 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (80:1,49 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (96:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (96:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private int counter;\n private void Increment() {\n counter++;\n }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..2747022f59
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithLambdaEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (96:3,12 [87] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+|
+Generated Location: (882:22,12 [87] )
+|
+ private int counter;
+ private void Increment() {
+ counter++;
+ }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs
new file mode 100644
index 0000000000..395aad9b1a
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.codegen.cs
@@ -0,0 +1,24 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "some-attribute", "foo");
+ builder.AddAttribute(2, "another-attribute", 43.ToString());
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt
new file mode 100644
index 0000000000..cab424d587
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithNonPropertyAttributes/TestComponent.ir.txt
@@ -0,0 +1,20 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [72] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - - some-attribute -
+ HtmlContent - (60:1,29 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (60:1,29 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - foo
+ ComponentAttributeExtensionNode - - another-attribute -
+ CSharpExpression - (84:1,53 [16] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (86:1,55 [13] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 43.ToString()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.codegen.cs
new file mode 100644
index 0000000000..127a8205c1
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.codegen.cs
@@ -0,0 +1,24 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ [Microsoft.AspNetCore.Blazor.Components.RouteAttribute("/MyPage")]
+ [Microsoft.AspNetCore.Blazor.Components.RouteAttribute("/AnotherRoute/{id}")]
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.ir.txt
new file mode 100644
index 0000000000..fa36faa85a
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithPageDirective/TestComponent.ir.txt
@@ -0,0 +1,16 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ RouteAttributeExtensionNode - - /MyPage
+ RouteAttributeExtensionNode - - /AnotherRoute/{id}
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (76:3,0 [15] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs
new file mode 100644
index 0000000000..42c7a8f06d
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.codegen.cs
@@ -0,0 +1,26 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "IntProperty", 123);
+ builder.AddAttribute(2, "BoolProperty", true);
+ builder.AddAttribute(3, "StringProperty", "My string");
+ builder.AddAttribute(4, "ObjectProperty", new SomeType());
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt
new file mode 100644
index 0000000000..d48829d55e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithParameters/TestComponent.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ TagHelper - (31:1,0 [132] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - TagMode.SelfClosing
+ ComponentOpenExtensionNode - - Test.MyComponent
+ ComponentAttributeExtensionNode - (63:2,17 [3] x:\dir\subdir\Test\TestComponent.cshtml) - IntProperty - IntProperty
+ IntermediateToken - (63:2,17 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
+ ComponentAttributeExtensionNode - (87:3,18 [4] x:\dir\subdir\Test\TestComponent.cshtml) - BoolProperty - BoolProperty
+ IntermediateToken - (87:3,18 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true
+ ComponentAttributeExtensionNode - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml) - StringProperty - StringProperty
+ HtmlContent - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (114:4,20 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - My string
+ ComponentAttributeExtensionNode - (146:5,20 [14] x:\dir\subdir\Test\TestComponent.cshtml) - ObjectProperty - ObjectProperty
+ IntermediateToken - (146:5,20 [14] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - new SomeType()
+ ComponentBodyExtensionNode -
+ ComponentCloseExtensionNode -