Razor compiler emit CSS scope attributes (#23703)

This commit is contained in:
Steve Sanderson 2020-07-13 17:27:27 +01:00 committed by GitHub
parent fae3dd12ae
commit 90b697f92e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 940 additions and 44 deletions

View File

@ -407,6 +407,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
{
public RenderTreeBuilder() { }
public void AddAttribute(int sequence, in Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame frame) { }
public void AddAttribute(int sequence, string name) { }
public void AddAttribute(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback value) { }
public void AddAttribute(int sequence, string name, bool value) { }
public void AddAttribute(int sequence, string name, System.MulticastDelegate? value) { }

View File

@ -157,6 +157,29 @@ namespace Microsoft.AspNetCore.Components.Rendering
public void AddContent(int sequence, object? textContent)
=> AddContent(sequence, textContent?.ToString());
/// <summary>
/// <para>
/// Appends a frame representing a bool-valued attribute with value 'true'.
/// </para>
/// <para>
/// The attribute is associated with the most recently added element.
/// </para>
/// </summary>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="name">The name of the attribute.</param>
public void AddAttribute(int sequence, string name)
{
ProfilingStart();
if (_lastNonAttributeFrameType != RenderTreeFrameType.Element)
{
throw new InvalidOperationException($"Valueless attributes may only be added immediately after frames of type {RenderTreeFrameType.Element}");
}
Append(RenderTreeFrame.Attribute(sequence, name, BoxedTrue));
ProfilingEnd();
}
/// <summary>
/// <para>
/// Appends a frame representing a bool-valued attribute.

View File

@ -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;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Components
{
internal class ComponentCssScopePass : ComponentIntermediateNodePassBase, IRazorOptimizationPass
{
// Runs after components/bind, since it's preferable for the auto-generated attribute to appear later
// in the DOM than developer-written ones
public override int Order => 110;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (!IsComponentDocument(documentNode))
{
return;
}
var cssScope = codeDocument.GetCssScope();
if (string.IsNullOrEmpty(cssScope))
{
return;
}
var nodes = documentNode.FindDescendantNodes<MarkupElementIntermediateNode>();
for (var i = 0; i < nodes.Count; i++)
{
ProcessElement(nodes[i], cssScope);
}
}
private void ProcessElement(MarkupElementIntermediateNode node, string cssScope)
{
// Add a minimized attribute whose name is simply the CSS scope
node.Children.Add(new HtmlAttributeIntermediateNode
{
AttributeName = cssScope,
Prefix = cssScope,
Suffix = string.Empty,
});
}
}
}

View File

@ -316,8 +316,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
.WriteStartMethodInvocation($"{_scopeStack.BuilderVarName}.{nameof(ComponentsApi.RenderTreeBuilder.AddAttribute)}")
.Write("-1")
.WriteParameterSeparator()
.WriteStringLiteral(key)
.WriteParameterSeparator();
.WriteStringLiteral(key);
}
protected override void BeginWriteAttribute(CodeRenderingContext context, IntermediateNode expression)
@ -341,8 +340,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
context.CodeWriter.Write(tokens[i].Content);
}
context.CodeWriter.WriteParameterSeparator();
}
public override void WriteComponent(CodeRenderingContext context, ComponentIntermediateNode node)
@ -731,6 +728,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
// OR
// __builder.AddAttribute(1, "ChildContent", (RenderFragment<Person>)((person) => (__builder73) => { ... }));
BeginWriteAttribute(context, node.AttributeName);
context.CodeWriter.WriteParameterSeparator();
context.CodeWriter.Write($"({node.TypeName})(");
WriteComponentChildContentInnards(context, node);

View File

@ -673,6 +673,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
// OR
// _builder.AddAttribute(1, "ChildContent", (RenderFragment<Person>)((person) => (__builder73) => { ... }));
BeginWriteAttribute(context, node.AttributeName);
context.CodeWriter.WriteParameterSeparator();
context.CodeWriter.Write($"({node.TypeName})(");
WriteComponentChildContentInnards(context, node);
@ -851,14 +852,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
private void WriteAttribute(CodeRenderingContext context, string key, IList<IntermediateToken> value)
{
BeginWriteAttribute(context, key);
WriteAttributeValue(context, value);
if (value.Count > 0)
{
context.CodeWriter.WriteParameterSeparator();
WriteAttributeValue(context, value);
}
context.CodeWriter.WriteEndMethodInvocation();
}
private void WriteAttribute(CodeRenderingContext context, IntermediateNode nameExpression, IList<IntermediateToken> value)
{
BeginWriteAttribute(context, nameExpression);
WriteAttributeValue(context, value);
if (value.Count > 0)
{
context.CodeWriter.WriteParameterSeparator();
WriteAttributeValue(context, value);
}
context.CodeWriter.WriteEndMethodInvocation();
}
@ -868,8 +877,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
.WriteStartMethodInvocation($"{_scopeStack.BuilderVarName}.{ComponentsApi.RenderTreeBuilder.AddAttribute}")
.Write((_sourceSequence++).ToString())
.WriteParameterSeparator()
.WriteStringLiteral(key)
.WriteParameterSeparator();
.WriteStringLiteral(key);
}
protected override void BeginWriteAttribute(CodeRenderingContext context, IntermediateNode nameExpression)
@ -883,8 +891,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
WriteCSharpToken(context, tokens[i]);
}
context.CodeWriter.WriteParameterSeparator();
}
private static string GetHtmlContent(HtmlContentIntermediateNode node)
@ -988,8 +994,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
}
else
{
// Minimized attributes always map to 'true'
writer.Write("true");
throw new InvalidOperationException("Found attribute whose value is neither HTML nor CSharp");
}
}

