Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public void Execute_DirectiveWithoutQuotes_RewritesTagHelpers_TagHelperMatchesEl

var formTagHelper = Assert.Single(tagHelperNodes);
Assert.Equal("form", formTagHelper.TagHelperInfo.TagName);
Assert.Equal(2, formTagHelper.TagHelperInfo.BindingResult.Mappings[tagHelper].Length);
Assert.Equal(2, formTagHelper.TagHelperInfo.BindingResult.GetBoundRules(tagHelper).Length);
}

[Fact]
Expand Down Expand Up @@ -340,7 +340,7 @@ public void Execute_DirectiveWithQuotes_RewritesTagHelpers_TagHelperMatchesEleme

var formTagHelper = Assert.Single(tagHelperNodes);
Assert.Equal("form", formTagHelper.TagHelperInfo.TagName);
Assert.Equal(2, formTagHelper.TagHelperInfo.BindingResult.Mappings[tagHelper].Length);
Assert.Equal(2, formTagHelper.TagHelperInfo.BindingResult.GetBoundRules(tagHelper).Length);
}

[Fact]
Expand Down Expand Up @@ -441,6 +441,7 @@ public void Execute_SetsTagHelperDocumentContext()

// Assert
var context = codeDocument.GetTagHelperContext();
Assert.NotNull(context);
Assert.Null(context.Prefix);
Assert.Empty(context.TagHelpers);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public class MyComponent : ComponentBase
var result = CompileToCSharp(string.Empty);

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.MyComponent");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);
Assert.Contains(context.TagHelpers, t => t.Name == "Test.MyComponent");
}

[Fact]
Expand All @@ -55,15 +56,16 @@ public class MyComponent : ComponentBase
var result = CompileToCSharp(string.Empty);

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(bindings.TagHelpers, t =>
Assert.Contains(context.TagHelpers, t =>
{
return t.Name == "Test.AnotherNamespace.MyComponent" &&
t.IsComponentFullyQualifiedNameMatch;
});

Assert.DoesNotContain(bindings.TagHelpers, t =>
Assert.DoesNotContain(context.TagHelpers, t =>
{
return t.Name == "Test.AnotherNamespace.MyComponent" &&
!t.IsComponentFullyQualifiedNameMatch;
Expand All @@ -79,8 +81,10 @@ public void ComponentDiscovery_CanFindComponent_DefinedinCshtml()
var result = CompileToCSharp("UniqueName.cshtml", cshtmlContent: string.Empty);

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.UniqueName");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(context.TagHelpers, t => t.Name == "Test.UniqueName");
}

[Fact]
Expand All @@ -96,8 +100,10 @@ @typeparam TItem
}");

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.UniqueName<TItem>");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(context.TagHelpers, t => t.Name == "Test.UniqueName<TItem>");
}

[Fact]
Expand All @@ -113,8 +119,10 @@ public void ComponentDiscovery_CanFindComponent_WithTypeParameterAndSemicolon()
}");

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.UniqueName<TItem>");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(context.TagHelpers, t => t.Name == "Test.UniqueName<TItem>");
}

[Fact]
Expand All @@ -132,8 +140,10 @@ @typeparam TItem3
}");

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.UniqueName<TItem1, TItem2, TItem3>");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(context.TagHelpers, t => t.Name == "Test.UniqueName<TItem1, TItem2, TItem3>");
}

[Fact]
Expand All @@ -151,7 +161,9 @@ @typeparam TItem3
}");

// Assert
var bindings = result.CodeDocument.GetTagHelperContext();
Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.UniqueName<TItem1, TItem2, TItem3>");
var context = result.CodeDocument.GetTagHelperContext();
Assert.NotNull(context);

Assert.Contains(context.TagHelpers, t => t.Name == "Test.UniqueName<TItem1, TItem2, TItem3>");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ public void SetCSharpDocument_SetsCSharpDocument()
}

[Fact]
public void GetTagHelperContext_ReturnsTagHelperContext()
public void GetAndSetTagHelperContext_ReturnsTagHelperContext()
{
// Arrange
var codeDocument = TestRazorCodeDocument.CreateEmpty();

var expected = TagHelperDocumentContext.Create(prefix: null, tagHelpers: []);
codeDocument.Items[typeof(TagHelperDocumentContext)] = expected;
codeDocument.SetTagHelperContext(expected);

// Act
var actual = codeDocument.GetTagHelperContext();
Expand All @@ -152,21 +152,6 @@ public void GetTagHelperContext_ReturnsTagHelperContext()
Assert.Same(expected, actual);
}

[Fact]
public void SetTagHelperContext_SetsTagHelperContext()
{
// Arrange
var codeDocument = TestRazorCodeDocument.CreateEmpty();

var expected = TagHelperDocumentContext.Create(prefix: null, tagHelpers: []);

// Act
codeDocument.SetTagHelperContext(expected);

// Assert
Assert.Same(expected, codeDocument.Items[typeof(TagHelperDocumentContext)]);
}

