Skip to content

Commit f73e56b

Browse files
committed
ts-codelens: implementations for overrides + test
1 parent 05c2fd5 commit f73e56b

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

extensions/typescript-language-features/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@
218218
"description": "%typescript.implementationsCodeLens.showOnInterfaceMethods%",
219219
"scope": "window"
220220
},
221+
"typescript.implementationsCodeLens.showOnClassMethods": {
222+
"type": "boolean",
223+
"default": false,
224+
"description": "%typescript.implementationsCodeLens.showOnClassMethods.desc%",
225+
"scope": "window"
226+
},
221227
"typescript.reportStyleChecksAsWarnings": {
222228
"type": "boolean",
223229
"default": true,

extensions/typescript-language-features/package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"typescript.referencesCodeLens.showOnAllFunctions": "Enable/disable references CodeLens on all functions in TypeScript files.",
5757
"typescript.implementationsCodeLens.enabled": "Enable/disable implementations CodeLens. This CodeLens shows the implementers of an interface.",
5858
"typescript.implementationsCodeLens.showOnInterfaceMethods": "Enable/disable implementations CodeLens on interface methods.",
59+
"typescript.implementationsCodeLens.showOnClassMethods.desc": "Enable/disable showing 'implementations' CodeLens above class methods.",
5960
"typescript.openTsServerLog.title": "Open TS Server log",
6061
"typescript.restartTsServer": "Restart TS Server",
6162
"typescript.selectTypeScriptVersion.title": "Select TypeScript Version...",

extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip
2525
super(client, _cachedResponse);
2626
this._register(
2727
vscode.workspace.onDidChangeConfiguration(evt => {
28-
if (evt.affectsConfiguration(`${language.id}.implementationsCodeLens.showOnInterfaceMethods`)) {
28+
if (evt.affectsConfiguration(`${language.id}.implementationsCodeLens.showOnInterfaceMethods`) ||
29+
evt.affectsConfiguration(`${language.id}.implementationsCodeLens.showOnClassMethods`))
30+
{
2931
this.changeEmitter.fire();
3032
}
3133
})
@@ -87,24 +89,27 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip
8789
item: Proto.NavigationTree,
8890
parent: Proto.NavigationTree | undefined
8991
): vscode.Range | undefined {
90-
if (item.kind === PConst.Kind.method && parent && parent.kind === PConst.Kind.interface && vscode.workspace.getConfiguration(this.language.id).get<boolean>('implementationsCodeLens.showOnInterfaceMethods')) {
91-
return getSymbolRange(document, item);
92-
}
93-
switch (item.kind) {
94-
case PConst.Kind.interface:
95-
return getSymbolRange(document, item);
92+
const cfg = vscode.workspace.getConfiguration(this.language.id);
9693

97-
case PConst.Kind.class:
98-
case PConst.Kind.method:
99-
case PConst.Kind.memberVariable:
100-
case PConst.Kind.memberGetAccessor:
101-
case PConst.Kind.memberSetAccessor:
102-
if (item.kindModifiers.match(/\babstract\b/g)) {
103-
return getSymbolRange(document, item);
104-
}
105-
break;
106-
}
107-
return undefined;
94+
// Interface members (behind existing setting)
95+
if (
96+
item.kind === PConst.Kind.method &&
97+
parent?.kind === PConst.Kind.interface &&
98+
cfg.get<boolean>('implementationsCodeLens.showOnInterfaceMethods')
99+
) {
100+
return getSymbolRange(document, item);
101+
}
102+
103+
// Class methods (behind new setting; default off)
104+
if (
105+
item.kind === PConst.Kind.method &&
106+
parent?.kind === PConst.Kind.class &&
107+
cfg.get<boolean>('implementationsCodeLens.showOnClassMethods', false)
108+
) {
109+
return getSymbolRange(document, item);
110+
}
111+
112+
return undefined;
108113
}
109114
}
110115

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 assert from "assert";
7+
import * as vscode from "vscode";
8+
import { joinLines, withRandomFileEditor } from "../testUtils";
9+
10+
suite("TypeScript Implementations CodeLens", () => {
11+
test("should show implementations code lens for overridden methods", async () => {
12+
await withRandomFileEditor(
13+
joinLines(
14+
"abstract class A {",
15+
" foo() {}",
16+
"}",
17+
"class B extends A {",
18+
" foo() {}",
19+
"}",
20+
),
21+
"ts",
22+
async (editor: vscode.TextEditor, doc: vscode.TextDocument) => {
23+
assert.strictEqual(
24+
editor.document,
25+
doc,
26+
"Editor and document should match",
27+
);
28+
29+
const lenses = await vscode.commands.executeCommand<vscode.CodeLens[]>(
30+
"vscode.executeCodeLensProvider",
31+
doc.uri,
32+
);
33+
34+
const fooLens = lenses?.find((lens) =>
35+
doc.getText(lens.range).includes("foo"),
36+
);
37+
38+
assert.ok(fooLens, "Expected a CodeLens above foo()");
39+
assert.match(
40+
fooLens!.command?.title ?? "",
41+
/1 implementation/,
42+
'Expected lens to show "1 implementation"',
43+
);
44+
},
45+
);
46+
});
47+
});

0 commit comments

Comments
 (0)