View File

@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Razor.Language
}
var importSourceDocuments = GetImportSourceDocuments(importItems);
return CreateCodeDocumentCore(sourceDocument, projectItem.FileKind, importSourceDocuments, tagHelpers: null, configureParser, configureCodeGeneration);
return CreateCodeDocumentCore(sourceDocument, projectItem.FileKind, importSourceDocuments, tagHelpers: null, configureParser, configureCodeGeneration, cssScope: projectItem.CssScope);
}
protected internal RazorCodeDocument CreateCodeDocumentCore(
@ -94,7 +94,8 @@ namespace Microsoft.AspNetCore.Razor.Language
IReadOnlyList<RazorSourceDocument> importSourceDocuments = null,
IReadOnlyList<TagHelperDescriptor> tagHelpers = null,
Action<RazorParserOptionsBuilder> configureParser = null,
Action<RazorCodeGenerationOptionsBuilder> configureCodeGeneration = null)
Action<RazorCodeGenerationOptionsBuilder> configureCodeGeneration = null,
string cssScope = null)
{
if (sourceDocument == null)
{
@ -122,6 +123,11 @@ namespace Microsoft.AspNetCore.Razor.Language
codeDocument.SetFileKind(fileKind);
}
if (cssScope != null)
{
codeDocument.SetCssScope(cssScope);
}
return codeDocument;
}

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, fileKind: null, file);
return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, fileKind: null, file, cssScope: null);
});
}
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, fileKind, new FileInfo(absolutePath));
return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, fileKind, new FileInfo(absolutePath), cssScope: null);
}
[Obsolete("Use GetItem(string path, string fileKind) instead.")]

View File

@ -17,13 +17,15 @@ namespace Microsoft.AspNetCore.Razor.Language
/// <param name="filePath">The path.</param>
/// <param name="fileKind">The file kind. If null, the document kind will be inferred from the file extension.</param>
/// <param name="file">The <see cref="FileInfo"/>.</param>
public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, string fileKind, FileInfo file)
/// <param name="cssScope">A scope identifier that will be used on elements in the generated class, or null.</param>
public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, string fileKind, FileInfo file, string cssScope)
{
BasePath = basePath;
FilePath = filePath;
RelativePhysicalPath = relativePhysicalPath;
_fileKind = fileKind;
File = file;
CssScope = cssScope;
}
public FileInfo File { get; }
@ -40,6 +42,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string FileKind => _fileKind ?? base.FileKind;
public override string CssScope { get; }
public override Stream Read() => new FileStream(PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
}
}

View File

@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
private static readonly char[] PathSeparators = new char[] { '/', '\\' };
private static readonly char[] NamespaceSeparators = new char[] { '.' };
private static object CssScopeKey = new object();
public static TagHelperDocumentContext GetTagHelperContext(this RazorCodeDocument document)
{
@ -216,6 +217,26 @@ namespace Microsoft.AspNetCore.Razor.Language
document.Items[typeof(FileKinds)] = fileKind;
}
public static string GetCssScope(this RazorCodeDocument document)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
return (string)document.Items[CssScopeKey];
}
public static void SetCssScope(this RazorCodeDocument document, string cssScope)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
document.Items[CssScopeKey] = cssScope;
}
// In general documents will have a relative path (relative to the project root).
// We can only really compute a nice namespace when we know a relative path.
//

View File

@ -238,6 +238,7 @@ namespace Microsoft.AspNetCore.Razor.Language
builder.Features.Add(new ComponentReferenceCaptureLoweringPass());
builder.Features.Add(new ComponentSplatLoweringPass());
builder.Features.Add(new ComponentBindLoweringPass());
builder.Features.Add(new ComponentCssScopePass());
builder.Features.Add(new ComponentTemplateDiagnosticPass());
builder.Features.Add(new ComponentGenericTypePass());
builder.Features.Add(new ComponentChildContentDiagnosticPass());

View File