[Fact]
public void TryComputeNamespace_RootNamespaceNotSet_ReturnsNull()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public void GetBinding_ReturnsBindingWithInformation()
Assert.Equal("th:div", bindingResult.TagName);
Assert.Equal("body", bindingResult.ParentTagName);
Assert.Equal<KeyValuePair<string, string>>(expectedAttributes, bindingResult.Attributes);
Assert.Equal("th:", bindingResult.TagHelperPrefix);
Assert.Equal<TagMatchingRuleDescriptor>(divTagHelper.TagMatchingRules, bindingResult.Mappings[divTagHelper]);
Assert.Equal("th:", bindingResult.TagNamePrefix);
Assert.Equal<TagMatchingRuleDescriptor>(divTagHelper.TagMatchingRules, bindingResult.GetBoundRules(divTagHelper));
}

[Fact]
Expand Down Expand Up @@ -81,7 +81,7 @@ void TestTagName(string tagName, TagMatchingRuleDescriptor expectedBindingResult
Assert.Equal<TagHelperDescriptor>(expectedDescriptors, bindingResult.Descriptors);

Assert.Equal(tagName, bindingResult.TagName);
var mapping = Assert.Single(bindingResult.Mappings[multiTagHelper]);
var mapping = Assert.Single(bindingResult.GetBoundRules(multiTagHelper));
Assert.Equal(expectedBindingResult, mapping);
}
}
Expand Down Expand Up @@ -136,7 +136,7 @@ void TestTagName(string tagName, TagHelperDescriptor[] expectedDescriptors, TagM

for (int i = 0; i < expectedDescriptors.Length; i++)
{
var mapping = Assert.Single(bindingResult.Mappings[expectedDescriptors[i]]);
var mapping = Assert.Single(bindingResult.GetBoundRules(expectedDescriptors[i]));
Assert.Equal(expectedBindingResults[i], mapping);
}
}
Expand Down Expand Up @@ -598,7 +598,7 @@ public void GetBinding_DescriptorWithMultipleRules_CorrectlySelectsMatchingRules
// Assert
var boundDescriptor = Assert.Single(binding.Descriptors);
Assert.Same(multiRuleDescriptor, boundDescriptor);
var boundRules = binding.Mappings[boundDescriptor];
var boundRules = binding.GetBoundRules(boundDescriptor);
var boundRule = Assert.Single(boundRules);
Assert.Equal("div", boundRule.TagName);
}
Expand Down Expand Up @@ -626,7 +626,7 @@ public void GetBinding_PrefixedParent_ReturnsBinding()
// Assert
var boundDescriptor = Assert.Single(bindingResult.Descriptors);
Assert.Same(divDescriptor, boundDescriptor);
var boundRules = bindingResult.Mappings[boundDescriptor];
var boundRules = bindingResult.GetBoundRules(boundDescriptor);
var boundRule = Assert.Single(boundRules);
Assert.Equal("div", boundRule.TagName);
Assert.Equal("p", boundRule.ParentTag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, Cancellation
{
var syntaxTree = codeDocument.GetPreTagHelperSyntaxTree();
var context = codeDocument.GetTagHelperContext();
if (syntaxTree is null || context.TagHelpers.Length == 0)
if (syntaxTree is null || context is not { TagHelpers.Length: > 0 })
{
// No descriptors, no-op.
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ public static TagMode GetTagMode(
}

var hasDirectiveAttribute = false;
foreach (var descriptor in bindingResult.Descriptors)
foreach (var boundRulesInfo in bindingResult.AllBoundRules)
{
var boundRules = bindingResult.Mappings[descriptor];
var nonDefaultRule = boundRules.FirstOrDefault(static rule => rule.TagStructure != TagStructure.Unspecified);
var nonDefaultRule = boundRulesInfo.Rules.FirstOrDefault(static rule => rule.TagStructure != TagStructure.Unspecified);

if (nonDefaultRule?.TagStructure == TagStructure.WithoutEndTag)
{
Expand All @@ -42,6 +41,7 @@ public static TagMode GetTagMode(
// <input @onclick="..."> vs <input onclick="..." />
//
// We don't want this to become an error just because you added a directive attribute.
var descriptor = boundRulesInfo.Descriptor;
if (descriptor.IsAnyComponentDocumentTagHelper() && !descriptor.IsComponentOrChildContentTagHelper)
{
hasDirectiveAttribute = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public static RazorSyntaxTree Rewrite(RazorSyntaxTree syntaxTree, TagHelperBinde
builder.AddRange(treeDiagnostics);
builder.AddRange(sinkDiagnostics);

foreach (var tagHelper in binder.TagHelpers)
foreach (var descriptor in binder.Descriptors)
{
foreach (var diagnostic in tagHelper.GetAllDiagnostics())
foreach (var diagnostic in descriptor.GetAllDiagnostics())
{
builder.Add(diagnostic);
}
Expand Down Expand Up @@ -137,7 +137,7 @@ public override SyntaxNode VisitMarkupElement(MarkupElementSyntax node)
else
{
// Tag helper start tag. Keep track.
var tracker = new TagHelperTracker(_binder.TagHelperPrefix, tagHelperInfo);
var tracker = new TagHelperTracker(_binder.TagNamePrefix, tagHelperInfo);
_trackerStack.Push(tracker);
}
}
Expand Down Expand Up @@ -347,10 +347,9 @@ private bool TryRewriteTagHelperEnd(
return false;
}

foreach (var descriptor in tagHelperBinding.Descriptors)
foreach (var boundRulesInfo in tagHelperBinding.AllBoundRules)
{
var boundRules = tagHelperBinding.Mappings[descriptor];
var invalidRule = boundRules.FirstOrDefault(static rule => rule.TagStructure == TagStructure.WithoutEndTag);
var invalidRule = boundRulesInfo.Rules.FirstOrDefault(static rule => rule.TagStructure == TagStructure.WithoutEndTag);

if (invalidRule != null)
{
Expand All @@ -359,7 +358,7 @@ private bool TryRewriteTagHelperEnd(
RazorDiagnosticFactory.CreateParsing_TagHelperMustNotHaveAnEndTag(
new SourceSpan(SourceLocationTracker.Advance(endTag.GetSourceLocation(_source), "</"), tagName.Length),
tagName,
descriptor.DisplayName,
boundRulesInfo.Descriptor.DisplayName,
invalidRule.TagStructure));

return false;
Expand Down Expand Up @@ -462,10 +461,11 @@ private void ValidateBinding(
TagHelperDescriptor? baseDescriptor = null;
TagStructure? baseStructure = null;

foreach (var descriptor in bindingResult.Descriptors)
foreach (var boundRulesInfo in bindingResult.AllBoundRules)
{
var boundRules = bindingResult.Mappings[descriptor];
foreach (var rule in boundRules)
var descriptor = boundRulesInfo.Descriptor;

foreach (var rule in boundRulesInfo.Rules)
{
if (rule.TagStructure != TagStructure.Unspecified)
{
Expand Down Expand Up @@ -726,18 +726,18 @@ private record TagHelperTracker : TagTracker
{
public uint OpenMatchingTags;

private readonly string? _tagHelperPrefix;
private readonly string? _tagNamePrefix;
private readonly TagHelperBinding _binding;

private readonly Lazy<(ImmutableArray<string> Names, HashSet<string> NameSet)> _lazyAllowedChildren;
private readonly Lazy<HashSet<string>> _lazyPrefixedAllowedChildrenNameSet;

public ImmutableArray<string> AllowedChildren => _lazyAllowedChildren.Value.Names;

public TagHelperTracker(string? tagHelperPrefix, TagHelperInfo info)
public TagHelperTracker(string? tagNamePrefix, TagHelperInfo info)
: base(info.TagName, IsTagHelper: true)
{
_tagHelperPrefix = tagHelperPrefix;
_tagNamePrefix = tagNamePrefix;
_binding = info.BindingResult;

_lazyAllowedChildren = new(CreateAllowedChildren);
Expand Down Expand Up @@ -773,7 +773,7 @@ public bool AllowsChild(string tagName, bool nameIncludesPrefix)

private HashSet<string> CreatePrefixedAllowedChildren()
{
if (_tagHelperPrefix is not string tagHelperPrefix)
if (_tagNamePrefix is not string tagNamePrefix)
{
return _lazyAllowedChildren.Value.NameSet;
}
Expand All @@ -782,7 +782,7 @@ private HashSet<string> CreatePrefixedAllowedChildren()

foreach (var childName in AllowedChildren)
{
distinctSet.Add(tagHelperPrefix + childName);
distinctSet.Add(tagNamePrefix + childName);
}

return distinctSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;

namespace Microsoft.AspNetCore.Razor.Language;
Expand All @@ -17,6 +19,8 @@ public sealed class RazorCodeDocument

public string FileKind => ParserOptions.FileKind;

private TagHelperDocumentContext? _tagHelperContext;

private RazorCodeDocument(
RazorSourceDocument source,
ImmutableArray<RazorSourceDocument> imports,
Expand Down Expand Up @@ -52,4 +56,23 @@ public static RazorCodeDocument Create(

return new RazorCodeDocument(source, imports, parserOptions, codeGenerationOptions);
}

internal bool TryGetTagHelperContext([NotNullWhen(true)] out TagHelperDocumentContext? result)
{
result = _tagHelperContext;
return result is not null;
}

internal TagHelperDocumentContext? GetTagHelperContext()
=> _tagHelperContext;

internal TagHelperDocumentContext GetRequiredTagHelperContext()
=> _tagHelperContext.AssumeNotNull();

internal void SetTagHelperContext(TagHelperDocumentContext context)
{
ArgHelper.ThrowIfNull(context);

_tagHelperContext = context;
}
}
Loading