Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -355,8 +355,21 @@ internal static bool IsTypeInNamespace(TagHelperDescriptor tagHelper, string @na

static bool IsTypeInNamespace(string typeNamespace, string @namespace)
{
// Either the typeName is not the full type name or this type is at the top level.
return string.IsNullOrEmpty(typeNamespace) || typeNamespace.Equals(@namespace, StringComparison.Ordinal);
if (string.IsNullOrEmpty(typeNamespace))
{
// Either the typeName is not the full type name or this type is at the top level.
return true;
}

// Remove global:: prefix from namespace.
const string globalPrefix = "global::";
var normalizedNamespace = @namespace.AsSpan();
if (@namespace.StartsWith(globalPrefix, StringComparison.Ordinal))
{
normalizedNamespace = normalizedNamespace[globalPrefix.Length..];
}

return normalizedNamespace.Equals(typeNamespace.AsSpan(), StringComparison.Ordinal);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,35 @@ @using SomeProject.SomeOtherFolder
Assert.Equal(2, visitor.Matches.Count);
}

[Fact]
public void ComponentDirectiveVisitor_MatchesIfNamespaceInUsing_GlobalPrefix()
{
// Arrange
var currentNamespace = "SomeProject";
var componentDescriptor = CreateComponentDescriptor(
"Counter",
"SomeProject.SomeOtherFolder.Counter",
AssemblyA);
var descriptors = new[]
{
componentDescriptor,
};
var filePath = "C:\\SomeFolder\\SomeProject\\Counter.cshtml";
var content = """
@using global::SomeProject.SomeOtherFolder
""";
var sourceDocument = CreateComponentTestSourceDocument(content, filePath);
var tree = RazorSyntaxTree.Parse(sourceDocument);
var visitor = new DefaultRazorTagHelperContextDiscoveryPhase.ComponentDirectiveVisitor(sourceDocument.FilePath, descriptors, currentNamespace);

// Act
visitor.Visit(tree);

// Assert
var match = Assert.Single(visitor.Matches);
Assert.Same(componentDescriptor, match);
}

[Fact]
public void ComponentDirectiveVisitor_DoesNotMatchForUsingAliasAndStaticUsings()
{
Expand Down Expand Up @@ -1335,8 +1364,10 @@ @using static SomeProject.SomeOtherFolder.Foo
[InlineData("", "", true)]
[InlineData("Foo", "Project", true)]
[InlineData("Project.Foo", "Project", true)]
[InlineData("Project.Foo", "global::Project", true)]
[InlineData("Project.Bar.Foo", "Project.Bar", true)]
[InlineData("Project.Foo", "Project.Bar", false)]
[InlineData("Project.Foo", "global::Project.Bar", false)]
[InlineData("Project.Bar.Foo", "Project", false)]
[InlineData("Bar.Foo", "Project", false)]
public void IsTypeInNamespace_WorksAsExpected(string typeName, string @namespace, bool expected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8504,6 +8504,34 @@ @layout MainLayout
CompileToAssembly(generated, throwOnFailure: false);
}

[Fact]
public void ComponentImports_GlobalPrefix()
{
// Arrange
AdditionalSyntaxTrees.Add(Parse("""
using Microsoft.AspNetCore.Components;

namespace MyComponents
{
public class Counter : ComponentBase
{
}
}
"""));

// Act
var generated = CompileToCSharp("Index.razor", """
@using global::MyComponents

<Counter />
""");

// Assert
CompileToAssembly(generated);
Assert.DoesNotContain("<Counter", generated.Code);
Assert.Contains("global::MyComponents.Counter", generated.Code);
}

[Fact]
public void Component_NamespaceDirective_InImports()
{
Expand Down