From 675b0dfb9bdc5c6d48d7750cb47d3f31a1b056af Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 15 Oct 2025 09:57:12 +1100 Subject: [PATCH 1/3] Create failing test --- .../SemanticTokens/RazorComponents.txt | 69 +++++++++++++++++++ .../RazorComponents_misc_file.txt | 69 +++++++++++++++++++ .../RazorComponents_with_background.txt | 69 +++++++++++++++++++ ...orComponents_with_background_misc_file.txt | 69 +++++++++++++++++++ .../CohostSemanticTokensRangeEndpointTest.cs | 17 +++++ .../SemanticTokens/RazorComponents.txt | 69 +++++++++++++++++++ .../RazorComponents_misc_file.txt | 69 +++++++++++++++++++ .../RazorComponents_with_background.txt | 69 +++++++++++++++++++ ...orComponents_with_background_misc_file.txt | 69 +++++++++++++++++++ 9 files changed, 569 insertions(+) create mode 100644 src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents.txt create mode 100644 src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt create mode 100644 src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt create mode 100644 src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt create mode 100644 src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents.txt create mode 100644 src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt create mode 100644 src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt create mode 100644 src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents.txt b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents.txt new file mode 100644 index 00000000000..79373585584 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 razorComponentElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 class name [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method name [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] +1 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 namespace name [] [Microsoft] +0 9 1 operator [] [.] +0 1 10 namespace name [] [AspNetCore] +0 10 1 operator [] [.] +0 1 10 namespace name [] [Components] +0 10 1 operator [] [.] +0 1 5 namespace name [] [Forms] +0 5 1 operator [] [.] +0 1 9 class name [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method name [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt new file mode 100644 index 00000000000..dfeceace673 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 markupElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 variable [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method name [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] +1 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 namespace name [] [Microsoft] +0 9 1 operator [] [.] +0 1 10 variable [] [AspNetCore] +0 10 1 operator [] [.] +0 1 10 variable [] [Components] +0 10 1 operator [] [.] +0 1 5 variable [] [Forms] +0 5 1 operator [] [.] +0 1 9 variable [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method name [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt new file mode 100644 index 00000000000..70e0ef908b9 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 razorComponentElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 class name [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method name [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] +1 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 namespace name [razorCode] [Microsoft] +0 9 1 operator [razorCode] [.] +0 1 10 namespace name [razorCode] [AspNetCore] +0 10 1 operator [razorCode] [.] +0 1 10 namespace name [razorCode] [Components] +0 10 1 operator [razorCode] [.] +0 1 5 namespace name [razorCode] [Forms] +0 5 1 operator [razorCode] [.] +0 1 9 class name [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method name [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt new file mode 100644 index 00000000000..7ae31783f99 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 markupElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 variable [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method name [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] +1 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 namespace name [razorCode] [Microsoft] +0 9 1 operator [razorCode] [.] +0 1 10 variable [razorCode] [AspNetCore] +0 10 1 operator [razorCode] [.] +0 1 10 variable [razorCode] [Components] +0 10 1 operator [razorCode] [.] +0 1 5 variable [razorCode] [Forms] +0 5 1 operator [razorCode] [.] +0 1 9 variable [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method name [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostSemanticTokensRangeEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostSemanticTokensRangeEndpointTest.cs index 806d69b0e92..73b37005b22 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostSemanticTokensRangeEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostSemanticTokensRangeEndpointTest.cs @@ -20,6 +20,23 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; public class CohostSemanticTokensRangeEndpointTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper) { + [Theory] + [CombinatorialData] + public async Task RazorComponents(bool colorBackground, bool miscellaneousFile) + { + var input = """ + + + + + + @typeof(InputText).ToString() + @typeof(Microsoft.AspNetCore.Components.Forms.InputText).ToString() + """; + + await VerifySemanticTokensAsync(input, colorBackground, miscellaneousFile); + } + [Theory] [CombinatorialData] public async Task Razor(bool colorBackground, bool miscellaneousFile) diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents.txt b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents.txt new file mode 100644 index 00000000000..729ec4f8992 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 razorComponentElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 class [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] +1 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 namespace [] [Microsoft] +0 9 1 operator [] [.] +0 1 10 namespace [] [AspNetCore] +0 10 1 operator [] [.] +0 1 10 namespace [] [Components] +0 10 1 operator [] [.] +0 1 5 namespace [] [Forms] +0 5 1 operator [] [.] +0 1 9 class [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt new file mode 100644 index 00000000000..344aa6e5a99 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_misc_file.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 markupElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 variable [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] +1 0 1 razorTransition [] [@] +0 1 6 keyword [] [typeof] +0 6 1 punctuation [] [(] +0 1 9 namespace [] [Microsoft] +0 9 1 operator [] [.] +0 1 10 variable [] [AspNetCore] +0 10 1 operator [] [.] +0 1 10 variable [] [Components] +0 10 1 operator [] [.] +0 1 5 variable [] [Forms] +0 5 1 operator [] [.] +0 1 9 variable [] [InputText] +0 9 1 punctuation [] [)] +0 1 1 operator [] [.] +0 1 8 method [] [ToString] +0 8 1 punctuation [] [(] +0 1 1 punctuation [] [)] diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt new file mode 100644 index 00000000000..1b8e3c533bd --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 razorComponentElement [] [InputText] +0 10 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 razorComponentElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 razorComponentAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 razorComponentElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 class [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] +1 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 namespace [razorCode] [Microsoft] +0 9 1 operator [razorCode] [.] +0 1 10 namespace [razorCode] [AspNetCore] +0 10 1 operator [razorCode] [.] +0 1 10 namespace [razorCode] [Components] +0 10 1 operator [razorCode] [.] +0 1 5 namespace [razorCode] [Forms] +0 5 1 operator [razorCode] [.] +0 1 9 class [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt new file mode 100644 index 00000000000..d8b85cd0a86 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/TestFiles/SemanticTokens/RazorComponents_with_background_misc_file.txt @@ -0,0 +1,69 @@ +Line Δ, Char Δ, Length, Type, Modifier(s), Text +0 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 9 markupElement [] [InputText] +0 10 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 9 markupElement [] [InputText] +0 9 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 2 1 markupTagDelimiter [] [/] +0 1 1 markupTagDelimiter [] [>] +1 0 1 markupTagDelimiter [] [<] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 48 5 markupAttribute [] [Value] +0 5 1 markupOperator [] [=] +0 1 1 markupAttributeQuote [] ["] +0 1 9 markupAttributeValue [] [someValue] +0 9 1 markupAttributeQuote [] ["] +0 1 1 markupTagDelimiter [] [>] +0 1 1 markupTagDelimiter [] [<] +0 1 1 markupTagDelimiter [] [/] +0 1 47 markupElement [] [Microsoft.AspNetCore.Components.Forms.InputText] +0 47 1 markupTagDelimiter [] [>] +2 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 variable [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] +1 0 1 razorTransition [razorCode] [@] +0 1 6 keyword [razorCode] [typeof] +0 6 1 punctuation [razorCode] [(] +0 1 9 namespace [razorCode] [Microsoft] +0 9 1 operator [razorCode] [.] +0 1 10 variable [razorCode] [AspNetCore] +0 10 1 operator [razorCode] [.] +0 1 10 variable [razorCode] [Components] +0 10 1 operator [razorCode] [.] +0 1 5 variable [razorCode] [Forms] +0 5 1 operator [razorCode] [.] +0 1 9 variable [razorCode] [InputText] +0 9 1 punctuation [razorCode] [)] +0 1 1 operator [razorCode] [.] +0 1 8 method [razorCode] [ToString] +0 8 1 punctuation [razorCode] [(] +0 1 1 punctuation [razorCode] [)] From 769d151d545eddeb7b3cc7404d71fd90806039c9 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 15 Oct 2025 11:19:45 +1100 Subject: [PATCH 2/3] Allow Razor ranges to overlap multiple C# ranges --- .../AbstractRazorSemanticTokensInfoService.cs | 19 ++++++++++++---- .../SemanticTokens/SemanticRange.cs | 22 ++++++++++--------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs index bebeef99665..58d31c092d9 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs @@ -338,14 +338,25 @@ static bool TryWriteToken( int deltaStart; if (!isFirstRange && previousRange.StartLine == currentRange.StartLine) { - deltaStart = currentRange.StartCharacter - previousRange.StartCharacter; + // If the current range overlaps the previous one, we assume the sort order was + // correct, and prefer the previous range. We have a check for the start character first + // just in case there is a C# range that extends past a Razor range. There is no known case + // for this, but we need to make sure we don't report bad data. + if (previousRange.StartCharacter == currentRange.StartCharacter) + { + return false; + } - // If there is no line delta, no char delta, and this isn't the first range - // then it means this range overlaps the previous, so we skip it. - if (deltaStart == 0) + // Razor ranges are allowed to extend past C# ranges though, so we need to check for that too. + if (previousRange.StartCharacter <= currentRange.StartCharacter && + previousRange.EndCharacter >= currentRange.EndCharacter) { return false; } + + deltaStart = currentRange.StartCharacter - previousRange.StartCharacter; + + Debug.Assert(deltaStart > 0, "There is no char delta which means this span overlaps the previous. This should have been filtered out!"); } else { diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/SemanticRange.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/SemanticRange.cs index f7c6602112a..a5b84c35a4d 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/SemanticRange.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/SemanticRange.cs @@ -70,6 +70,18 @@ public int CompareTo(SemanticRange other) return result; } + // If the start positions are the same, and one is Razor and one isn't, we prefer Razor. This allows a Razor + // produced token to win over multiple C# tokens, for example the tag name in "" is one + // Razor classification (for component) but multiple C# classifications (2 namespaces and a type name) + if (FromRazor && !other.FromRazor) + { + return -1; + } + else if (other.FromRazor && !FromRazor) + { + return 1; + } + result = EndLine.CompareTo(other.EndLine); if (result != 0) { @@ -82,16 +94,6 @@ public int CompareTo(SemanticRange other) return result; } - // If we have ranges that are the same, we want a Razor produced token to win over a non-Razor produced token - if (FromRazor && !other.FromRazor) - { - return -1; - } - else if (other.FromRazor && !FromRazor) - { - return 1; - } - return 0; } From 0c9b5c098c931d687010d9fb9b060b3400d81f65 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 16 Oct 2025 07:51:17 +1100 Subject: [PATCH 3/3] Check endline too --- .../SemanticTokens/AbstractRazorSemanticTokensInfoService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs index 58d31c092d9..d2753817fc1 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SemanticTokens/AbstractRazorSemanticTokensInfoService.cs @@ -349,7 +349,7 @@ static bool TryWriteToken( // Razor ranges are allowed to extend past C# ranges though, so we need to check for that too. if (previousRange.StartCharacter <= currentRange.StartCharacter && - previousRange.EndCharacter >= currentRange.EndCharacter) + (previousRange.EndCharacter >= currentRange.EndCharacter || previousRange.EndLine > currentRange.EndLine)) { return false; }