Skip to content

Commit e783b50

Browse files
authored
Fix completion resolve for provisional completion (#12403)
2 parents bb00268 + ed6839b commit e783b50

File tree

7 files changed

+34
-13
lines changed

7 files changed

+34
-13
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionListProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ internal class DelegatedCompletionListProvider(
116116
? DelegatedCompletionHelper.RewriteCSharpResponse(delegatedResponse, absoluteIndex, codeDocument, positionInfo.Position, razorCompletionOptions)
117117
: DelegatedCompletionHelper.RewriteHtmlResponse(delegatedResponse, razorCompletionOptions);
118118

119-
var resolutionContext = new DelegatedCompletionResolutionContext(identifier, positionInfo.LanguageKind, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data);
119+
var resolutionContext = new DelegatedCompletionResolutionContext(identifier, positionInfo.LanguageKind, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data, provisionalTextEdit);
120120
var resultId = _completionListCache.Add(rewrittenResponse, resolutionContext);
121121
rewrittenResponse.SetResultId(resultId, clientCapabilities);
122122

src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Completion/CohostDocumentCompletionEndpoint.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ public ImmutableArray<Registration> GetRegistrations(VSInternalClientCapabilitie
234234
var rewrittenResponse = DelegatedCompletionHelper.RewriteHtmlResponse(result, razorCompletionOptions);
235235

236236
var razorDocumentIdentifier = new TextDocumentIdentifierAndVersion(completionParams.TextDocument, Version: 0);
237-
var resolutionContext = new DelegatedCompletionResolutionContext(razorDocumentIdentifier, RazorLanguageKind.Html, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data);
237+
var resolutionContext = new DelegatedCompletionResolutionContext(razorDocumentIdentifier, RazorLanguageKind.Html, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data, ProvisionalTextEdit: null);
238238
var resultId = _completionListCache.Add(rewrittenResponse, resolutionContext);
239239
rewrittenResponse.SetResultId(resultId, _clientCapabilitiesService.ClientCapabilities);
240240

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/DelegatedTypes.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ internal record DelegatedMapCodeParams(
7171
internal record DelegatedCompletionResolutionContext(
7272
[property: JsonPropertyName("identifier")] TextDocumentIdentifierAndVersion Identifier,
7373
[property: JsonPropertyName("projectedKind")] RazorLanguageKind ProjectedKind,
74-
[property: JsonPropertyName("originalCompletionListData")] object? OriginalCompletionListData) : ICompletionResolveContext;
74+
[property: JsonPropertyName("originalCompletionListData")] object? OriginalCompletionListData,
75+
[property: JsonPropertyName("provisionalTextEdit")] TextEdit? ProvisionalTextEdit) : ICompletionResolveContext;
7576

7677
internal record DelegatedCompletionItemResolveParams(
7778
[property: JsonPropertyName("identifier")] TextDocumentIdentifierAndVersion Identifier,

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Completion/RemoteCompletionService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ private async ValueTask<Response> GetCompletionAsync(
149149
completionContext,
150150
razorCompletionOptions,
151151
correlationId,
152+
positionInfo.ProvisionalTextEdit,
152153
cancellationToken)
153154
.ConfigureAwait(false);
154155

@@ -191,6 +192,7 @@ private async ValueTask<Response> GetCompletionAsync(
191192
CompletionContext completionContext,
192193
RazorCompletionOptions razorCompletionOptions,
193194
Guid correlationId,
195+
TextEdit? provisionalTextEdit,
194196
CancellationToken cancellationToken)
195197
{
196198
var clientCapabilities = _clientCapabilitiesService.ClientCapabilities;
@@ -236,7 +238,7 @@ private async ValueTask<Response> GetCompletionAsync(
236238
mappedPosition,
237239
razorCompletionOptions);
238240

239-
var resolutionContext = new DelegatedCompletionResolutionContext(identifier, RazorLanguageKind.CSharp, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data);
241+
var resolutionContext = new DelegatedCompletionResolutionContext(identifier, RazorLanguageKind.CSharp, rewrittenResponse.Data ?? rewrittenResponse.ItemDefaults?.Data, provisionalTextEdit);
240242
var resultId = _completionListCache.Add(rewrittenResponse, resolutionContext);
241243
rewrittenResponse.SetResultId(resultId, clientCapabilities);
242244

@@ -326,7 +328,7 @@ private async ValueTask<VSInternalCompletionItem> ResolveCSharpCompletionItemAsy
326328
}
327329

328330
var documentSnapshot = context.Snapshot;
329-
var generatedDocument = await documentSnapshot.GetGeneratedDocumentAsync(cancellationToken).ConfigureAwait(false);
331+
var generatedDocument = await GetCSharpGeneratedDocumentAsync(documentSnapshot, resolutionContext.ProvisionalTextEdit, cancellationToken).ConfigureAwait(false);
330332

331333
var clientCapabilities = _clientCapabilitiesService.ClientCapabilities;
332334
var completionListSetting = clientCapabilities.TextDocument?.Completion;

src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionItemResolverTest.NetFx.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public async Task ResolveAsync_UsesItemsData()
151151
Data = expectedData,
152152
};
153153
var containingCompletionList = new RazorVSInternalCompletionList() { Items = [item], Data = new object() };
154-
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, new object());
154+
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, new object(), ProvisionalTextEdit: null);
155155

156156
// Act
157157
await resolver.ResolveAsync(
@@ -176,7 +176,7 @@ public async Task ResolveAsync_InheritsOriginalCompletionListData()
176176
var resolver = new DelegatedCompletionItemResolver(DocumentContextFactory, formattingService, DocumentMappingService, optionsMonitor, clientConnection, LoggerFactory);
177177
var item = new VSInternalCompletionItem();
178178
var containingCompletionList = new RazorVSInternalCompletionList() { Items = [item], Data = new object() };
179-
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, expectedData);
179+
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, expectedData, ProvisionalTextEdit: null);
180180