@ -35,6 +35,11 @@ namespace Microsoft.AspNetCore.Razor.Language
/// </summary>
public virtual string RelativePhysicalPath => null;
/// <summary>
/// A scope identifier that will be used on elements in the generated class, or null.
/// </summary>
public virtual string CssScope { get; }
/// <summary>
/// Gets the document kind that should be used for the generated document. If possible this will be inferred from the file path. May be null.
/// </summary>

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo);
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo, "MyCssScope");
// Assert
Assert.Equal("/Home.cshtml", projectItem.FilePath);
@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.Equal("test", projectItem.FileKind);
Assert.Equal(fileInfo.FullName, projectItem.PhysicalPath);
Assert.Equal("Home.cshtml", projectItem.RelativePhysicalPath);
Assert.Equal("MyCssScope", projectItem.CssScope);
}
[Fact]
@ -39,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
var projectItem = new DefaultRazorProjectItem("/", "/Home.razor", "Home.cshtml", fileKind: null, fileInfo);
var projectItem = new DefaultRazorProjectItem("/", "/Home.razor", "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Equal(FileKinds.Component, projectItem.FileKind);
@ -52,7 +53,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileKind: null, fileInfo);
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Equal(FileKinds.Legacy, projectItem.FileKind);
@ -65,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
var projectItem = new DefaultRazorProjectItem("/", filePath: null, "Home.cshtml", fileKind: null, fileInfo);
var projectItem = new DefaultRazorProjectItem("/", filePath: null, "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Null(projectItem.FileKind);
@ -78,7 +79,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Views", "FileDoesNotExist.cshtml"));
// Act
var projectItem = new DefaultRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), "test", fileInfo);
var projectItem = new DefaultRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), "test", fileInfo, cssScope: null);
// Assert
Assert.False(projectItem.Exists);
@ -89,7 +90,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
// Arrange
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo);
var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo, cssScope: null);
// Act
var stream = projectItem.Read();

View File

@ -4929,6 +4929,69 @@ namespace New.Test
#endregion
#region "CSS scoping"
[Fact]
public void Component_WithCssScope()
{
// Arrange
AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;
namespace Test
{
public class TemplatedComponent : ComponentBase
{
[Parameter]
public RenderFragment ChildContent { get; set; }
}
}
"));
// Act
// This test case attempts to use all syntaxes that might interact with auto-generated attributes
var generated = CompileToCSharp(@"
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Rendering
<h1>Element with no attributes</h1>
<parent with-attributes=""yes"" with-csharp-attribute-value=""@(123)"">
<child />
<child has multiple attributes=""some with values"">With text</child>
<TemplatedComponent @ref=""myComponentReference"">
<span id=""hello"">This is in child content</span>
</TemplatedComponent>
</parent>
@if (DateTime.Now.Year > 1950)
{
<with-ref-capture some-attr @ref=""myElementReference"">Content</with-ref-capture>
<input id=""myElem"" @bind=""myVariable"" another-attr=""Another attr value"" />
}
@code {
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
<li data-index=@i>Something @i</li>
}
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
}
", cssScope: "TestCssScope");
// Assert
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
CompileToAssembly(generated);
}
#endregion
#region Misc
[Fact] // We don't process <!DOCTYPE ...> - we just skip them

View File

@ -49,6 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<ComponentBindLoweringPass>(feature),
feature => Assert.IsType<ComponentChildContentDiagnosticPass>(feature),
feature => Assert.IsType<ComponentComplexAttributeContentPass>(feature),
feature => Assert.IsType<ComponentCssScopePass>(feature),
feature => Assert.IsType<ComponentDocumentClassifierPass>(feature),
feature => Assert.IsType<ComponentEventHandlerLoweringPass>(feature),
feature => Assert.IsType<ComponentGenericTypePass>(feature),

View File

