Skip to content
Merged
41 changes: 37 additions & 4 deletions src/services/goToDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,22 @@ namespace ts.GoToDefinition {
return label ? [createDefinitionInfoFromName(typeChecker, label, ScriptElementKind.label, node.text, /*containerName*/ undefined!)] : undefined; // TODO: GH#18217
}

if (node.kind === SyntaxKind.ReturnKeyword) {
const functionDeclaration = findAncestor(node.parent, n =>
isClassStaticBlockDeclaration(n) ? "quit" : isFunctionLikeDeclaration(n)) as FunctionLikeDeclaration | undefined;
return functionDeclaration ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined;
switch (node.kind) {
case SyntaxKind.ReturnKeyword:
const functionDeclaration = findAncestor(node.parent, n =>
isClassStaticBlockDeclaration(n) ? "quit" : isFunctionLikeDeclaration(n)) as FunctionLikeDeclaration | undefined;
return functionDeclaration ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined;
case SyntaxKind.DefaultKeyword:
if (!isDefaultClause(node.parent)) {
break;
}
// falls through
case SyntaxKind.CaseKeyword:
const switchStatement = findAncestor(node.parent, isSwitchStatement);
if (switchStatement) {
return [createDefinitionInfoFromStatement(switchStatement, SyntaxKind.SwitchKeyword, sourceFile, "switch")];
}
break;
}

if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) {
Expand Down Expand Up @@ -510,4 +522,25 @@ namespace ts.GoToDefinition {
return false;
}
}

interface StatementWithExpression extends Statement {
readonly expression: Expression
}

function createDefinitionInfoFromStatement(statement: StatementWithExpression, keywordKind: KeywordSyntaxKind, sourceFile: SourceFile, name: string): DefinitionInfo {
const keyword = find(statement.getChildren(sourceFile), (node) => node.kind === keywordKind)!;
return {
fileName: sourceFile.fileName,
textSpan: createTextSpanFromNode(keyword, sourceFile),
kind: ScriptElementKind.keyword,
name,
containerKind: undefined!,
containerName: "",
contextSpan: createTextSpanFromNode(statement.expression, sourceFile),
isLocal: true,
isAmbient: false,
unverified: false,
failedAliasResolution: undefined,
};
}
}
7 changes: 7 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference path="fourslash.ts" />

/////*end*/switch (null) {
//// [|/*start*/case|] null: break;
////}

verify.goToDefinition("start", "end");
7 changes: 7 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference path="fourslash.ts" />

/////*end*/switch (null) {
//// [|/*start*/default|]: break;
////}

verify.goToDefinition("start", "end");
12 changes: 12 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// <reference path="fourslash.ts" />

/////*end1*/switch (null) {
//// [|/*start1*/default|]: {
//// /*end2*/switch (null) {
//// [|/*start2*/default|]: break;
//// }
//// };
////}

verify.goToDefinition("start1", "end1");
verify.goToDefinition("start2", "end2");
11 changes: 11 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase4.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />

//// switch (null) {
//// case null: break;
//// }
////
//// /*end*/switch (null) {
//// [|/*start*/case|] null: break;
//// }

verify.goToDefinition("start", "end");
5 changes: 5 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference path="fourslash.ts" />

/////*end*/export [|/*start*/default|] {}

verify.goToDefinition("start", "end");
9 changes: 9 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase6.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// <reference path="fourslash.ts" />

/////*d*/export default { [|/*a*/case|] };
////[|/*b*/default|];
////[|/*c*/case|] 42;

verify.goToDefinition("a", "a");
verify.goToDefinition("b", "d");
verify.goToDefinition("c", []);
7 changes: 7 additions & 0 deletions tests/cases/fourslash/goToDefinitionSwitchCase7.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference path="fourslash.ts" />

////switch (null) {
//// case null:
//// /*end*/export [|/*start*/default|] 123;

verify.goToDefinition("start", "end");