Skip to content

Commit ed087cc

Browse files
committed
More semantic update changes
1 parent f733ba8 commit ed087cc

19 files changed

+194
-18
lines changed

eng/config/PublishData.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
"Microsoft.CodeAnalysis.Remote.Razor.ServiceHub": "vs-impl",
9595
"Microsoft.CodeAnalysis.Remote.ServiceHub": "vs-impl",
9696
"Microsoft.CodeAnalysis.Remote.Workspaces": "vs-impl",
97+
"Microsoft.CodeAnalysis.SemanticSearch.Extensions": "vs-impl",
9798
"Microsoft.CodeAnalysis.SemanticSearch.ReferenceAssemblies": "vs-impl",
9899
"Microsoft.VisualStudio.LanguageServices.LiveShare": "vs-impl",
99100
"Microsoft.VisualStudio.LanguageServices.Razor.RemoteClient": "vs-impl",

src/EditorFeatures/Core/SemanticSearch/SemanticSearchEditorWorkspace.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ internal sealed class SemanticSearchEditorWorkspace(
2626
private ITextBuffer? _queryTextBuffer;
2727
private DocumentId? _queryDocumentId;
2828

29-
public async Task OpenQueryDocumentAsync(ITextBuffer buffer, CancellationToken cancellationToken)
29+
public async Task OpenQueryDocumentAsync(ITextBuffer buffer, string? targetLanguage, CancellationToken cancellationToken)
3030
{
3131
_queryTextBuffer = buffer;
3232

3333
// initialize solution with default query, unless it has already been initialized:
34-
var queryDocument = await UpdateQueryDocumentAsync(query: null, cancellationToken).ConfigureAwait(false);
34+
var queryDocument = await UpdateQueryDocumentAsync(query: null, targetLanguage, cancellationToken).ConfigureAwait(false);
3535

3636
_queryDocumentId = queryDocument.Id;
3737

src/Features/Core/Portable/SemanticSearch/ISemanticSearchResultsObserver.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ internal interface ISemanticSearchResultsCommonObserver
3232
internal interface ISemanticSearchResultsObserver : ISemanticSearchResultsCommonObserver
3333
{
3434
ValueTask OnSymbolFoundAsync(Solution solution, ISymbol symbol, CancellationToken cancellationToken);
35+
ValueTask OnSyntaxNodeFoundAsync(Document document, SyntaxNode node, CancellationToken cancellationToken);
36+
ValueTask OnLocationFoundAsync(Solution solution, Location location, CancellationToken cancellationToken);
37+
ValueTask OnValueFoundAsync(Solution solution, object value, CancellationToken cancellationToken);
3538
}
3639

3740
internal interface ISemanticSearchResultsDefinitionObserver : ISemanticSearchResultsCommonObserver

src/Features/Core/Portable/SemanticSearch/ISemanticSearchSolutionService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ internal interface ISemanticSearchSolutionService
2121
/// </summary>
2222
/// <param name="solution">Original solution.</param>
2323
/// <param name="query">New query, or null to use default query.</param>
24+
/// <param name="targetLanguage">Language of the target projects the query executes against, or null if it should execute against all supported projects.</param>
2425
/// <param name="referenceAssembliesDir">Directory containing reference assemblies.</param>
25-
Solution SetQueryText(Solution solution, string? query, string referenceAssembliesDir);
26+
Solution SetQueryText(Solution solution, string? query, string? targetLanguage, string referenceAssembliesDir);
2627

2728
(WorkspaceChangeKind changeKind, ProjectId? projectId, DocumentId? documentId) GetWorkspaceChangeKind(Solution oldSolution, Solution newSolution);
2829
}

src/Features/Core/Portable/SemanticSearch/SemanticSearchDefinitionItemFactory.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
6+
using System.Collections.Immutable;
57
using System.Threading;
68
using System.Threading.Tasks;
79
using Microsoft.CodeAnalysis.Classification;
810
using Microsoft.CodeAnalysis.FindSymbols;
911
using Microsoft.CodeAnalysis.FindUsages;
12+
using Microsoft.CodeAnalysis.Text;
1013

1114
namespace Microsoft.CodeAnalysis.SemanticSearch;
1215

@@ -17,7 +20,63 @@ internal static class SemanticSearchDefinitionItemFactory
1720
DisplayAllDefinitions = true,
1821
};
1922

