Skip to content

Commit ae6b091

Browse files
authored
Merge pull request #6869 from dibarbet/fix_override_completion
Deserialize URI in override completion before attempting to open the document
2 parents ee4d964 + f8b5f82 commit ae6b091

File tree

4 files changed

+90
-5
lines changed

4 files changed

+90
-5
lines changed

src/lsptoolshost/commands.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ async function completionComplexEdit(
106106
const componentName = '[roslyn.client.completionComplexEdit]';
107107

108108
// Find TextDocument, opening if needed.
109-
const document = await vscode.workspace.openTextDocument(uriStr);
109+
const uri = UriConverter.deserialize(uriStr);
110+
const document = await vscode.workspace.openTextDocument(uri);
110111
if (document === undefined) {
111112
outputAndThrow(outputChannel, `${componentName} Can't open document with path: '${uriStr}'`);
112113
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import * as path from 'path';
8+
import { describe, beforeAll, beforeEach, afterAll, test, expect } from '@jest/globals';
9+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
10+
import { activateCSharpExtension, openFileInWorkspaceAsync } from './integrationHelpers';
11+
12+
describe(`[${testAssetWorkspace.description}] Test Completion`, function () {
13+
beforeAll(async function () {
14+
await activateCSharpExtension();
15+
});
16+
17+
beforeEach(async function () {
18+
const fileName = path.join('src', 'app', 'completion.cs');
19+
await openFileInWorkspaceAsync(fileName);
20+
});
21+
22+
afterAll(async () => {
23+
await testAssetWorkspace.cleanupWorkspace();
24+
});
25+
26+
test('Returns completion items', async () => {
27+
const completionList = await getCompletionsAsync(new vscode.Position(8, 12), undefined, 10);
28+
expect(completionList.items.length).toBeGreaterThan(0);
29+
expect(completionList.items.map((item) => item.label)).toContain('Console');
30+
});
31+
32+
test('Resolve adds documentation', async () => {
33+
const completionList = await getCompletionsAsync(new vscode.Position(8, 12), undefined, 10);
34+
const documentation = completionList.items.slice(0, 10).filter((item) => item.documentation);
35+
expect(documentation.length).toEqual(10);
36+
});
37+
38+
test('Override completion is applied', async () => {
39+
const completionList = await getCompletionsAsync(new vscode.Position(12, 24), ' ', 10);
40+
expect(completionList.items.length).toBeGreaterThan(0);
41+
const methodOverrideItem = completionList.items.find(
42+
(item) => item.label === 'Method(singleCsproj2.NeedsImport n)'
43+
);
44+
expect(methodOverrideItem).toBeDefined();
45+
expect(methodOverrideItem!.kind).toEqual(vscode.CompletionItemKind.Method);
46+
expect(methodOverrideItem!.command).toBeDefined();
47+
expect(methodOverrideItem!.command!.command).toEqual('roslyn.client.completionComplexEdit');
48+
49+
await vscode.commands.executeCommand(
50+
methodOverrideItem!.command!.command,
51+
methodOverrideItem!.command!.arguments![0],
52+
methodOverrideItem!.command!.arguments![1],
53+
methodOverrideItem!.command!.arguments![2],
54+
methodOverrideItem!.command!.arguments![3]
55+
);
56+
57+
const usingLine = vscode.window.activeTextEditor!.document.lineAt(1).text;
58+
const methodOverrideLine = vscode.window.activeTextEditor!.document.lineAt(13).text;
59+
const methodOverrideImplLine = vscode.window.activeTextEditor!.document.lineAt(15).text;
60+
expect(usingLine).toContain('using singleCsproj2;');
61+
expect(methodOverrideLine).toContain('override void Method(NeedsImport n)');
62+
expect(methodOverrideImplLine).toContain('base.Method(n);');
63+
});
64+
65+
async function getCompletionsAsync(
66+
position: vscode.Position,
67+
triggerCharacter: string | undefined,
68+
completionsToResolve: number
69+
): Promise<vscode.CompletionList> {
70+
const activeEditor = vscode.window.activeTextEditor;
71+
if (!activeEditor) {
72+
throw new Error('No active editor');
73+
}
74+
75+
return await vscode.commands.executeCommand(
76+
'vscode.executeCompletionItemProvider',
77+
activeEditor.document.uri,
78+
position,
79+
triggerCharacter,
80+
completionsToResolve
81+
);
82+
}
83+
});

test/integrationTests/testAssets/slnWithCsproj/src/app/completion.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ class Completion : CompletionBase
66
{
77
static void shouldHaveCompletions(string[] args)
88
{
9+
910
Completion a = new Completion();
1011
}
1112

12-
// override // Trailing space is intentional
13+
public override // Trailing space is intentional
1314
}
1415
}

test/integrationTests/workspaceDiagnostics.integration.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe(`[${testAssetWorkspace.description}] Test diagnostics`, function () {
3636
.flatMap(([_, diagnostics]) => diagnostics);
3737

3838
expect(diagnosticsInDiagnosticsCs).toHaveLength(4);
39-
expect(diagnosticsInCompletionCs).toHaveLength(6);
39+
expect(diagnosticsInCompletionCs).toHaveLength(4);
4040

4141
// Compiler diagnostic in diagnostics.cs
4242
expect(getCode(diagnosticsInDiagnosticsCs[2])).toBe('CS0219');
@@ -115,7 +115,7 @@ describe(`[${testAssetWorkspace.description}] Test diagnostics`, function () {
115115
.flatMap(([_, diagnostics]) => diagnostics);
116116

117117
expect(diagnosticsInDiagnosticsCs).toHaveLength(1);
118-
expect(diagnosticsInCompletionCs).toHaveLength(0);
118+
expect(diagnosticsInCompletionCs).toHaveLength(1);
119119

120120
expect(
121121
diagnosticsInDiagnosticsCs.some((d) => getCode(d).startsWith('IDE') || getCode(d).startsWith('CA'))
@@ -144,7 +144,7 @@ describe(`[${testAssetWorkspace.description}] Test diagnostics`, function () {
144144
.flatMap(([_, diagnostics]) => diagnostics);
145145

146146
expect(diagnosticsInDiagnosticsCs).toHaveLength(1);
147-
expect(diagnosticsInCompletionCs).toHaveLength(0);
147+
expect(diagnosticsInCompletionCs).toHaveLength(1);
148148

149149
expect(
150150
diagnosticsInDiagnosticsCs.some((d) => getCode(d).startsWith('IDE') || getCode(d).startsWith('CA'))

0 commit comments

Comments
 (0)