/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/Test2/Classification/ClassificationTests.vb
371 строка
17 KB
Tomáš Matoušek
Refactoring of extension methods in source packages (#78620) - take 2 (#78894)
26 июн 2025, 18:42
Не верифицирован
26 июн 2025, 18:42
05fc006
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable Imports System.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Classification Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.Editor.Shared.Extensions Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities Imports Microsoft.CodeAnalysis.Editor.Tagging Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.UnitTests Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Classification Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Classification <UseExportProvider> Public Class ClassificationTests <Fact, WorkItem("https://github.com/dotnet/roslyn/pull/66245")> Public Async Function TestClassificationAndHighlight1() As Task Using workspace = EditorTestWorkspace.Create( <Workspace> <Project Language="C#" AssemblyName="TestAssembly" CommonReferences="true"> <Document> using System.Text.RegularExpressions; class C { [| Regex |]re = new Regex("()"); } </Document> </Project> </Workspace>) Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() Dim text = Await document.GetTextAsync() Dim referenceSpan = workspace.Documents.Single().SelectedSpans.Single() Dim spansAndHighlightSpan = Await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync( New DocumentSpan(document, referenceSpan), classifiedSpans:=Nothing, ClassificationOptions.Default, CancellationToken.None) ' This is the classification of the line, starting at the beginning of the highlight, and going to the end of that line. Assert.Equal( "(text, '<spaces>', [154..155)) (class name, 'Regex', [155..160)) (text, '<spaces>', [160..161)) (field name, 're', [161..163)) (text, '<spaces>', [163..164)) (operator, '=', [164..165)) (text, '<spaces>', [165..166)) (keyword, 'new', [166..169)) (text, '<spaces>', [169..170)) (class name, 'Regex', [170..175)) (punctuation, '(', [175..176)) (string, '""', [176..177)) (regex - grouping, '(', [177..178)) (regex - grouping, ')', [178..179)) (string, '""', [179..180)) (punctuation, ')', [180..181)) (punctuation, ';', [181..182))", String.Join(vbCrLf, spansAndHighlightSpan.ClassifiedSpans.Select(Function(s) ToTestString(text, s)))) ' The portion of the classified spans to highlight goes from the start of the classified spans to the ' length of the original reference span. Assert.Equal(New TextSpan(0, referenceSpan.Length), spansAndHighlightSpan.HighlightSpan) End Using End Function <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65926")> Public Async Function TestEmbeddedClassifications1() As Task Using workspace = EditorTestWorkspace.Create( <Workspace> <Project Language="C#" AssemblyName="TestAssembly" CommonReferences="true"> <Document> using System.Text.RegularExpressions; class C { private Regex re = new Regex("()"); } </Document> </Project> </Workspace>) Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() Dim text = Await document.GetTextAsync() Dim spans = Await ClassifierHelper.GetClassifiedSpansAsync( document, New TextSpan(0, text.Length), ClassificationOptions.Default, includeAdditiveSpans:=False, CancellationToken.None) Assert.Equal( "(text, '<spaces>', [0..26)) (keyword, 'using', [26..31)) (text, '<spaces>', [31..32)) (namespace name, 'System', [32..38)) (operator, '.', [38..39)) (namespace name, 'Text', [39..43)) (operator, '.', [43..44)) (namespace name, 'RegularExpressions', [44..62)) (punctuation, ';', [62..63)) (text, '<spaces>', [63..91)) (keyword, 'class', [91..96)) (text, '<spaces>', [96..97)) (class name, 'C', [97..98)) (text, '<spaces>', [98..124)) (punctuation, '{', [124..125)) (text, '<spaces>', [125..155)) (keyword, 'private', [155..162)) (text, '<spaces>', [162..163)) (class name, 'Regex', [163..168)) (text, '<spaces>', [168..169)) (field name, 're', [169..171)) (text, '<spaces>', [171..172)) (operator, '=', [172..173)) (text, '<spaces>', [173..174)) (keyword, 'new', [174..177)) (text, '<spaces>', [177..178)) (class name, 'Regex', [178..183)) (punctuation, '(', [183..184)) (string, '""', [184..185)) (regex - grouping, '(', [185..186)) (regex - grouping, ')', [186..187)) (string, '""', [187..188)) (punctuation, ')', [188..189)) (punctuation, ';', [189..190)) (text, '<spaces>', [190..216)) (punctuation, '}', [216..217))", String.Join(vbCrLf, spans.Select(Function(s) ToTestString(text, s)))) End Using End Function <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63702")> Public Async Function TestEmbeddedClassifications2() As Task Using workspace = EditorTestWorkspace.Create( <Workspace> <Project Language="C#" AssemblyName="TestAssembly" CommonReferences="true"> <Document> class C { void B() => M("W\"X\tY\'Z"); void M(string s) { } } </Document> </Project> </Workspace>) Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() Dim text = Await document.GetTextAsync() Dim spans = Await ClassifierHelper.GetClassifiedSpansAsync( document, New TextSpan(0, text.Length), ClassificationOptions.Default, includeAdditiveSpans:=False, CancellationToken.None) Assert.Equal( "(text, '<spaces>', [0..26)) (keyword, 'class', [26..31)) (text, '<spaces>', [31..32)) (class name, 'C', [32..33)) (text, '<spaces>', [33..59)) (punctuation, '{', [59..60)) (text, '<spaces>', [60..90)) (keyword, 'void', [90..94)) (text, '<spaces>', [94..95)) (method name, 'B', [95..96)) (punctuation, '(', [96..97)) (punctuation, ')', [97..98)) (text, '<spaces>', [98..99)) (operator, '=>', [99..101)) (text, '<spaces>', [101..102)) (method name, 'M', [102..103)) (punctuation, '(', [103..104)) (string, '""W', [104..106)) (string - escape character, '\""', [106..108)) (string, 'X', [108..109)) (string - escape character, '\t', [109..111)) (string, 'Y', [111..112)) (string - escape character, '\'', [112..114)) (string, 'Z""', [114..116)) (punctuation, ')', [116..117)) (punctuation, ';', [117..118)) (text, '<spaces>', [118..148)) (keyword, 'void', [148..152)) (text, '<spaces>', [152..153)) (method name, 'M', [153..154)) (punctuation, '(', [154..155)) (keyword, 'string', [155..161)) (text, '<spaces>', [161..162)) (parameter name, 's', [162..163)) (punctuation, ')', [163..164)) (text, '<spaces>', [164..165)) (punctuation, '{', [165..166)) (text, '<spaces>', [166..167)) (punctuation, '}', [167..168)) (text, '<spaces>', [168..194)) (punctuation, '}', [194..195))", String.Join(vbCrLf, spans.Select(Function(s) ToTestString(text, s)))) End Using End Function <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66507")> Public Async Function TestUtf8StringSuffix() As Task Using workspace = EditorTestWorkspace.Create( <Workspace> <Project Language="C#" AssemblyName="TestAssembly" CommonReferences="true"> <Document> [|var v = "goo"u8;|] </Document> </Project> </Workspace>) Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() Dim text = Await document.GetTextAsync() Dim referenceSpan = workspace.Documents.Single().SelectedSpans.Single() Dim spansAndHighlightSpan = Await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync( New DocumentSpan(document, referenceSpan), classifiedSpans:=Nothing, ClassificationOptions.Default, CancellationToken.None) ' string classification should not overlap u8 classification. AssertEx.Equal( "(keyword, 'var', [26..29)) (text, '<spaces>', [29..30)) (local name, 'v', [30..31)) (text, '<spaces>', [31..32)) (operator, '=', [32..33)) (text, '<spaces>', [33..34)) (string, '""goo""', [34..39)) (keyword, 'u8', [39..41)) (punctuation, ';', [41..42))", String.Join(vbCrLf, spansAndHighlightSpan.ClassifiedSpans.Select(Function(s) ToTestString(text, s)))) End Using End Function Private Shared Function ToTestString(text As SourceText, span As ClassifiedSpan) As String Dim subText = text.ToString(span.TextSpan) Return $"({span.ClassificationType}, '{If(subText.Trim() = "", "<spaces>", subText)}', {span.TextSpan})" End Function <WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/13753")> Public Async Function TestSemanticClassificationWithoutSyntaxTree() As Task Dim workspaceDefinition = <Workspace> <Project Language="NoCompilation" AssemblyName="TestAssembly" CommonReferencesPortable="true"> <Document> var x = {}; // e.g., TypeScript code or anything else that doesn't support compilations </Document> </Project> </Workspace> Dim composition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeDefinitions), GetType(NoCompilationContentTypeLanguageService), GetType(NoCompilationEditorClassificationService)) Using workspace = EditorTestWorkspace.Create(workspaceDefinition, composition:=composition) Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim provider = New SemanticClassificationViewTaggerProvider( workspace.GetService(Of TaggerHost), workspace.GetService(Of ClassificationTypeMap)) Dim buffer = workspace.Documents.First().GetTextBuffer() Using tagger = provider.CreateTagger( workspace.Documents.First().GetTextView(), buffer) Using edit = buffer.CreateEdit() edit.Insert(0, " ") edit.Apply() End Using Await listenerProvider.GetWaiter(FeatureAttribute.Classification).ExpeditedWaitAsync() ' Note: we don't actually care what results we get back. We're just ' verifying that we don't crash because the SemanticViewTagger ends up ' calling SyntaxTree/SemanticModel code. tagger.GetTags(New NormalizedSnapshotSpanCollection( New SnapshotSpan(buffer.CurrentSnapshot, New Span(0, 1)))) End Using End Using End Function <WpfFact> Public Sub TestFailOverOfMissingClassificationType() Dim exportProvider = EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider() Dim typeMap = exportProvider.GetExportedValue(Of ClassificationTypeMap) Dim formatMap = exportProvider.GetExportedValue(Of IClassificationFormatMapService).GetClassificationFormatMap("tooltip") Dim classifiedText = New ClassifiedText("UnknownClassificationType", "dummy") Dim run = classifiedText.ToRun(formatMap, typeMap) Assert.NotNull(run) End Sub <WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/13753")> Public Async Function TestWrongDocument() As Task Dim workspaceDefinition = <Workspace> <Project Language="NoCompilation" AssemblyName="NoCompilationAssembly" CommonReferencesPortable="true"> <Document> var x = {}; // e.g., TypeScript code or anything else that doesn't support compilations </Document> </Project> <Project Language="C#" AssemblyName="CSharpAssembly" CommonReferencesPortable="true"> </Project> </Workspace> Dim composition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeLanguageService), GetType(NoCompilationContentTypeDefinitions)) Using workspace = EditorTestWorkspace.Create(workspaceDefinition, composition:=composition) Dim project = workspace.CurrentSolution.Projects.First(Function(p) p.Language = LanguageNames.CSharp) Dim classificationService = project.Services.GetService(Of IClassificationService)() Dim wrongDocument = workspace.CurrentSolution.Projects.First(Function(p) p.Language = "NoCompilation").Documents.First() Dim text = Await wrongDocument.GetTextAsync(CancellationToken.None) ' make sure we don't crash with wrong document Dim result = New SegmentedList(Of ClassifiedSpan)() Await classificationService.AddSyntacticClassificationsAsync(wrongDocument, New TextSpan(0, text.Length), result, CancellationToken.None) Await classificationService.AddSemanticClassificationsAsync(wrongDocument, New TextSpan(0, text.Length), options:=Nothing, result, CancellationToken.None) End Using End Function <ExportLanguageService(GetType(IClassificationService), NoCompilationConstants.LanguageName, ServiceLayer.Test), [Shared], PartNotDiscoverable> Private Class NoCompilationEditorClassificationService Implements IClassificationService <ImportingConstructor> <Obsolete(MefConstruction.ImportingConstructorMessage, True)> Public Sub New() End Sub Public Sub AddLexicalClassifications(text As SourceText, textSpan As TextSpan, result As SegmentedList(Of ClassifiedSpan), cancellationToken As CancellationToken) Implements IClassificationService.AddLexicalClassifications End Sub Public Sub AddSyntacticClassifications(services As SolutionServices, root As SyntaxNode, textSpans As ImmutableArray(Of TextSpan), result As SegmentedList(Of ClassifiedSpan), cancellationToken As CancellationToken) Implements IClassificationService.AddSyntacticClassifications End Sub Public Function AddSemanticClassificationsAsync(document As Document, textSpans As ImmutableArray(Of TextSpan), options As ClassificationOptions, result As SegmentedList(Of ClassifiedSpan), cancellationToken As CancellationToken) As Task Implements IClassificationService.AddSemanticClassificationsAsync Return Task.CompletedTask End Function Public Function AddSyntacticClassificationsAsync(document As Document, textSpans As ImmutableArray(Of TextSpan), result As SegmentedList(Of ClassifiedSpan), cancellationToken As CancellationToken) As Task Implements IClassificationService.AddSyntacticClassificationsAsync Return Task.CompletedTask End Function Public Function AdjustStaleClassification(text As SourceText, classifiedSpan As ClassifiedSpan) As ClassifiedSpan Implements IClassificationService.AdjustStaleClassification End Function Public Function ComputeSyntacticChangeRangeAsync(oldDocument As Document, newDocument As Document, timeout As TimeSpan, cancellationToken As CancellationToken) As ValueTask(Of TextChangeRange?) Implements IClassificationService.ComputeSyntacticChangeRangeAsync Return New ValueTask(Of TextChangeRange?) End Function Public Function ComputeSyntacticChangeRange(services As SolutionServices, oldRoot As SyntaxNode, newRoot As SyntaxNode, timeout As TimeSpan, cancellationToken As CancellationToken) As TextChangeRange? Implements IClassificationService.ComputeSyntacticChangeRange Return Nothing End Function Public Function AddEmbeddedLanguageClassificationsAsync(document As Document, textSpans As ImmutableArray(Of TextSpan), options As ClassificationOptions, result As SegmentedList(Of ClassifiedSpan), cancellationToken As CancellationToken) As Task Implements IClassificationService.AddEmbeddedLanguageClassificationsAsync Return Task.CompletedTask End Function End Class End Class End Namespace