23+
public static DefinitionItem Create(string text)
24+
{
25+
var displayStr = Clip(text, maxLength: 100);
26+
var displayText = new TaggedText(TextTags.Text, displayStr);
27+
28+
return DefinitionItem.CreateNonNavigableItem(
29+
tags: [],
30+
displayParts: text.Length == displayStr.Length ? [displayText] : [displayText, new TaggedText(TextTags.Punctuation, "…")]);
31+
}
32+
2033
public static ValueTask<DefinitionItem> CreateAsync(Solution solution, ISymbol symbol, OptionsProvider<ClassificationOptions> classificationOptions, CancellationToken cancellationToken)
2134
=> symbol.ToClassifiedDefinitionItemAsync(
2235
classificationOptions, solution, s_findReferencesSearchOptions, isPrimary: true, includeHiddenLocations: false, cancellationToken);
36+
37+
public static ValueTask<DefinitionItem> CreateAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
38+
=> CreateItemAsync(document, node.FullSpan, cancellationToken);
39+
40+
public static async ValueTask<DefinitionItem?> CreateAsync(Solution solution, Location location, CancellationToken cancellationToken)
41+
{
42+
if (location.MetadataModule is { } module)
43+
{
44+
var metadataLocation = DefinitionItemFactory.GetMetadataLocation(module.ContainingAssembly, solution, out var originatingProjectId);
45+
46+
return DefinitionItem.Create(
47+
tags: [],
48+
displayParts: [],
49+
sourceSpans: [],
50+
classifiedSpans: [],
51+
metadataLocations: [metadataLocation],
52+
properties: ImmutableDictionary<string, string>.Empty.WithMetadataSymbolProperties(module.ContainingAssembly, originatingProjectId));
53+
}
54+
55+
if (solution.GetDocument(location.SourceTree) is { } document)
56+
{
57+
return await CreateItemAsync(document, location.SourceSpan, cancellationToken).ConfigureAwait(false);
58+
}
59+
60+
return null;
61+
}
62+
63+
private static async ValueTask<DefinitionItem> CreateItemAsync(Document document, TextSpan span, CancellationToken cancellationToken)
64+
{
65+
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
66+
var displaySpan = Clip(span, maxLength: 100);
67+
var displayText = new TaggedText(TextTags.Text, text.ToString(displaySpan));
68+
69+
return DefinitionItem.Create(
70+
tags: [],
71+
displayParts: displaySpan.Length == span.Length ? [displayText] : [displayText, new TaggedText(TextTags.Punctuation, "…")],
72+
sourceSpans: [new DocumentSpan(document, span)],
73+
classifiedSpans: [],
74+
metadataLocations: []);
75+
}
76+
77+
private static TextSpan Clip(TextSpan span, int maxLength)
78+
=> new(span.Start, Math.Min(span.Length, maxLength));
79+
80+
private static string Clip(string str, int maxLength)
81+
=> str[0..Math.Min(str.Length, maxLength)];
2382
}

src/Features/Core/Portable/SemanticSearch/SemanticSearchWorkspace.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public override bool CanOpenDocuments
2626
public override bool CanApplyChange(ApplyChangesKind feature)
2727
=> feature == ApplyChangesKind.ChangeDocument;
2828