181181
// Act
182182
await resolver.ResolveAsync(item, containingCompletionList, originalRequestContext, s_clientCapabilities, _componentAvailabilityService, DisposalToken);
@@ -282,7 +282,7 @@ Task FooAsync()
282282

283283
Assert.NotNull(item);
284284

285-
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, containingCompletionList.Data);
285+
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, containingCompletionList.Data, ProvisionalTextEdit: null);
286286
var resolvedItem = await resolver.ResolveAsync(
287287
item, containingCompletionList, originalRequestContext, s_clientCapabilities, _componentAvailabilityService, DisposalToken);
288288

@@ -334,7 +334,7 @@ public async Task ResolveAsync_Html_Resolves()
334334
var resolver = new DelegatedCompletionItemResolver(DocumentContextFactory, formattingService, DocumentMappingService, optionsMonitor, clientConnection, LoggerFactory);
335335
var item = new VSInternalCompletionItem();
336336
var containingCompletionList = new RazorVSInternalCompletionList() { Items = [item] };
337-
var originalRequestContext = new DelegatedCompletionResolutionContext(_htmlCompletionParams.Identifier, _htmlCompletionParams.ProjectedKind, new object());
337+
var originalRequestContext = new DelegatedCompletionResolutionContext(_htmlCompletionParams.Identifier, _htmlCompletionParams.ProjectedKind, new object(), ProvisionalTextEdit: null);
338338

339339
// Act
340340
var resolvedItem = await resolver.ResolveAsync(
@@ -363,7 +363,7 @@ private async Task<VSInternalCompletionItem> ResolveCompletionItemAsync(string c
363363
var resolver = new DelegatedCompletionItemResolver(documentContextFactory, formattingService, DocumentMappingService, optionsMonitor, clientConnection, LoggerFactory);
364364
var containingCompletionList = await GetCompletionListAndOriginalParamsAsync(cursorPosition, codeDocument, csharpServer);
365365

366-
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, containingCompletionList.Data);
366+
var originalRequestContext = new DelegatedCompletionResolutionContext(_csharpCompletionParams.Identifier, _csharpCompletionParams.ProjectedKind, containingCompletionList.Data, ProvisionalTextEdit: null);
367367
var item = containingCompletionList.Items.FirstOrDefault(item => item.Label == itemToResolve);
368368

369369
if (item is null)

src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostDocumentCompletionEndpointTest.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,16 @@ The end.
123123
TriggerCharacter = ".",
124124
TriggerKind = CompletionTriggerKind.TriggerCharacter
125125
},
126-
expectedItemLabels: ["DaysInMonth", "IsLeapYear", "Now"]);
126+
expectedItemLabels: ["DaysInMonth", "IsLeapYear", "Now"],
127+
itemToResolve: "Now",
128+
expectedResolvedItemDescription: "DateTime DateTime.Now { get; }",
129+
expected: """
130+
This is a Razor document.
131+
132+
<div>@DateTime.Now</div>
133+
134+
The end.
135+
""");
127136
}
128137

129138
[Fact]
@@ -1150,9 +1159,17 @@ private async Task VerifyCompletionResolveAsync(CodeAnalysis.TextDocument docume
11501159
var insertIndex = text.GetRequiredAbsoluteIndex(position);
11511160
changedText = text.WithChanges(new TextChange(new TextSpan(insertIndex, 0), insertText));
11521161
}
1162+
else if (result.Label is { } label)
1163+
{
1164+
// We'll let expected be null here, since its just simple text insertion
1165+
1166+
var text = await document.GetTextAsync(DisposalToken).ConfigureAwait(false);
1167+
var insertIndex = text.GetRequiredAbsoluteIndex(position);
1168+
changedText = text.WithChanges(new TextChange(new TextSpan(insertIndex, 0), label));
1169+
}
11531170
else if (expected is not null)
11541171
{
1155-
Assert.Fail("Expected a TextEdit or Command with TextEdit, but got none. Presumably resolve failed. Result: " + JsonSerializer.SerializeToElement(result).ToString());
1172+
Assert.Fail("Expected a TextEdit or Command with TextEdit, or InsertText, or Label, but got none. Presumably resolve failed. Result: " + JsonSerializer.SerializeToElement(result).ToString());
11561173
}
11571174

11581175
if (result.AdditionalTextEdits is not null)

src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CohostDocumentCompletionResolveEndpointTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ private async Task VerifyCompletionItemResolveAsync(TestCode input)
6666
var context = new DelegatedCompletionResolutionContext(
6767
textDocumentIdentifier,
6868
OriginalCompletionListData: null,
69-
ProjectedKind: RazorLanguageKind.Html);
69+
ProjectedKind: RazorLanguageKind.Html,
70+
ProvisionalTextEdit: null);
7071

7172
var list = new RazorVSInternalCompletionList
7273
{

0 commit comments

Comments
 (0)