feat(44736): add go-to-definition on overridden members (#44740)
This commit is contained in:
parent
54b913cf31
commit
066796be54
|
@ -12,10 +12,14 @@ namespace ts.GoToDefinition {
|
|||
if (node === sourceFile) {
|
||||
return undefined;
|
||||
}
|
||||
const { parent } = node;
|
||||
|
||||
const { parent } = node;
|
||||
const typeChecker = program.getTypeChecker();
|
||||
|
||||
if (node.kind === SyntaxKind.OverrideKeyword || (isJSDocOverrideTag(node) && rangeContainsPosition(node.tagName, position))) {
|
||||
return getDefinitionFromOverriddenMember(typeChecker, node) || emptyArray;
|
||||
}
|
||||
|
||||
// Labels
|
||||
if (isJumpStatementTarget(node)) {
|
||||
const label = getTargetLabel(node.parent, node.text);
|
||||
|
@ -126,6 +130,26 @@ namespace ts.GoToDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
function getDefinitionFromOverriddenMember(typeChecker: TypeChecker, node: Node) {
|
||||
const classElement = findAncestor(node, isClassElement);
|
||||
if (!(classElement && classElement.name)) return;
|
||||
|
||||
const baseDeclaration = findAncestor(classElement, isClassLike);
|
||||
if (!baseDeclaration) return;
|
||||
|
||||
const baseTypeNode = getEffectiveBaseTypeNode(baseDeclaration);
|
||||
const baseType = baseTypeNode ? typeChecker.getTypeAtLocation(baseTypeNode) : undefined;
|
||||
if (!baseType) return;
|
||||
|
||||
const name = unescapeLeadingUnderscores(getTextOfPropertyName(classElement.name));
|
||||
const symbol = hasStaticModifier(classElement)
|
||||
? typeChecker.getPropertyOfType(typeChecker.getTypeOfSymbolAtLocation(baseType.symbol, baseDeclaration), name)
|
||||
: typeChecker.getPropertyOfType(baseType, name);
|
||||
if (!symbol) return;
|
||||
|
||||
return getDefinitionFromSymbol(typeChecker, symbol, node);
|
||||
}
|
||||
|
||||
export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { reference: FileReference, fileName: string, unverified: boolean, file?: SourceFile } | undefined {
|
||||
const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position);
|
||||
if (referencePath) {
|
||||
|
|
12
tests/cases/fourslash/goToDefinitionOverriddenMember1.ts
Normal file
12
tests/cases/fourslash/goToDefinitionOverriddenMember1.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// /*2*/p = '';
|
||||
////}
|
||||
////class Bar extends Foo {
|
||||
//// [|/*1*/override|] p = '';
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
15
tests/cases/fourslash/goToDefinitionOverriddenMember10.ts
Normal file
15
tests/cases/fourslash/goToDefinitionOverriddenMember10.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitOverride: true
|
||||
// @filename: a.js
|
||||
|
||||
////class Foo {}
|
||||
////class Bar extends Foo {
|
||||
//// /** [|@override{|"name": "1"|} |]*/
|
||||
//// m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", []);
|
23
tests/cases/fourslash/goToDefinitionOverriddenMember11.ts
Normal file
23
tests/cases/fourslash/goToDefinitionOverriddenMember11.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitOverride: true
|
||||
// @filename: a.js
|
||||
|
||||
////class Foo {
|
||||
//// /*Foo_m*/m() {}
|
||||
////}
|
||||
////class Bar extends Foo {
|
||||
//// /** [|@over{|"name": "1"|}ride[| se{|"name": "2"|}e {@li{|"name": "3"|}nk https://test.c{|"name": "4"|}om} {|"name": "5"|}description |]|]*/
|
||||
//// m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition({
|
||||
1: "Foo_m",
|
||||
2: [],
|
||||
3: [],
|
||||
4: [],
|
||||
5: []
|
||||
});
|
12
tests/cases/fourslash/goToDefinitionOverriddenMember12.ts
Normal file
12
tests/cases/fourslash/goToDefinitionOverriddenMember12.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// static /*2*/p = '';
|
||||
////}
|
||||
////class Bar extends Foo {
|
||||
//// static [|/*1*/override|] p = '';
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
12
tests/cases/fourslash/goToDefinitionOverriddenMember13.ts
Normal file
12
tests/cases/fourslash/goToDefinitionOverriddenMember13.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// static /*2*/m() {}
|
||||
////}
|
||||
////class Bar extends Foo {
|
||||
//// static [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
13
tests/cases/fourslash/goToDefinitionOverriddenMember14.ts
Normal file
13
tests/cases/fourslash/goToDefinitionOverriddenMember14.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class A {
|
||||
//// /*2*/m() {}
|
||||
////}
|
||||
////class B extends A {}
|
||||
////class C extends B {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
13
tests/cases/fourslash/goToDefinitionOverriddenMember15.ts
Normal file
13
tests/cases/fourslash/goToDefinitionOverriddenMember15.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class A {
|
||||
//// static /*2*/m() {}
|
||||
////}
|
||||
////class B extends A {}
|
||||
////class C extends B {
|
||||
//// static [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
13
tests/cases/fourslash/goToDefinitionOverriddenMember2.ts
Normal file
13
tests/cases/fourslash/goToDefinitionOverriddenMember2.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// /*2*/m() {}
|
||||
////}
|
||||
////
|
||||
////class Bar extends Foo {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
13
tests/cases/fourslash/goToDefinitionOverriddenMember3.ts
Normal file
13
tests/cases/fourslash/goToDefinitionOverriddenMember3.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////abstract class Foo {
|
||||
//// abstract /*2*/m() {}
|
||||
////}
|
||||
////
|
||||
////export class Bar extends Foo {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
15
tests/cases/fourslash/goToDefinitionOverriddenMember4.ts
Normal file
15
tests/cases/fourslash/goToDefinitionOverriddenMember4.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// /*2*/m() {}
|
||||
////}
|
||||
////function f () {
|
||||
//// return class extends Foo {
|
||||
//// [|/*1*/override|] m() {}
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
||||
|
11
tests/cases/fourslash/goToDefinitionOverriddenMember5.ts
Normal file
11
tests/cases/fourslash/goToDefinitionOverriddenMember5.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo extends (class {
|
||||
//// /*2*/m() {}
|
||||
////}) {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
12
tests/cases/fourslash/goToDefinitionOverriddenMember6.ts
Normal file
12
tests/cases/fourslash/goToDefinitionOverriddenMember6.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// m() {}
|
||||
////}
|
||||
////class Bar extends Foo {
|
||||
//// [|/*1*/override|] m1() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", []);
|
9
tests/cases/fourslash/goToDefinitionOverriddenMember7.ts
Normal file
9
tests/cases/fourslash/goToDefinitionOverriddenMember7.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////class Foo {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", []);
|
16
tests/cases/fourslash/goToDefinitionOverriddenMember8.ts
Normal file
16
tests/cases/fourslash/goToDefinitionOverriddenMember8.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
// @Filename: ./a.ts
|
||||
////export class A {
|
||||
//// /*2*/m() {}
|
||||
////}
|
||||
|
||||
// @Filename: ./b.ts
|
||||
////import { A } from "./a";
|
||||
////class B extends A {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
15
tests/cases/fourslash/goToDefinitionOverriddenMember9.ts
Normal file
15
tests/cases/fourslash/goToDefinitionOverriddenMember9.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////interface I {
|
||||
//// m(): void;
|
||||
////}
|
||||
////class A {
|
||||
//// /*2*/m() {};
|
||||
////}
|
||||
////class B extends A implements I {
|
||||
//// [|/*1*/override|] m() {}
|
||||
////}
|
||||
|
||||
verify.goToDefinition("1", "2");
|
Loading…
Reference in a new issue