Fix semantic tokens for fully qualified component names#12334
Closed
Fix semantic tokens for fully qualified component names#12334
Conversation
- Modified SemanticRange.CompareTo to prioritize Razor tokens over C# tokens when they have the same start position - Added containment check in TryWriteToken to filter out C# tokens that are fully contained within Razor tokens - Added test case for fully qualified component names with baseline files - Fixes issue where C# semantic tokens (namespace, operator, class) were showing through instead of being overridden by Razor component element tokens Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix fully qualified components rendering issue
Fix semantic tokens for fully qualified component names
Oct 15, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fully qualified component names were displaying with incorrect colorization in the editor. When using components like
<Microsoft.AspNetCore.Components.Web.PageTitle>, the C# semantic tokens (namespace, operator, class) were showing through instead of being overridden by Razor's component element token:Root Cause
The issue was in the
SemanticRange.CompareTosorting logic. When multiple semantic tokens started at the same position, the sort order was:This caused shorter C# tokens (e.g., "Microsoft" at chars 1-10) to be sorted before the longer Razor token (chars 1-46), preventing the Razor token from overriding the C# tokens.
Solution
Modified
SemanticRange.CompareTo: Moved theFromRazorcheck to occur immediately after comparing start positions, before comparing end positions. This ensures Razor tokens at the same start position always sort first, regardless of length.Added containment filtering in
TryWriteToken: Added logic to skip C# tokens that are fully contained within a Razor token on the same line, providing an additional safeguard.Testing
Added comprehensive test coverage with the new
FullyQualifiedComponenttest that verifies:razorComponentElementtokensAll existing semantic tokens tests continue to pass with no regressions.
Fixes #11480 (if applicable - replace with actual issue number)
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
2kmvsblobprodcus39.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)2zrvsblobprodcus388.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)7devsblobprodcus323.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)7tjvsblobprodcus341.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)bcnvsblobprodcus378.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)frdvsblobprodcus327.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)ibzvsblobprodcus369.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)imzvsblobprodcus368.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)josvsblobprodcus372.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)kgfvsblobprodcus314.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)kh4vsblobprodcus325.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)kijvsblobprodcus387.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)l49vsblobprodcus358.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)mobile.events.data.microsoft.com/usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.runtimeconfig.json --depsfile /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.deps.json /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/testhost.dll --port 46623 --endpoint 127.0.0.1:046623 --role client --parentprocessid 6323 --telemetryoptedin false(dns block)/usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.runtimeconfig.json --depsfile /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.deps.json /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/testhost.dll --port 40259 --endpoint 127.0.0.1:040259 --role client --parentprocessid 6599 --telemetryoptedin false(dns block)/usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.runtimeconfig.json --depsfile /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.deps.json /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/testhost.dll --port 42535 --endpoint 127.0.0.1:042535 --role client --parentprocessid 11560 --telemetryoptedin false(dns block)s4uvsblobprodcus326.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)u3hvsblobprodcus371.vsblob.vsassets.iodotnet build src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
Fixes #12330
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.