Skip to content

Commit ab0c4f1

Browse files
authored
Fix cohosting completion and code actions (#11619)
Fixes #10693 Not a lot in the way of code changes here, its mostly just unskipping tests. Those tests won't pass until dotnet/roslyn#77587 is merged and available, but this PR leaves only 5 tests skipped in cohosting, which probably puts us in a position to internally dogfood.
2 parents 00ef962 + fbb0068 commit ab0c4f1

File tree

11 files changed

+61
-61
lines changed

11 files changed

+61
-61
lines changed

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/ProjectExtensions.cs

+6-14
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
using Microsoft.AspNetCore.Razor;
1212
using Microsoft.AspNetCore.Razor.Language;
1313
using Microsoft.AspNetCore.Razor.PooledObjects;
14-
using Microsoft.CodeAnalysis.Razor;
14+
using Microsoft.AspNetCore.Razor.Threading;
1515
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
16+
using Microsoft.CodeAnalysis.Razor;
1617
using Microsoft.CodeAnalysis.Razor.Telemetry;
1718

1819
namespace Microsoft.CodeAnalysis;
@@ -84,23 +85,14 @@ internal static Document GetRequiredDocument(this Project project, DocumentId do
8485
?? ThrowHelper.ThrowInvalidOperationException<Document>($"The document {documentId} did not exist in {project.Name}");
8586
}
8687

87-
public static bool TryGetCSharpDocument(this Project project, Uri csharpDocumentUri, [NotNullWhen(true)] out Document? document)
88+
public static Task<SourceGeneratedDocument?> TryGetCSharpDocumentFromGeneratedDocumentUriAsync(this Project project, Uri generatedDocumentUri, CancellationToken cancellationToken)
8889
{
89-
document = null;
90-
91-
var generatedDocumentIds = project.Solution.GetDocumentIdsWithUri(csharpDocumentUri);
92-
var generatedDocumentId = generatedDocumentIds.FirstOrDefault(d => d.ProjectId == project.Id);
93-
if (generatedDocumentId is null)
94-
{
95-
return false;
96-
}
97-
98-
if (project.GetDocument(generatedDocumentId) is { } generatedDocument)
90+
if (!TryGetHintNameFromGeneratedDocumentUri(project, generatedDocumentUri, out var hintName))
9991
{
100-
document = generatedDocument;
92+
return SpecializedTasks.Null<SourceGeneratedDocument>();
10193
}
10294

103-
return document is not null;
95+
return TryGetSourceGeneratedDocumentFromHintNameAsync(project, hintName, cancellationToken);
10496
}
10597

10698
/// <summary>

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/SolutionExtensions.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
using System;
55
using System.Collections.Immutable;
6+
using System.Diagnostics;
67
using System.Diagnostics.CodeAnalysis;
78
using System.Linq;
89
using Microsoft.AspNetCore.Razor;
10+
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
911
using Microsoft.CodeAnalysis.Razor;
1012
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
1113

@@ -14,7 +16,10 @@ namespace Microsoft.CodeAnalysis;
1416
internal static class SolutionExtensions
1517
{
1618
public static ImmutableArray<DocumentId> GetDocumentIdsWithUri(this Solution solution, Uri uri)
17-
=> solution.GetDocumentIdsWithFilePath(uri.GetDocumentFilePath());
19+
{
20+
Debug.Assert(RazorUri.IsGeneratedDocumentUri(uri) == false, "This won't work with source generated Uris");
21+
return solution.GetDocumentIdsWithFilePath(uri.GetDocumentFilePath());
22+
}
1823

1924
public static bool TryGetRazorDocument(this Solution solution, Uri razorDocumentUri, [NotNullWhen(true)] out TextDocument? razorDocument)
2025
{

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public ImmutableArray<Registration> GetRegistrations(VSInternalClientCapabilitie
9898

9999
private async Task<RazorVSInternalCodeAction[]> GetCSharpCodeActionsAsync(TextDocument razorDocument, VSCodeActionParams request, Guid correlationId, CancellationToken cancellationToken)
100100
{
101-
if (!razorDocument.Project.TryGetCSharpDocument(request.TextDocument.Uri, out var generatedDocument))
101+
var generatedDocument = await razorDocument.Project.TryGetCSharpDocumentFromGeneratedDocumentUriAsync(request.TextDocument.Uri, cancellationToken).ConfigureAwait(false);
102+
if (generatedDocument is null)
102103
{
103104
return [];
104105
}

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsResolveEndpoint.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ private async Task<CodeAction> ResolveCSharpCodeActionAsync(TextDocument razorDo
102102

103103
var uri = resolveParams.DelegatedDocumentUri.AssumeNotNull();
104104

105-
if (!razorDocument.Project.TryGetCSharpDocument(uri, out var generatedDocument))
105+
var generatedDocument = await razorDocument.Project.TryGetCSharpDocumentFromGeneratedDocumentUriAsync(uri, cancellationToken).ConfigureAwait(false);
106+
if (generatedDocument is null)
106107
{
107108
return codeAction;
108109
}

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostInlineCompletionEndpoint.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ public ImmutableArray<Registration> GetRegistrations(VSInternalClientCapabilitie
6868
return null;
6969
}
7070

71-
if (!razorDocument.Project.TryGetCSharpDocument(generatedDocumentUri, out var generatedDocument))
71+
var generatedDocument = await razorDocument.Project.TryGetCSharpDocumentFromGeneratedDocumentUriAsync(generatedDocumentUri, cancellationToken).ConfigureAwait(false);
72+
if (generatedDocument is null)
7273
{
7374
return null;
7475
}
7576

7677
var result = await Completion.GetInlineCompletionItemsAsync(context, generatedDocument, position, formattingOptions, cancellationToken).ConfigureAwait(false);
77-
7878
if (result is null)
7979
{
8080
return null;

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/AddUsingTests.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
using System.Threading.Tasks;
55
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
6+
using Microsoft.CodeAnalysis.Razor.Protocol;
67
using Xunit;
78
using Xunit.Abstractions;
89

910
namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost.CodeActions;
1011

1112
public class AddUsingTests(ITestOutputHelper testOutputHelper) : CohostCodeActionsEndpointTestBase(testOutputHelper)
1213
{
13-
[Fact(Skip = "Need to map uri back to source generated document")]
14+
[Fact]
1415
public async Task FullyQualify()
1516
{
1617
var input = """
@@ -27,10 +28,10 @@ public async Task FullyQualify()
2728
}
2829
""";
2930

30-
await VerifyCodeActionAsync(input, expected, "System.Text.StringBuilder");
31+
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.FullyQualify);
3132
}
3233

33-
[Fact(Skip = "Need to map uri back to source generated document")]
34+
[Fact]
3435
public async Task FullyQualify_Multiple()
3536
{
3637
await VerifyCodeActionAsync(
@@ -54,11 +55,11 @@ public class StringBuilder
5455
{
5556
}
5657
""")],
57-
codeActionName: "Fully qualify 'StringBuilder'",
58+
codeActionName: LanguageServerConstants.CodeActions.FullyQualify,
5859
childActionIndex: 0);
5960
}
6061

61-
[Fact(Skip = "Need to map uri back to source generated document")]
62+
[Fact]
6263
public async Task AddUsing()
6364
{
6465
var input = """
@@ -79,7 +80,7 @@ @using System.Text
7980
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.AddImport);
8081
}
8182

82-
[Fact(Skip = "Need to map uri back to source generated document")]
83+
[Fact]
8384
public async Task AddUsing_Typo()
8485
{
8586
var input = """
@@ -100,7 +101,7 @@ @using System.Text
100101
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.AddImport);
101102
}
102103

103-
[Fact(Skip = "Need to map uri back to source generated document")]
104+
[Fact]
104105
public async Task AddUsing_WithExisting()
105106
{
106107
var input = """

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/CSharpCodeActionTests.cs

+14-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost.CodeActions;
1010

1111
public class CSharpCodeActionTests(ITestOutputHelper testOutputHelper) : CohostCodeActionsEndpointTestBase(testOutputHelper)
1212
{
13-
[Fact(Skip = "Need to map uri back to source generated document")]
13+
[Fact]
1414
public async Task GenerateConstructor()
1515
{
1616
var input = """
@@ -45,7 +45,7 @@ public Goo()
4545
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.GenerateConstructorFromMembers);
4646
}
4747

48-
[Fact(Skip = "Need to map uri back to source generated document")]
48+
[Fact]
4949
public async Task UseExpressionBodiedMember()
5050
{
5151
var input = """
@@ -78,7 +78,7 @@ @using System.Linq
7878
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.UseExpressionBody);
7979
}
8080

81-
[Fact(Skip = "Need to map uri back to source generated document")]
81+
[Fact(Skip = "Roslyn code refactoring provider is not finding the expression")]
8282
public async Task IntroduceLocal()
8383
{
8484
var input = """
@@ -125,7 +125,7 @@ void M(string[] args)
125125
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.IntroduceVariable);
126126
}
127127

128-
[Fact(Skip = "Need to map uri back to source generated document")]
128+
[Fact(Skip = "Roslyn code refactoring provider is not finding the expression")]
129129
public async Task IntroduceLocal_All()
130130
{
131131
var input = """
@@ -172,7 +172,7 @@ void M(string[] args)
172172
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.IntroduceVariable, childActionIndex: 1);
173173
}
174174

175-
[Fact(Skip = "Need to map uri back to source generated document")]
175+
[Fact]
176176
public async Task ConvertConcatenationToInterpolatedString_CSharpStatement()
177177
{
178178
var input = """
@@ -190,7 +190,7 @@ public async Task ConvertConcatenationToInterpolatedString_CSharpStatement()
190190
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertConcatenationToInterpolatedString);
191191
}
192192

193-
[Fact(Skip = "Need to map uri back to source generated document")]
193+
[Fact]
194194
public async Task ConvertConcatenationToInterpolatedString_ExplicitExpression()
195195
{
196196
var input = """
@@ -204,7 +204,7 @@ public async Task ConvertConcatenationToInterpolatedString_ExplicitExpression()
204204
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertConcatenationToInterpolatedString);
205205
}
206206

207-
[Fact(Skip = "Need to map uri back to source generated document")]
207+
[Fact]
208208
public async Task ConvertConcatenationToInterpolatedString_CodeBlock()
209209
{
210210
var input = """
@@ -224,7 +224,7 @@ public async Task ConvertConcatenationToInterpolatedString_CodeBlock()
224224
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertConcatenationToInterpolatedString);
225225
}
226226

227-
[Fact(Skip = "Need to map uri back to source generated document")]
227+
[Fact]
228228
public async Task ConvertBetweenRegularAndVerbatimInterpolatedString_CodeBlock()
229229
{
230230
var input = """
@@ -244,7 +244,7 @@ public async Task ConvertBetweenRegularAndVerbatimInterpolatedString_CodeBlock()
244244
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertBetweenRegularAndVerbatimInterpolatedString);
245245
}
246246

247-
[Fact(Skip = "Need to map uri back to source generated document")]
247+
[Fact]
248248
public async Task ConvertBetweenRegularAndVerbatimInterpolatedString_CodeBlock2()
249249
{
250250
var input = """
@@ -264,7 +264,7 @@ public async Task ConvertBetweenRegularAndVerbatimInterpolatedString_CodeBlock2(
264264
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertBetweenRegularAndVerbatimInterpolatedString);
265265
}
266266

267-
[Fact(Skip = "Need to map uri back to source generated document")]
267+
[Fact]
268268
public async Task ConvertBetweenRegularAndVerbatimString_CodeBlock()
269269
{
270270
var input = """
@@ -284,7 +284,7 @@ public async Task ConvertBetweenRegularAndVerbatimString_CodeBlock()
284284
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertBetweenRegularAndVerbatimString);
285285
}
286286

287-
[Fact(Skip = "Need to map uri back to source generated document")]
287+
[Fact]
288288
public async Task ConvertBetweenRegularAndVerbatimString_CodeBlock2()
289289
{
290290
var input = """
@@ -304,7 +304,7 @@ public async Task ConvertBetweenRegularAndVerbatimString_CodeBlock2()
304304
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertBetweenRegularAndVerbatimString);
305305
}
306306

307-
[Fact(Skip = "Need to map uri back to source generated document")]
307+
[Fact]
308308
public async Task ConvertPlaceholderToInterpolatedString_CodeBlock()
309309
{
310310
var input = """
@@ -324,7 +324,7 @@ public async Task ConvertPlaceholderToInterpolatedString_CodeBlock()
324324
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertPlaceholderToInterpolatedString);
325325
}
326326

327-
[Fact(Skip = "Need to map uri back to source generated document")]
327+
[Fact]
328328
public async Task ConvertToInterpolatedString_CodeBlock()
329329
{
330330
var input = """
@@ -344,7 +344,7 @@ public async Task ConvertToInterpolatedString_CodeBlock()
344344
await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.ConvertToInterpolatedString);
345345
}
346346

347-
[Fact(Skip = "Need to map uri back to source generated document")]
347+
[Fact]
348348
public async Task AddDebuggerDisplay()
349349
{
350350
var input = """

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/GenerateEventHandlerTests.cs

+11-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost.CodeActions;
1010

1111
public class GenerateEventHandlerTests(ITestOutputHelper testOutputHelper) : CohostCodeActionsEndpointTestBase(testOutputHelper)
1212
{
13-
[Fact(Skip = "Need to map uri back to source generated document")]
13+
[Fact]
1414
public async Task NoCodeBlock()
1515
{
1616
var input = """
@@ -30,7 +30,7 @@ private void DoesNotExist(MouseEventArgs args)
3030
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateEventHandler);
3131
}
3232

33-
[Fact(Skip = "Need to map uri back to source generated document")]
33+
[Fact]
3434
public async Task CodeBlock()
3535
{
3636
var input = """
@@ -56,7 +56,7 @@ private void DoesNotExist(MouseEventArgs args)
5656
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateEventHandler);
5757
}
5858

59-
[Fact(Skip = "Need to map uri back to source generated document")]
59+
[Fact(Skip = "@bind- attribute tag helper is not being found")]
6060
public async Task BindSet()
6161
{
6262
var input = """
@@ -84,7 +84,7 @@ private void DoesNotExist(string args)
8484
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateEventHandler);
8585
}
8686

87-
[Fact(Skip = "Need to map uri back to source generated document")]
87+
[Fact(Skip = "@bind- attribute tag helper is not being found")]
8888
public async Task BindAfter()
8989
{
9090
var input = """
@@ -112,7 +112,7 @@ private void DoesNotExist()
112112
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateEventHandler);
113113
}
114114

115-
[Fact(Skip = "Need to map uri back to source generated document")]
115+
[Fact]
116116
public async Task Callback()
117117
{
118118
var input = """
@@ -138,7 +138,7 @@ private void DoesNotExist(InputFileChangeEventArgs args)
138138
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateEventHandler);
139139
}
140140

141-
[Fact(Skip = "Need to map uri back to source generated document")]
141+
[Fact]
142142
public async Task AsyncCallback()
143143
{
144144
var input = """
@@ -164,7 +164,7 @@ private Task DoesNotExistAsync(string args)
164164
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateAsyncEventHandler);
165165
}
166166

167-
[Fact(Skip = "Need to map uri back to source generated document")]
167+
[Fact]
168168
public async Task BadCodeBehind()
169169
{
170170
await VerifyCodeActionAsync(
@@ -192,7 +192,7 @@ public partial class NotAComponent
192192
codeActionName: LanguageServerConstants.CodeActions.GenerateEventHandler);
193193
}
194194

195-
[Fact(Skip = "Need to map uri back to source generated document")]
195+
[Fact]
196196
public async Task CodeBehind()
197197
{
198198
await VerifyCodeActionAsync(
@@ -231,7 +231,7 @@ private void DoesNotExist(Microsoft.AspNetCore.Components.Web.MouseEventArgs arg
231231
codeActionName: LanguageServerConstants.CodeActions.GenerateEventHandler);
232232
}
233233

234-
[Fact(Skip = "Need to map uri back to source generated document")]
234+
[Fact]
235235
public async Task EmptyCodeBehind()
236236
{
237237
await VerifyCodeActionAsync(
@@ -264,7 +264,7 @@ private void DoesNotExist(Microsoft.AspNetCore.Components.Web.MouseEventArgs arg
264264
codeActionName: LanguageServerConstants.CodeActions.GenerateEventHandler);
265265
}
266266

267-
[Fact(Skip = "Need to map uri back to source generated document")]
267+
[Fact]
268268
public async Task GenerateAsyncEventHandler_NoCodeBlock()
269269
{
270270
var input = """
@@ -284,7 +284,7 @@ private Task DoesNotExist(MouseEventArgs args)
284284
await VerifyCodeActionAsync(input, expected, LanguageServerConstants.CodeActions.GenerateAsyncEventHandler);
285285
}
286286

287-
[Fact(Skip = "Need to map uri back to source generated document")]
287+
[Fact]
288288
public async Task GenerateAsyncEventHandler_CodeBlock()
289289
{
290290
var input = """

0 commit comments

Comments
 (0)