29-
public async Task<Document> UpdateQueryDocumentAsync(string? query, CancellationToken cancellationToken)
29+
public async Task<Document> UpdateQueryDocumentAsync(string? query, string? targetLanguage, CancellationToken cancellationToken)
3030
{
3131
var (updated, newSolution) = await this.SetCurrentSolutionAsync(
3232
useAsync: true,
33-
transformation: oldSolution => solutionService.SetQueryText(oldSolution, query, ReferenceAssembliesDirectory),
33+
transformation: oldSolution => solutionService.SetQueryText(oldSolution, query, targetLanguage, ReferenceAssembliesDirectory),
3434
changeKind: solutionService.GetWorkspaceChangeKind,
3535
onBeforeUpdate: null,
3636
onAfterUpdate: null,

src/Features/ExternalAccess/Copilot/Internal/SemanticSearch/CopilotSemanticSearchQueryService.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Immutable;
67
using System.Composition;
78
using System.Diagnostics;
89
using System.Threading;
@@ -11,6 +12,8 @@
1112
using Microsoft.CodeAnalysis.Host;
1213
using Microsoft.CodeAnalysis.Host.Mef;
1314
using Microsoft.CodeAnalysis.SemanticSearch;
15+
using Microsoft.CodeAnalysis.SolutionExplorer;
16+
using Microsoft.CodeAnalysis.Text;
1417

1518
namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Internal.SemanticSearch;
1619

@@ -22,15 +25,24 @@ internal sealed class CopilotSemanticSearchQueryService(
2225
{
2326
private sealed class CopilotObserver(ISemanticSearchResultsObserver observer) : ICopilotSemanticSearchResultsObserver
2427
{
28+
public ValueTask OnLocationFoundAsync(Solution solution, Location location, CancellationToken cancellationToken)
29+
=> observer.OnLocationFoundAsync(solution, location, cancellationToken);
30+
31+
public ValueTask OnSymbolFoundAsync(Solution solution, ISymbol symbol, CancellationToken cancellationToken)
32+
=> observer.OnSymbolFoundAsync(solution, symbol, cancellationToken);
33+
34+
public ValueTask OnSyntaxNodeFoundAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
35+
=> observer.OnSyntaxNodeFoundAsync(document, node, cancellationToken);
36+
37+
public ValueTask OnValueFoundAsync(Solution solution, object value, CancellationToken cancellationToken)
38+
=> observer.OnValueFoundAsync(solution, value, cancellationToken);
39+
2540
public ValueTask AddItemsAsync(int itemCount, CancellationToken cancellationToken)
2641
=> observer.AddItemsAsync(itemCount, cancellationToken);
2742

2843
public ValueTask ItemsCompletedAsync(int itemCount, CancellationToken cancellationToken)
2944
=> observer.ItemsCompletedAsync(itemCount, cancellationToken);
3045

31-
public ValueTask OnSymbolFoundAsync(Solution solution, ISymbol symbol, CancellationToken cancellationToken)
32-
=> observer.OnSymbolFoundAsync(solution, symbol, cancellationToken);
33-
3446
public ValueTask OnUserCodeExceptionAsync(ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo info, CancellationToken cancellationToken)
3547
=> observer.OnUserCodeExceptionAsync(
3648
new UserCodeExceptionInfo(
@@ -40,6 +52,15 @@ public ValueTask OnUserCodeExceptionAsync(ICopilotSemanticSearchResultsObserver.
4052
info.StackTrace,
4153
info.Span),
4254
cancellationToken);
55+
56+
public ValueTask OnDocumentUpdatedAsync(DocumentId documentId, ImmutableArray<TextChange> changes, CancellationToken cancellationToken)
57+
=> observer.OnDocumentUpdatedAsync(documentId, changes, cancellationToken);
58+
59+
public ValueTask OnTextFileUpdatedAsync(string filePath, string? newContent, CancellationToken cancellationToken)
60+
=> observer.OnTextFileUpdatedAsync(filePath, newContent, cancellationToken);
61+
62+
public ValueTask OnLogMessageAsync(string message, CancellationToken cancellationToken)
63+
=> observer.OnLogMessageAsync(message, cancellationToken);
4364
}
4465

4566
public CompileQueryResult CompileQuery(SolutionServices services, string query, string? targetLanguage, string referenceAssembliesDir, TraceSource traceSource, CancellationToken cancellationToken)

src/Features/ExternalAccess/Copilot/Internal/SemanticSearch/CopilotSemanticSearchSolutionService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ public DocumentId GetQueryDocumentId(Solution solution)
3131
public (WorkspaceChangeKind changeKind, ProjectId? projectId, DocumentId? documentId) GetWorkspaceChangeKind(Solution oldSolution, Solution newSolution)
3232
=> GetImpl().GetWorkspaceChangeKind(oldSolution, newSolution);
3333

34-
public Solution SetQueryText(Solution solution, string? query, string referenceAssembliesDir)
35-
=> GetImpl().SetQueryText(solution, query, referenceAssembliesDir);
34+
public Solution SetQueryText(Solution solution, string? query, string? targetLanguage, string referenceAssembliesDir)
35+
=> GetImpl().SetQueryText(solution, query, targetLanguage, referenceAssembliesDir);
3636
}

src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,14 @@ Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSea
155155
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver
156156
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.AddItemsAsync(int itemCount, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
157157
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.ItemsCompletedAsync(int itemCount, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
158+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnDocumentUpdatedAsync(Microsoft.CodeAnalysis.DocumentId! documentId, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Text.TextChange> changes, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
159+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnLocationFoundAsync(Microsoft.CodeAnalysis.Solution! solution, Microsoft.CodeAnalysis.Location! location, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
160+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnLogMessageAsync(string! message, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
158161
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnSymbolFoundAsync(Microsoft.CodeAnalysis.Solution! solution, Microsoft.CodeAnalysis.ISymbol! symbol, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
162+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnSyntaxNodeFoundAsync(Microsoft.CodeAnalysis.Document! document, Microsoft.CodeAnalysis.SyntaxNode! node, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
163+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnTextFileUpdatedAsync(string! filePath, string? newContent, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
159164
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnUserCodeExceptionAsync(Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo exception, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
165+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.OnValueFoundAsync(Microsoft.CodeAnalysis.Solution! solution, object! value, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
160166
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo
161167
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo.Deconstruct(out string! ProjectDisplayName, out string! Message, out System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.TaggedText> TypeName, out System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.TaggedText> StackTrace, out Microsoft.CodeAnalysis.Text.TextSpan Span) -> void
162168
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo.Equals(Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchResultsObserver.UserCodeExceptionInfo other) -> bool
@@ -176,7 +182,7 @@ Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSea
176182
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchSolutionService.GetQueryDocumentFilePath() -> string!
177183
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchSolutionService.GetQueryDocumentId(Microsoft.CodeAnalysis.Solution! solution) -> Microsoft.CodeAnalysis.DocumentId!
178184
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchSolutionService.GetWorkspaceChangeKind(Microsoft.CodeAnalysis.Solution! oldSolution, Microsoft.CodeAnalysis.Solution! newSolution) -> (Microsoft.CodeAnalysis.WorkspaceChangeKind changeKind, Microsoft.CodeAnalysis.ProjectId? projectId, Microsoft.CodeAnalysis.DocumentId? documentId)
179-
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchSolutionService.SetQueryText(Microsoft.CodeAnalysis.Solution! solution, string? query, string! referenceAssembliesDir) -> Microsoft.CodeAnalysis.Solution!
185+
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ICopilotSemanticSearchSolutionService.SetQueryText(Microsoft.CodeAnalysis.Solution! solution, string? query, string? targetLanguage, string! referenceAssembliesDir) -> Microsoft.CodeAnalysis.Solution!
180186
Microsoft.CodeAnalysis.SemanticSearch.SemanticSearchCopilotServiceWrapper
181187
Microsoft.CodeAnalysis.SemanticSearch.SemanticSearchCopilotServiceWrapper.SemanticSearchCopilotServiceWrapper(System.Lazy<Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ISemanticSearchCopilotServiceImpl!>? impl) -> void
182188
override Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.CodeSnippetItem.Equals(object? obj) -> bool
@@ -203,6 +209,7 @@ static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.GetContain
203209
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.GetCopilotSuggestionDiagnosticTag() -> string!
204210
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.IsResultantVisibilityPublic(this Microsoft.CodeAnalysis.ISymbol! symbol) -> bool
205211
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.IsValidIdentifier(string? name) -> bool
212+
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.CopilotSemanticSearchUtilities.CanApplyChange(Microsoft.CodeAnalysis.TextDocument! document) -> bool
206213
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.CopilotSemanticSearchUtilities.CreateSyntaxTree(Microsoft.CodeAnalysis.Host.SolutionServices! services, string! language, string? filePath, Microsoft.CodeAnalysis.ParseOptions! options, Microsoft.CodeAnalysis.Text.SourceText? text, System.Text.Encoding? encoding, Microsoft.CodeAnalysis.Text.SourceHashAlgorithm checksumAlgorithm, Microsoft.CodeAnalysis.SyntaxNode! root) -> Microsoft.CodeAnalysis.SyntaxTree!
207214
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.CopilotSemanticSearchUtilities.FindNode(this Microsoft.CodeAnalysis.Location! location, bool findInsideTrivia, bool getInnermostNodeForTie, System.Threading.CancellationToken cancellationToken) -> Microsoft.CodeAnalysis.SyntaxNode!
208215
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.CopilotSemanticSearchUtilities.FindReferencesAsync(Microsoft.CodeAnalysis.Solution! solution, Microsoft.CodeAnalysis.ISymbol! symbol, System.Action<Microsoft.CodeAnalysis.FindSymbols.ReferenceLocation>! callback, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!

src/Features/ExternalAccess/Copilot/SemanticSearch/CopilotSemanticSearchUtilities.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public static Task FindReferencesAsync(Solution solution, ISymbol symbol, Action
4646
=> SymbolFinder.FindReferencesAsync(
4747
symbol, solution, new Progress(callback), documents: null, s_options, cancellationToken);
4848

49+
public static bool CanApplyChange(TextDocument document)
50+
=> document.CanApplyChange();
51+
4952
private sealed class Progress(Action<ReferenceLocation> callback) : IStreamingFindReferencesProgress
5053
{
5154
public ValueTask OnStartedAsync(CancellationToken cancellationToken) => ValueTask.CompletedTask;

0 commit comments

Comments
 (0)