From 416433604f93e6abe51994f761662d54cbebffe1 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Tue, 7 Dec 2021 22:40:52 -0800 Subject: [PATCH] Allow for alternate versions of documents to be semantically highlighted --- .../SemanticHighlightRequest.cs | 11 +++- .../SemanticHighlightService.cs | 9 ++- .../SemanticHighlightFacts.cs | 56 ++++++++++++++++--- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/OmniSharp.Abstractions/Models/v2/SemanticHighlight/SemanticHighlightRequest.cs b/src/OmniSharp.Abstractions/Models/v2/SemanticHighlight/SemanticHighlightRequest.cs index 249ec7b98f..afc08bc86d 100644 --- a/src/OmniSharp.Abstractions/Models/v2/SemanticHighlight/SemanticHighlightRequest.cs +++ b/src/OmniSharp.Abstractions/Models/v2/SemanticHighlight/SemanticHighlightRequest.cs @@ -7,10 +7,15 @@ namespace OmniSharp.Models.SemanticHighlight public class SemanticHighlightRequest : Request { /// - /// Specifies the range to highlight. - /// If none is given, highlight the entire - /// file. + /// Specifies the range to highlight. If none is given, highlight the entire file. /// public Range Range { get; set; } + + /// + /// Optionally provide the text for a different version of the document to be highlighted. + /// This property works differently than the Buffer property, since it is only used for + /// highlighting and will not update the document in the CurrentSolution. + /// + public string VersionedText { get; set; } } } diff --git a/src/OmniSharp.Roslyn.CSharp/Services/SemanticHighlight/SemanticHighlightService.cs b/src/OmniSharp.Roslyn.CSharp/Services/SemanticHighlight/SemanticHighlightService.cs index 3f93d0ba4e..80126f8fea 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/SemanticHighlight/SemanticHighlightService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/SemanticHighlight/SemanticHighlightService.cs @@ -33,7 +33,12 @@ public async Task Handle(SemanticHighlightRequest req foreach (var document in documents) { var project = document.Project.Name; - var text = await document.GetTextAsync(); + + var highlightDocument = request.VersionedText != null + ? document.WithText(SourceText.From(request.VersionedText)) + : document; + + var text = await highlightDocument.GetTextAsync(); TextSpan textSpan; if (request.Range is object) @@ -55,7 +60,7 @@ public async Task Handle(SemanticHighlightRequest req textSpan = new TextSpan(0, text.Length); } - results.AddRange((await Classifier.GetClassifiedSpansAsync(document, textSpan)) + results.AddRange((await Classifier.GetClassifiedSpansAsync(highlightDocument, textSpan)) .Select(span => new ClassifiedResult() { Span = span, diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SemanticHighlightFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SemanticHighlightFacts.cs index 771ab24e47..a9606c13fe 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SemanticHighlightFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SemanticHighlightFacts.cs @@ -31,7 +31,7 @@ class C1 { int n = true; } "); var line = -1; - var highlights = await GetSemanticHighlightsForLineAsync(testFile, line); + var highlights = await GetSemanticHighlightsForLineAsync(testFile, line, versionedText: null); Assert.Empty(highlights); } @@ -47,7 +47,7 @@ class C1 { int n = true; } "); var line = 3; - var highlights = await GetSemanticHighlightsForLineAsync(testFile, line); + var highlights = await GetSemanticHighlightsForLineAsync(testFile, line, versionedText: null); AssertSyntax(highlights, testFile.Content.Code, line, Keyword("class"), @@ -90,6 +90,42 @@ class C1 { int n = true; } ); } + [Fact] + public async Task SemanticHighlightEntireFileWithVersionedText() + { + var testFile = new TestFile("a.cs", @" +namespace N1 +{ + class C1 { int n = true; } +} +"); + var versionedText = @" +namespace N1 +{ + class C { int n = false; } +} +"; + + var highlights = await GetSemanticHighlightsForFileAsync(testFile, versionedText); + + AssertSyntax(highlights, versionedText, 0, + Keyword("namespace"), + NamespaceName("N1"), + Punctuation("{"), + Keyword("class"), + ClassName("C"), + Punctuation("{"), + Keyword("int"), + Field("n"), + Operator("="), + Keyword("false"), + Punctuation(";"), + Punctuation("}"), + Punctuation("}") + ); + } + + [Fact] public async Task SemanticHighlightStringInterpolation() { @@ -317,10 +353,15 @@ record struct R1(string S, int I); private Task GetSemanticHighlightsForFileAsync(TestFile testFile) { - return GetSemanticHighlightsAsync(testFile, range: null); + return GetSemanticHighlightsAsync(testFile, range: null, versionedText: null); + } + + private Task GetSemanticHighlightsForFileAsync(TestFile testFile, string versionedText) + { + return GetSemanticHighlightsAsync(testFile, range: null, versionedText); } - private Task GetSemanticHighlightsForLineAsync(TestFile testFile, int line) + private Task GetSemanticHighlightsForLineAsync(TestFile testFile, int line, string versionedText) { var range = new Range() { @@ -328,17 +369,18 @@ private Task GetSemanticHighlightsForLineAsync(TestFile End = new Point() { Column = 0, Line = line + 1 } }; - return GetSemanticHighlightsAsync(testFile, range); + return GetSemanticHighlightsAsync(testFile, range, versionedText); } - private async Task GetSemanticHighlightsAsync(TestFile testFile, Range range) + private async Task GetSemanticHighlightsAsync(TestFile testFile, Range range, string versionedText) { SharedOmniSharpTestHost.AddFilesToWorkspace(testFile); var requestHandler = GetRequestHandler(SharedOmniSharpTestHost); var request = new SemanticHighlightRequest { FileName = testFile.FileName, - Range = range + Range = range, + VersionedText = versionedText, }; var response = await requestHandler.Handle(request);