Skip to content

Commit 029f7a3

Browse files
authored
Merge pull request #33124 from armanio123/FixGotoMultipleFile
Fixed goto when global declarations are on multiple files
2 parents fa9e0fa + 09a5b68 commit 029f7a3

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/services/goToDefinition.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace ts.GoToDefinition {
3939
return [sigInfo];
4040
}
4141
else {
42-
const defs = getDefinitionFromSymbol(typeChecker, symbol, node) || emptyArray;
42+
const defs = getDefinitionFromSymbol(typeChecker, symbol, node, calledDeclaration) || emptyArray;
4343
// For a 'super()' call, put the signature first, else put the variable first.
4444
return node.kind === SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo];
4545
}
@@ -232,10 +232,11 @@ namespace ts.GoToDefinition {
232232
}
233233
}
234234

235-
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] | undefined {
235+
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, declarationNode?: Node): DefinitionInfo[] | undefined {
236236
// There are cases when you extend a function by adding properties to it afterwards,
237-
// we want to strip those extra properties
238-
const filteredDeclarations = filter(symbol.declarations, d => !isAssignmentDeclaration(d) || d === symbol.valueDeclaration) || undefined;
237+
// we want to strip those extra properties.
238+
// For deduping purposes, we also want to exclude any declarationNodes if provided.
239+
const filteredDeclarations = filter(symbol.declarations, d => d !== declarationNode && (!isAssignmentDeclaration(d) || d === symbol.valueDeclaration)) || undefined;
239240
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(filteredDeclarations, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node));
240241

241242
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
@@ -258,8 +259,13 @@ namespace ts.GoToDefinition {
258259
return undefined;
259260
}
260261
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isFunctionLike);
262+
const declarationsWithBody = declarations.filter(d => !!(<FunctionLikeDeclaration>d).body);
263+
264+
// declarations defined on the global scope can be defined on multiple files. Get all of them.
261265
return declarations.length
262-
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), typeChecker, symbol, node)]
266+
? declarationsWithBody.length !== 0
267+
? declarationsWithBody.map(x => createDefinitionInfo(x, typeChecker, symbol, node))
268+
: [createDefinitionInfo(last(declarations), typeChecker, symbol, node)]
263269
: undefined;
264270
}
265271
}

tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@
77
////var /*def2*/x: number;
88

99
//@Filename: c.ts
10+
////var /*def3*/x: number;
11+
12+
//@Filename: d.ts
13+
////var /*def4*/x: number;
14+
15+
//@Filename: e.ts
1016
/////// <reference path="a.ts" />
1117
/////// <reference path="b.ts" />
18+
/////// <reference path="c.ts" />
19+
/////// <reference path="d.ts" />
1220
////[|/*use*/x|]++;
1321

14-
verify.goToDefinition("use", ["def1", "def2"]);
22+
verify.goToDefinition("use", ["def1", "def2", "def3", "def4"]);

0 commit comments

Comments
 (0)