@ -0,0 +1,148 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
using Microsoft.AspNetCore.Components.Web;
#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
using Microsoft.AspNetCore.Components.Rendering;
#line default
#line hidden
#nullable disable
public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#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.Components.Rendering.RenderTreeBuilder __builder)
{
__o =
#nullable restore
#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
123
#line default
#line hidden
#nullable disable
;
__builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
}
));
#nullable restore
#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
myComponentReference = default(Test.TemplatedComponent);
#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = typeof(TemplatedComponent);
#line default
#line hidden
#nullable disable
#nullable restore
#line 11 "x:\dir\subdir\Test\TestComponent.cshtml"
if (DateTime.Now.Year > 1950)
{
#line default
#line hidden
#nullable disable
#nullable restore
#line 13 "x:\dir\subdir\Test\TestComponent.cshtml"
myElementReference = default(Microsoft.AspNetCore.Components.ElementReference);
#line default
#line hidden
#nullable disable
__o = Microsoft.AspNetCore.Components.BindConverter.FormatValue(
#nullable restore
#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
myVariable
#line default
#line hidden
#nullable disable
);
__o = Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value, myVariable);
#nullable restore
#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
}
#line default
#line hidden
#nullable disable
}
#pragma warning restore 1998
#nullable restore
#line 17 "x:\dir\subdir\Test\TestComponent.cshtml"
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
#line default
#line hidden
#nullable disable
__o =
#nullable restore
#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
i
#line default
#line hidden
#nullable disable
;
#nullable restore
#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = i;
#line default
#line hidden
#nullable disable
#nullable restore
#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
}
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
#line default
#line hidden
#nullable disable
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,114 @@
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 - (104:5,1 [37] ) - Microsoft.AspNetCore.Components
UsingDirective - (1:0,1 [41] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
UsingDirective - (45:1,1 [47] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Rendering
ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
DesignTimeDirective -
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
HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
HtmlContent - (92:1,48 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (92:1,48 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (94:2,0 [35] x:\dir\subdir\Test\TestComponent.cshtml) - h1
HtmlContent - (98:2,4 [26] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (98:2,4 [26] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Element with no attributes
HtmlContent - (129:2,35 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (129:2,35 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (131:3,0 [305] x:\dir\subdir\Test\TestComponent.cshtml) - parent
HtmlAttribute - (138:3,7 [22] x:\dir\subdir\Test\TestComponent.cshtml) - with-attributes=" - "
HtmlAttributeValue - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - yes
HtmlAttribute - (160:3,29 [37] x:\dir\subdir\Test\TestComponent.cshtml) - with-csharp-attribute-value=" - "
CSharpExpressionAttributeValue - (190:3,59 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
HtmlContent - (198:3,67 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (198:3,67 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (204:4,4 [9] x:\dir\subdir\Test\TestComponent.cshtml) - child
HtmlContent - (213:4,13 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (213:4,13 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (219:5,4 [67] x:\dir\subdir\Test\TestComponent.cshtml) - child
HtmlAttribute - (225:5,10 [4] x:\dir\subdir\Test\TestComponent.cshtml) - has -
HtmlAttribute - (229:5,14 [9] x:\dir\subdir\Test\TestComponent.cshtml) - multiple -
HtmlAttribute - (238:5,23 [30] x:\dir\subdir\Test\TestComponent.cshtml) - attributes=" - "
HtmlAttributeValue - (251:5,36 [4] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (251:5,36 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - some
HtmlAttributeValue - (255:5,40 [5] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (256:5,41 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - with
HtmlAttributeValue - (260:5,45 [7] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (261:5,46 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - values
HtmlContent - (269:5,54 [9] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (269:5,54 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - With text
HtmlContent - (286:5,71 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (286:5,71 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
Component - (292:6,4 [133] x:\dir\subdir\Test\TestComponent.cshtml) - TemplatedComponent
ComponentChildContent - - ChildContent - context
HtmlContent - (340:6,52 [10] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (340:6,52 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (350:7,8 [48] x:\dir\subdir\Test\TestComponent.cshtml) - span
HtmlAttribute - (355:7,13 [11] x:\dir\subdir\Test\TestComponent.cshtml) - id=" - "
HtmlAttributeValue - (360:7,18 [5] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (360:7,18 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Html - hello
HtmlContent - (367:7,25 [24] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (367:7,25 [24] x:\dir\subdir\Test\TestComponent.cshtml) - Html - This is in child content
HtmlContent - (398:7,56 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (398:7,56 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
ReferenceCapture - (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml) - myComponentReference
HtmlContent - (425:8,25 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (425:8,25 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
HtmlContent - (436:9,9 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (436:9,9 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - if (DateTime.Now.Year > 1950)\n{\n
MarkupElement - (477:12,4 [80] x:\dir\subdir\Test\TestComponent.cshtml) - with-ref-capture
HtmlContent - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Content
HtmlAttribute - - some-attr -
ReferenceCapture - (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml) - myElementReference
CSharpCode - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n
MarkupElement - (563:13,4 [74] x:\dir\subdir\Test\TestComponent.cshtml) - input
HtmlAttribute - - id=" - "
HtmlAttributeValue - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - myElem
HtmlAttribute - - another-attr=" - "
HtmlAttributeValue - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Another attr value
HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - value=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindConverter.FormatValue(
LazyIntermediateToken - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - myVariable
IntermediateToken - - CSharp - )
HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - onchange=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value,
IntermediateToken - - CSharp - myVariable
IntermediateToken - - CSharp - )
CSharpCode - (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n}
HtmlContent - (640:14,1 [4] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (640:14,1 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
HtmlContent - (1098:32,1 [2] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (1098:32,1 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n ElementReference myElementReference;\n TemplatedComponent myComponentReference;\n string myVariable;\n\n void MethodRenderingMarkup(RenderTreeBuilder __builder)\n {\n for (var i = 0; i < 10; i++)\n {\n
MarkupElement - (896:25,12 [35] x:\dir\subdir\Test\TestComponent.cshtml) - li
HtmlAttribute - (899:25,15 [14] x:\dir\subdir\Test\TestComponent.cshtml) - data-index= -
CSharpExpressionAttributeValue - (911:25,27 [2] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
HtmlContent - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Something
CSharpExpression - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
CSharpCode - (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n }\n\n System.GC.KeepAlive(myElementReference);\n System.GC.KeepAlive(myComponentReference);\n System.GC.KeepAlive(myVariable);\n }\n

View File

@ -0,0 +1,105 @@
Source Location: (1:0,1 [41] x:\dir\subdir\Test\TestComponent.cshtml)
|using Microsoft.AspNetCore.Components.Web|
Generated Location: (320:12,0 [41] )
|using Microsoft.AspNetCore.Components.Web|
Source Location: (45:1,1 [47] x:\dir\subdir\Test\TestComponent.cshtml)
|using Microsoft.AspNetCore.Components.Rendering|
Generated Location: (484:19,0 [47] )
|using Microsoft.AspNetCore.Components.Rendering|
Source Location: (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml)
|123|
Generated Location: (1267:39,61 [3] )
|123|
Source Location: (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml)
|myComponentReference|
Generated Location: (1592:50,30 [20] )
|myComponentReference|
Source Location: (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml)
|if (DateTime.Now.Year > 1950)
{
|
Generated Location: (1927:64,1 [38] )
|if (DateTime.Now.Year > 1950)
{
|
Source Location: (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml)
|myElementReference|
Generated Location: (2126:73,38 [18] )
|myElementReference|
Source Location: (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
|
|
Generated Location: (2353:78,96 [6] )
|
|
Source Location: (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
|myVariable|
Generated Location: (2540:83,30 [10] )
|myVariable|
Source Location: (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml)
|
}|
Generated Location: (2905:92,78 [3] )
|
}|
Source Location: (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml)
|
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
|
Generated Location: (3087:102,7 [245] )
|
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
|
Source Location: (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml)
|i|
Generated Location: (3499:119,28 [1] )
|i|
Source Location: (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
|i|
Generated Location: (3675:127,41 [1] )
|i|
Source Location: (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml)
|
}
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
|
Generated Location: (3847:134,47 [166] )
|
}
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
|

View File

@ -0,0 +1,162 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
using Microsoft.AspNetCore.Components.Web;
#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
using Microsoft.AspNetCore.Components.Rendering;
#line default
#line hidden
#nullable disable
public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
{
#pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
__builder.AddMarkupContent(0, "<h1 TestCssScope>Element with no attributes</h1>\r\n");
__builder.OpenElement(1, "parent");
__builder.AddAttribute(2, "with-attributes", "yes");
__builder.AddAttribute(3, "with-csharp-attribute-value",
#nullable restore
#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
123
#line default
#line hidden
#nullable disable
);
__builder.AddAttribute(4, "TestCssScope");
__builder.AddMarkupContent(5, "<child TestCssScope></child>\r\n ");
__builder.AddMarkupContent(6, "<child has multiple attributes=\"some with values\" TestCssScope>With text</child>\r\n ");
__builder.OpenComponent<Test.TemplatedComponent>(7);
__builder.AddAttribute(8, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
__builder2.AddMarkupContent(9, "<span id=\"hello\" TestCssScope>This is in child content</span>");
}
));
__builder.AddComponentReferenceCapture(10, (__value) => {
#nullable restore
#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
myComponentReference = (Test.TemplatedComponent)__value;
#line default
#line hidden
#nullable disable
}
);
__builder.CloseComponent();
__builder.CloseElement();
#nullable restore
#line 11 "x:\dir\subdir\Test\TestComponent.cshtml"
if (DateTime.Now.Year > 1950)
{
#line default
#line hidden
#nullable disable
__builder.OpenElement(11, "with-ref-capture");
__builder.AddAttribute(12, "some-attr");
__builder.AddAttribute(13, "TestCssScope");
__builder.AddElementReferenceCapture(14, (__value) => {
#nullable restore
#line 13 "x:\dir\subdir\Test\TestComponent.cshtml"
myElementReference = __value;
#line default
#line hidden
#nullable disable
}
);
__builder.AddContent(15, "Content");
__builder.CloseElement();
__builder.AddMarkupContent(16, "\r\n ");
__builder.OpenElement(17, "input");
__builder.AddAttribute(18, "id", "myElem");
__builder.AddAttribute(19, "another-attr", "Another attr value");
__builder.AddAttribute(20, "value", Microsoft.AspNetCore.Components.BindConverter.FormatValue(
#nullable restore
#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
myVariable
#line default
#line hidden
#nullable disable
));
__builder.AddAttribute(21, "onchange", Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value, myVariable));
__builder.SetUpdatesAttributeName("value");
__builder.AddAttribute(22, "TestCssScope");
__builder.CloseElement();
#nullable restore
#line 15 "x:\dir\subdir\Test\TestComponent.cshtml"
}
#line default
#line hidden
#nullable disable
}
#pragma warning restore 1998
#nullable restore
#line 17 "x:\dir\subdir\Test\TestComponent.cshtml"
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
#line default
#line hidden
#nullable disable
__builder.OpenElement(23, "li");
__builder.AddAttribute(24, "data-index",
#nullable restore
#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
i
#line default
#line hidden
#nullable disable
);
__builder.AddAttribute(25, "TestCssScope");
__builder.AddContent(26, "Something ");
__builder.AddContent(27,
#nullable restore
#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
i
#line default
#line hidden
#nullable disable
);
__builder.CloseElement();
#nullable restore
#line 27 "x:\dir\subdir\Test\TestComponent.cshtml"
}
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
#line default
#line hidden
#nullable disable
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,70 @@
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 - (104:5,1 [39] ) - Microsoft.AspNetCore.Components
UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
UsingDirective - (45:1,1 [49] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Rendering
ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
MethodDeclaration - - protected override - void - BuildRenderTree
MarkupBlock - - <h1 TestCssScope>Element with no attributes</h1>\n
MarkupElement - (131:3,0 [305] x:\dir\subdir\Test\TestComponent.cshtml) - parent
HtmlAttribute - (138:3,7 [22] x:\dir\subdir\Test\TestComponent.cshtml) - with-attributes=" - "
HtmlAttributeValue - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - yes
HtmlAttribute - (160:3,29 [37] x:\dir\subdir\Test\TestComponent.cshtml) - with-csharp-attribute-value=" - "
CSharpExpressionAttributeValue - (190:3,59 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
MarkupBlock - - <child TestCssScope></child>\n
MarkupBlock - - <child has multiple attributes="some with values" TestCssScope>With text</child>\n
Component - (292:6,4 [133] x:\dir\subdir\Test\TestComponent.cshtml) - TemplatedComponent
ComponentChildContent - - ChildContent - context
MarkupBlock - - <span id="hello" TestCssScope>This is in child content</span>
ReferenceCapture - (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml) - myComponentReference
HtmlAttribute - - TestCssScope -
CSharpCode - (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - if (DateTime.Now.Year > 1950)\n{\n
MarkupElement - (477:12,4 [80] x:\dir\subdir\Test\TestComponent.cshtml) - with-ref-capture
HtmlContent - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Content
HtmlAttribute - - some-attr -
ReferenceCapture - (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml) - myElementReference
HtmlAttribute - - TestCssScope -
HtmlContent - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (557:12,84 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
LazyIntermediateToken - (559:13,0 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
MarkupElement - (563:13,4 [74] x:\dir\subdir\Test\TestComponent.cshtml) - input
HtmlAttribute - - id=" - "
HtmlAttributeValue - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - myElem
HtmlAttribute - - another-attr=" - "
HtmlAttributeValue - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Another attr value
HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - value=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindConverter.FormatValue(
LazyIntermediateToken - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - myVariable
IntermediateToken - - CSharp - )
HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - onchange=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value,
IntermediateToken - - CSharp - myVariable
IntermediateToken - - CSharp - )
HtmlAttribute - - TestCssScope -
CSharpCode - (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - }\n
CSharpCode - (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n ElementReference myElementReference;\n TemplatedComponent myComponentReference;\n string myVariable;\n\n void MethodRenderingMarkup(RenderTreeBuilder __builder)\n {\n for (var i = 0; i < 10; i++)\n {\n
MarkupElement - (896:25,12 [35] x:\dir\subdir\Test\TestComponent.cshtml) - li
HtmlAttribute - (899:25,15 [14] x:\dir\subdir\Test\TestComponent.cshtml) - data-index= -
CSharpExpressionAttributeValue - (911:25,27 [2] x:\dir\subdir\Test\TestComponent.cshtml) -
LazyIntermediateToken - (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
HtmlContent - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Something
CSharpExpression - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
HtmlAttribute - - TestCssScope -
CSharpCode - (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml)
LazyIntermediateToken - (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - }\n\n System.GC.KeepAlive(myElementReference);\n System.GC.KeepAlive(myComponentReference);\n System.GC.KeepAlive(myVariable);\n }\n

View File

@ -0,0 +1,66 @@
Source Location: (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml)
|myComponentReference|
Generated Location: (2121:62,30 [20] )
|myComponentReference|
Source Location: (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml)
|if (DateTime.Now.Year > 1950)
{
|
Generated Location: (2412:73,1 [34] )
|if (DateTime.Now.Year > 1950)
{
|
Source Location: (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml)
|myElementReference|
Generated Location: (2845:85,38 [18] )
|myElementReference|
Source Location: (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
|}
|
Generated Location: (3972:113,0 [3] )
|}
|
Source Location: (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml)
|
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
|
Generated Location: (4152:122,7 [233] )
|
ElementReference myElementReference;
TemplatedComponent myComponentReference;
string myVariable;
void MethodRenderingMarkup(RenderTreeBuilder __builder)
{
for (var i = 0; i < 10; i++)
{
|
Source Location: (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml)
| }
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
|
Generated Location: (5112:159,0 [164] )
| }
System.GC.KeepAlive(myElementReference);
System.GC.KeepAlive(myComponentReference);
System.GC.KeepAlive(myVariable);
}
|

View File

@ -16,8 +16,8 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "a");
__builder.AddAttribute(2, "href", "/cool-url");
__builder.AddAttribute(3, "style", true);
__builder.AddAttribute(4, "disabled", true);
__builder.AddAttribute(3, "style");
__builder.AddAttribute(4, "disabled");
__builder.AddAttribute(5, "href", "/even-cooler-url");
__builder.AddContent(6, "Learn the ten cool tricks your compiler author will hate!");
__builder.CloseElement();

View File

@ -16,10 +16,10 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "a");
__builder.AddAttribute(2, "href", "/cool-url");
__builder.AddAttribute(3, "style", true);
__builder.AddAttribute(4, "disabled", true);
__builder.AddAttribute(3, "style");
__builder.AddAttribute(4, "disabled");
__builder.AddAttribute(5, "href", "/even-cooler-url");
__builder.AddAttribute(6, "href", true);
__builder.AddAttribute(6, "href");
__builder.AddContent(7, "Learn the ten cool tricks your compiler author will hate!");
__builder.CloseElement();
__builder.CloseElement();

View File

@ -30,7 +30,7 @@ using Microsoft.AspNetCore.Components.Web;
#line hidden
#nullable disable
);
__builder.AddAttribute(2, "@onclick:preventDefault", true);
__builder.AddAttribute(2, "@onclick:preventDefault");
__builder.CloseElement();
}
#pragma warning restore 1998

View File

@ -16,7 +16,7 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "script");
__builder.AddAttribute(2, "src", "some/url.js");
__builder.AddAttribute(3, "anotherattribute", true);
__builder.AddAttribute(3, "anotherattribute");
__builder.AddMarkupContent(4, "\r\n some text\r\n some more text\r\n ");
__builder.CloseElement();
__builder.CloseElement();

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
@ -25,6 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
Outputs = Option("-o", "Generated output file path", CommandOptionType.MultipleValue);
RelativePaths = Option("-r", "Relative path", CommandOptionType.MultipleValue);
FileKinds = Option("-k", "File kind", CommandOptionType.MultipleValue);
CssScopeSources = Option("-cssscopedinput", ".razor file with scoped CSS", CommandOptionType.MultipleValue);
CssScopeValues = Option("-cssscopevalue", "CSS scope value for .razor file with scoped CSS", CommandOptionType.MultipleValue);
ProjectDirectory = Option("-p", "project root directory", CommandOptionType.SingleValue);
TagHelperManifest = Option("-t", "tag helper manifest file", CommandOptionType.SingleValue);
Version = Option("-v|--version", "Razor language version", CommandOptionType.SingleValue);
@ -44,6 +47,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
public CommandOption FileKinds { get; }
public CommandOption CssScopeSources { get; }
public CommandOption CssScopeValues { get; }
public CommandOption ProjectDirectory { get; }
public CommandOption TagHelperManifest { get; }
@ -81,7 +88,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
var version = RazorLanguageVersion.Parse(Version.Value());
var configuration = RazorConfiguration.Create(version, Configuration.Value(), extensions);
var sourceItems = GetSourceItems(ProjectDirectory.Value(), Sources.Values, Outputs.Values, RelativePaths.Values, FileKinds.Values);
var sourceItems = GetSourceItems(
Sources.Values, Outputs.Values, RelativePaths.Values,
FileKinds.Values, CssScopeSources.Values, CssScopeValues.Values);
var result = ExecuteCore(
configuration: configuration,
@ -120,6 +129,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
return false;
}
if (CssScopeSources.Values.Count != CssScopeValues.Values.Count)
{
// CssScopeSources and CssScopeValues arguments must appear as matched pairs
Error.WriteLine($"{CssScopeSources.Description} has {CssScopeSources.Values.Count}, but {CssScopeValues.Description} has {CssScopeValues.Values.Count} values.");
return false;
}
if (string.IsNullOrEmpty(ProjectDirectory.Value()))
{
ProjectDirectory.Values.Add(Environment.CurrentDirectory);
@ -256,7 +272,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
filePath: item.FilePath,
relativePhysicalPath: item.RelativePhysicalPath,
fileKind: item.FileKind,
file: new FileInfo(item.SourcePath));
file: new FileInfo(item.SourcePath),
cssScope: item.CssScope);
project.Add(projectItem);
}
@ -284,19 +301,28 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
}
private SourceItem[] GetSourceItems(string projectDirectory, List<string> sources, List<string> outputs, List<string> relativePath, List<string> fileKinds)
private static SourceItem[] GetSourceItems(List<string> sources, List<string> outputs, List<string> relativePath, List<string> fileKinds, List<string> cssScopeSources, List<string> cssScopeValues)
{
var cssScopeAssociations = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
for (var cssScopeSourceIndex = 0; cssScopeSourceIndex < cssScopeSources.Count; cssScopeSourceIndex++)
{
cssScopeAssociations.Add(cssScopeSources[cssScopeSourceIndex], cssScopeSourceIndex);
}
var items = new SourceItem[sources.Count];
for (var i = 0; i < items.Length; i++)
{
var outputPath = Path.Combine(projectDirectory, outputs[i]);
var fileKind = fileKinds.Count > 0 ? fileKinds[i] : "mvc";
if (Language.FileKinds.IsComponent(fileKind))
{
fileKind = Language.FileKinds.GetComponentFileKindFromFilePath(sources[i]);
}
items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], fileKind);
var cssScopeValue = cssScopeAssociations.TryGetValue(sources[i], out var cssScopeIndex)
? cssScopeValues[cssScopeIndex]
: null;
items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], fileKind, cssScopeValue);
}
return items;
@ -334,7 +360,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
private readonly struct SourceItem
{
public SourceItem(string sourcePath, string outputPath, string physicalRelativePath, string fileKind)
public SourceItem(string sourcePath, string outputPath, string physicalRelativePath, string fileKind, string cssScope)
{
SourcePath = sourcePath;
OutputPath = outputPath;
@ -343,6 +369,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
.Replace(Path.DirectorySeparatorChar, '/')
.Replace("//", "/");
FileKind = fileKind;
CssScope = cssScope;
}
public string SourcePath { get; }
@ -354,6 +381,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
public string FilePath { get; }
public string FileKind { get; }
public string CssScope { get; }
}
private class StaticTagHelperFeature : ITagHelperFeature

View File

@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks
private const string Identity = "Identity";
private const string AssemblyName = "AssemblyName";
private const string AssemblyFilePath = "AssemblyFilePath";
private const string CssScope = "CssScope";
public string RootNamespace { get; set; }
@ -127,6 +128,26 @@ namespace Microsoft.AspNetCore.Razor.Tasks
}
}
// Added in 5.0: CSS scopes
if (parsedVersion.Major >= 5)
{
for (var i = 0; i < Sources.Length; i++)
{
// Most inputs won't have an associated CSS scope, so we only want to generate
// a scope parameter for those that do. Hence we need to specify in the parameter
// which one we're talking about.
var input = Sources[i];
var cssScope = input.GetMetadata(CssScope);
if (!string.IsNullOrEmpty(cssScope))
{
builder.AppendLine("-cssscopedinput");
builder.AppendLine(input.GetMetadata(FullPath));
builder.AppendLine("-cssscopevalue");
builder.AppendLine(cssScope);
}
}
}
builder.AppendLine("-p");
builder.AppendLine(ProjectRoot);

View File

@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
});
}
internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent, string fileKind = null)
internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent, string fileKind = null, string cssScope = null)
{
var fullPath = WorkingDirectory + PathSeparator + cshtmlRelativePath;
@ -161,18 +161,19 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
physicalPath: fullPath,
relativePhysicalPath: cshtmlRelativePath,
basePath: WorkingDirectory,
fileKind: fileKind ?? FileKind)
fileKind: fileKind ?? FileKind,
cssScope: cssScope)
{
Content = cshtmlContent.TrimStart(),
};
}
protected CompileToCSharpResult CompileToCSharp(string cshtmlContent, bool throwOnFailure=true)
protected CompileToCSharpResult CompileToCSharp(string cshtmlContent, bool throwOnFailure=true, string cssScope = null)
{
return CompileToCSharp(DefaultFileName, cshtmlContent, throwOnFailure);
return CompileToCSharp(DefaultFileName, cshtmlContent, throwOnFailure, cssScope: cssScope);
}
protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null)
protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null, string cssScope = null)
{
if (DeclarationOnly && DesignTime)
{
@ -202,7 +203,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
}
// Result of generating declarations
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind, cssScope);
codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
var declaration = new CompileToCSharpResult
{
@ -248,7 +249,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
// This will include the built-in components.
var projectEngine = CreateProjectEngine(Configuration, BaseCompilation.References.ToArray());
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind, cssScope);
RazorCodeDocument codeDocument;
if (DeclarationOnly)

View File

@ -15,12 +15,14 @@ namespace Microsoft.AspNetCore.Razor.Language
string physicalPath = null,
string relativePhysicalPath = null,
string basePath = "/",
string fileKind = null)
string fileKind = null,
string cssScope = null)
{
FilePath = filePath;
PhysicalPath = physicalPath;
RelativePhysicalPath = relativePhysicalPath;
BasePath = basePath;
CssScope = cssScope;
_fileKind = fileKind;
}
@ -34,6 +36,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string RelativePhysicalPath { get; }
public override string CssScope { get; }
public override bool Exists { get; } = true;
public string Content { get; set; } = "Default content";

View File

@ -385,6 +385,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
{
public RenderTreeBuilder() { }
public void AddAttribute(int sequence, in Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame frame) { }
public void AddAttribute(int sequence, string name) { }
public void AddAttribute(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback value) { }
public void AddAttribute(int sequence, string name, bool value) { }
public void AddAttribute(int sequence, string name, System.MulticastDelegate value) { }