From 7ddb2484671dd24c5c2e4acf00dca26a33f378e1 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 30 Oct 2024 18:59:40 -0700 Subject: [PATCH 1/5] refactor --- src/services/goToDefinition.ts | 40 ++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 9a47d90ce1deb..c0b1fa1e95063 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -137,15 +137,8 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile return label ? [createDefinitionInfoFromName(typeChecker, label, ScriptElementKind.label, node.text, /*containerName*/ undefined!)] : undefined; // TODO: GH#18217 } + // for switch statments 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; @@ -159,16 +152,31 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile break; } - if (node.kind === SyntaxKind.AwaitKeyword) { - const functionDeclaration = findAncestor(node, n => isFunctionLikeDeclaration(n)); - const isAsyncFunction = functionDeclaration && some(functionDeclaration.modifiers, node => node.kind === SyntaxKind.AsyncKeyword); - return isAsyncFunction ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined; + // for functions with keyword modifiers + let findFunctionDecl: ((n: Node) => boolean | "quit") | undefined; + let checkFunctionDeclaration: ((decl: FunctionLikeDeclaration) => boolean) | undefined; + switch (node.kind) { + case SyntaxKind.ReturnKeyword: + findFunctionDecl = n => { + return isClassStaticBlockDeclaration(n) + ? "quit" + : isFunctionLikeDeclaration(n); + }; + break; + case SyntaxKind.AwaitKeyword: + findFunctionDecl = isFunctionLikeDeclaration; + checkFunctionDeclaration = (functionDeclaration: FunctionLikeDeclaration) => some(functionDeclaration.modifiers, node => node.kind === SyntaxKind.AsyncKeyword); + break; + case SyntaxKind.YieldKeyword: + findFunctionDecl = isFunctionLikeDeclaration; + checkFunctionDeclaration = functionDeclaration => !!functionDeclaration.asteriskToken; + break; } - if (node.kind === SyntaxKind.YieldKeyword) { - const functionDeclaration = findAncestor(node, n => isFunctionLikeDeclaration(n)); - const isGeneratorFunction = functionDeclaration && functionDeclaration.asteriskToken; - return isGeneratorFunction ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined; + if (findFunctionDecl) { + const functionDeclaration = findAncestor(node, findFunctionDecl) as FunctionLikeDeclaration | undefined; + const isCorrectDeclaration = functionDeclaration && (!checkFunctionDeclaration || checkFunctionDeclaration(functionDeclaration)); + return isCorrectDeclaration ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined; } if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) { From 1d76398f9016759467c4342bcdd731c0dff6f2ea Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 30 Oct 2024 18:59:58 -0700 Subject: [PATCH 2/5] fix for functions --- src/services/goToDefinition.ts | 18 +- .../goToDefinitionMember.baseline.jsonc | 22 ++ .../goToDefinitionModifiers.baseline.jsonc | 210 ++++++++++++++++++ ...DefinitionOverriddenMember6.baseline.jsonc | 17 +- ...DefinitionOverriddenMember7.baseline.jsonc | 17 +- tests/cases/fourslash/goToDefinitionMember.ts | 10 + .../fourslash/goToDefinitionModifiers.ts | 30 +++ 7 files changed, 316 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/goToDefinitionMember.baseline.jsonc create mode 100644 tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc create mode 100644 tests/cases/fourslash/goToDefinitionMember.ts create mode 100644 tests/cases/fourslash/goToDefinitionModifiers.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index c0b1fa1e95063..fcaf38965cb9b 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -64,6 +64,7 @@ import { isJSDocOverrideTag, isJsxOpeningLikeElement, isJumpStatementTarget, + isModifier, isModuleSpecifierLike, isNameOfFunctionDeclaration, isNewExpressionTarget, @@ -128,7 +129,10 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile const typeChecker = program.getTypeChecker(); if (node.kind === SyntaxKind.OverrideKeyword || (isIdentifier(node) && isJSDocOverrideTag(parent) && parent.tagName === node)) { - return getDefinitionFromOverriddenMember(typeChecker, node) || emptyArray; + const def = getDefinitionFromOverriddenMember(typeChecker, node); + if (def !== undefined || node.kind !== SyntaxKind.OverrideKeyword) { + return def || emptyArray; + } } // Labels @@ -152,7 +156,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile break; } - // for functions with keyword modifiers + // for keywords related to function or method declarations let findFunctionDecl: ((n: Node) => boolean | "quit") | undefined; let checkFunctionDeclaration: ((decl: FunctionLikeDeclaration) => boolean) | undefined; switch (node.kind) { @@ -163,16 +167,18 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile : isFunctionLikeDeclaration(n); }; break; + case SyntaxKind.AsyncKeyword: case SyntaxKind.AwaitKeyword: findFunctionDecl = isFunctionLikeDeclaration; checkFunctionDeclaration = (functionDeclaration: FunctionLikeDeclaration) => some(functionDeclaration.modifiers, node => node.kind === SyntaxKind.AsyncKeyword); break; case SyntaxKind.YieldKeyword: - findFunctionDecl = isFunctionLikeDeclaration; checkFunctionDeclaration = functionDeclaration => !!functionDeclaration.asteriskToken; + // falls through + case SyntaxKind.ExportKeyword: + findFunctionDecl = isFunctionLikeDeclaration; break; } - if (findFunctionDecl) { const functionDeclaration = findAncestor(node, findFunctionDecl) as FunctionLikeDeclaration | undefined; const isCorrectDeclaration = functionDeclaration && (!checkFunctionDeclaration || checkFunctionDeclaration(functionDeclaration)); @@ -225,6 +231,10 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile } } + if (isModifier(node) && isClassElement(parent)) { + symbol = parent.symbol; + } + // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!symbol) { diff --git a/tests/baselines/reference/goToDefinitionMember.baseline.jsonc b/tests/baselines/reference/goToDefinitionMember.baseline.jsonc new file mode 100644 index 0000000000000..78eb68634245c --- /dev/null +++ b/tests/baselines/reference/goToDefinitionMember.baseline.jsonc @@ -0,0 +1,22 @@ +// === goToDefinition === +// === /a.ts === +// class A { +// +// <|private [|{| textSpan: true |}z|]/*GOTO DEF*/: string;|> +// +// readonly x: string; +// +// --- (line: 7) skipped --- + + // === Details === + [ + { + "kind": "property", + "name": "z", + "containerName": "A", + "isLocal": true, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc new file mode 100644 index 0000000000000..8f5b6db7a4e13 --- /dev/null +++ b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc @@ -0,0 +1,210 @@ +// === goToDefinition === +// === /a.ts === +// /*GOTO DEF*/export class A { +// +// private z: string; +// +// --- (line: 5) skipped --- + + + +// === goToDefinition === +// === /a.ts === +// expo/*GOTO DEF*/rt class A { +// +// private z: string; +// +// --- (line: 5) skipped --- + + + +// === goToDefinition === +// === /a.ts === +// export/*GOTO DEF*/ class A { +// +// private z: string; +// +// --- (line: 5) skipped --- + + + +// === goToDefinition === +// === /a.ts === +// export class A { +// +// /*GOTO DEF*/<|private [|z|]: string;|> +// +// readonly x: string; +// +// --- (line: 7) skipped --- + + // === Details === + [ + { + "kind": "property", + "name": "z", + "containerName": "A", + "isLocal": true, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// export class A { +// +// private z: string; +// +// /*GOTO DEF*/<|readonly [|x|]: string;|> +// +// async a() { } +// +// --- (line: 9) skipped --- + + // === Details === + [ + { + "kind": "property", + "name": "x", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 3) skipped --- +// +// readonly x: string; +// +// /*GOTO DEF*/<|async [|a|]() { }|> +// +// override b() {} +// +// --- (line: 11) skipped --- + + // === Details === + [ + { + "kind": "method", + "name": "a", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 5) skipped --- +// +// async a() { } +// +// /*GOTO DEF*/<|override [|b|]() {}|> +// +// public async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "b", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 7) skipped --- +// +// override b() {} +// +// /*GOTO DEF*/<|public async [|c|]() { }|> +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "c", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 7) skipped --- +// +// override b() {} +// +// <|public/*GOTO DEF*/ async [|c|]() { }|> +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "c", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 7) skipped --- +// +// override b() {} +// +// <|public as/*GOTO DEF*/ync [|c|]() { }|> +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "c", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember6.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember6.baseline.jsonc index 62684d5287adc..81f192334a6b4 100644 --- a/tests/baselines/reference/goToDefinitionOverriddenMember6.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionOverriddenMember6.baseline.jsonc @@ -4,5 +4,18 @@ // m() {} // } // class Bar extends Foo { -// /*GOTO DEF*/override m1() {} -// } \ No newline at end of file +// /*GOTO DEF*/<|override [|m1|]() {}|> +// } + + // === Details === + [ + { + "kind": "method", + "name": "m1", + "containerName": "Bar", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionOverriddenMember7.baseline.jsonc b/tests/baselines/reference/goToDefinitionOverriddenMember7.baseline.jsonc index 1b8e13a8715b2..95dc0b73f0459 100644 --- a/tests/baselines/reference/goToDefinitionOverriddenMember7.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionOverriddenMember7.baseline.jsonc @@ -1,5 +1,18 @@ // === goToDefinition === // === /tests/cases/fourslash/goToDefinitionOverriddenMember7.ts === // class Foo { -// /*GOTO DEF*/override m() {} -// } \ No newline at end of file +// /*GOTO DEF*/<|override [|m|]() {}|> +// } + + // === Details === + [ + { + "kind": "method", + "name": "m", + "containerName": "Foo", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionMember.ts b/tests/cases/fourslash/goToDefinitionMember.ts new file mode 100644 index 0000000000000..c21e2799f5d8b --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionMember.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: /a.ts +//// class A { +//// private z/*z*/: string; +//// } + +verify.baselineGoToDefinition( + "z" +); diff --git a/tests/cases/fourslash/goToDefinitionModifiers.ts b/tests/cases/fourslash/goToDefinitionModifiers.ts new file mode 100644 index 0000000000000..0bba6551563b0 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionModifiers.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: /a.ts +//// /*export1*/expo/*export2*/rt/*export3*/ class A { +//// +//// /*private*/private z: string; +//// +//// /*readonly*/readonly x: string; +//// +//// /*async*/async a() { } +//// +//// /*override*/override b() {} +//// +//// /*public1*/public/*public2*/ as/*multipleModifiers*/ync c() { } +//// } +//// +//// exp/**/ort function foo() { } + +verify.baselineGoToDefinition( + "export1", + "export2", + "export3", + "private", + "readonly", + "async", + "override", + "public1", + "public2", + "multipleModifiers" +); From 12c318a8bf12605b1dc5f062b6b2c1339299163d Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 30 Oct 2024 19:38:13 -0700 Subject: [PATCH 3/5] fix for any named declaration --- src/services/goToDefinition.ts | 10 +-- .../goToDefinitionMember.baseline.jsonc | 6 +- .../goToDefinitionModifiers.baseline.jsonc | 84 +++++++++++++++++-- 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index fcaf38965cb9b..2bc4fa9702ded 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -66,6 +66,7 @@ import { isJumpStatementTarget, isModifier, isModuleSpecifierLike, + isNamedDeclaration, isNameOfFunctionDeclaration, isNewExpressionTarget, isObjectBindingPattern, @@ -156,7 +157,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile break; } - // for keywords related to function or method declarations + // for keywords related to function or method definitions let findFunctionDecl: ((n: Node) => boolean | "quit") | undefined; let checkFunctionDeclaration: ((decl: FunctionLikeDeclaration) => boolean) | undefined; switch (node.kind) { @@ -167,15 +168,12 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile : isFunctionLikeDeclaration(n); }; break; - case SyntaxKind.AsyncKeyword: case SyntaxKind.AwaitKeyword: - findFunctionDecl = isFunctionLikeDeclaration; checkFunctionDeclaration = (functionDeclaration: FunctionLikeDeclaration) => some(functionDeclaration.modifiers, node => node.kind === SyntaxKind.AsyncKeyword); + findFunctionDecl = isFunctionLikeDeclaration; break; case SyntaxKind.YieldKeyword: checkFunctionDeclaration = functionDeclaration => !!functionDeclaration.asteriskToken; - // falls through - case SyntaxKind.ExportKeyword: findFunctionDecl = isFunctionLikeDeclaration; break; } @@ -231,7 +229,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile } } - if (isModifier(node) && isClassElement(parent)) { + if (isModifier(node) && (isClassElement(parent) || isNamedDeclaration(parent))) { symbol = parent.symbol; } diff --git a/tests/baselines/reference/goToDefinitionMember.baseline.jsonc b/tests/baselines/reference/goToDefinitionMember.baseline.jsonc index 78eb68634245c..56d045363ee91 100644 --- a/tests/baselines/reference/goToDefinitionMember.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionMember.baseline.jsonc @@ -1,12 +1,8 @@ // === goToDefinition === // === /a.ts === // class A { -// // <|private [|{| textSpan: true |}z|]/*GOTO DEF*/: string;|> -// -// readonly x: string; -// -// --- (line: 7) skipped --- +// } // === Details === [ diff --git a/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc index 8f5b6db7a4e13..e629d167bd85a 100644 --- a/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc @@ -1,30 +1,96 @@ // === goToDefinition === // === /a.ts === -// /*GOTO DEF*/export class A { +// /*GOTO DEF*/<|export class [|A|] { // // private z: string; // -// --- (line: 5) skipped --- +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] // === goToDefinition === // === /a.ts === -// expo/*GOTO DEF*/rt class A { +// <|expo/*GOTO DEF*/rt class [|A|] { // // private z: string; // -// --- (line: 5) skipped --- +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] // === goToDefinition === // === /a.ts === -// export/*GOTO DEF*/ class A { +// <|export/*GOTO DEF*/ class [|A|] { // // private z: string; // -// --- (line: 5) skipped --- +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] @@ -100,7 +166,8 @@ "containerName": "A", "isLocal": false, "isAmbient": false, - "unverified": false + "unverified": false, + "failedAliasResolution": false } ] @@ -205,6 +272,7 @@ "containerName": "A", "isLocal": false, "isAmbient": false, - "unverified": false + "unverified": false, + "failedAliasResolution": false } ] \ No newline at end of file From 873188557d264dd2fd071c89ddf6a5d4687f12ca Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 30 Oct 2024 21:03:16 -0700 Subject: [PATCH 4/5] gototypedef --- src/services/goToDefinition.ts | 6 +- .../goToDefinitionModifiers.baseline.jsonc | 171 ++++- ...goToTypeDefinitionModifiers.baseline.jsonc | 597 ++++++++++++++++++ .../fourslash/goToDefinitionModifiers.ts | 30 +- .../fourslash/goToTypeDefinitionModifiers.ts | 40 ++ 5 files changed, 815 insertions(+), 29 deletions(-) create mode 100644 tests/baselines/reference/goToTypeDefinitionModifiers.baseline.jsonc create mode 100644 tests/cases/fourslash/goToTypeDefinitionModifiers.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 2bc4fa9702ded..083c5e4d53e7c 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -473,7 +473,11 @@ export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile if (isImportMeta(node.parent) && node.parent.name === node) { return definitionFromType(typeChecker.getTypeAtLocation(node.parent), typeChecker, node.parent, /*failedAliasResolution*/ false); } - const { symbol, failedAliasResolution } = getSymbol(node, typeChecker, /*stopAtAlias*/ false); + let { symbol, failedAliasResolution } = getSymbol(node, typeChecker, /*stopAtAlias*/ false); + if (isModifier(node) && (isClassElement(node.parent) || isNamedDeclaration(node.parent))) { + symbol = node.parent.symbol; + failedAliasResolution = false; + } if (!symbol) return undefined; const typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node); diff --git a/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc index e629d167bd85a..2916c40cfcf04 100644 --- a/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionModifiers.baseline.jsonc @@ -32,7 +32,7 @@ // === goToDefinition === // === /a.ts === -// <|expo/*GOTO DEF*/rt class [|A|] { +// <|export class [|{| textSpan: true |}A|]/*GOTO DEF*/ { // // private z: string; // @@ -64,28 +64,21 @@ // === goToDefinition === // === /a.ts === -// <|export/*GOTO DEF*/ class [|A|] { +// export class A { // -// private z: string; +// /*GOTO DEF*/<|private [|z|]: string;|> // // readonly x: string; // -// async a() { } -// -// override b() {} -// -// public async c() { } -// }|> -// -// export function foo() { } +// --- (line: 7) skipped --- // === Details === [ { - "kind": "class", - "name": "A", - "containerName": "\"/a\"", - "isLocal": false, + "kind": "property", + "name": "z", + "containerName": "A", + "isLocal": true, "isAmbient": false, "unverified": false, "failedAliasResolution": false @@ -98,7 +91,7 @@ // === /a.ts === // export class A { // -// /*GOTO DEF*/<|private [|z|]: string;|> +// <|private [|{| textSpan: true |}z|]/*GOTO DEF*/: string;|> // // readonly x: string; // @@ -146,6 +139,33 @@ +// === goToDefinition === +// === /a.ts === +// export class A { +// +// private z: string; +// +// <|readonly [|{| textSpan: true |}x|]/*GOTO DEF*/: string;|> +// +// async a() { } +// +// --- (line: 9) skipped --- + + // === Details === + [ + { + "kind": "property", + "name": "x", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + // === goToDefinition === // === /a.ts === // --- (line: 3) skipped --- @@ -173,6 +193,31 @@ +// === goToDefinition === +// === /a.ts === +// --- (line: 3) skipped --- +// +// readonly x: string; +// +// <|async [|{| textSpan: true |}a|]/*GOTO DEF*/() { }|> +// +// override b() {} +// +// --- (line: 11) skipped --- + + // === Details === + [ + { + "kind": "method", + "name": "a", + "containerName": "A", + "isLocal": false, + "isAmbient": false + } + ] + + + // === goToDefinition === // === /a.ts === // --- (line: 5) skipped --- @@ -201,6 +246,32 @@ +// === goToDefinition === +// === /a.ts === +// --- (line: 5) skipped --- +// +// async a() { } +// +// <|override [|{| textSpan: true |}b|]/*GOTO DEF*/() {}|> +// +// public async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "b", + "containerName": "A", + "isLocal": false, + "isAmbient": false + } + ] + + + // === goToDefinition === // === /a.ts === // --- (line: 7) skipped --- @@ -275,4 +346,72 @@ "unverified": false, "failedAliasResolution": false } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 7) skipped --- +// +// override b() {} +// +// <|public async [|{| textSpan: true |}c|]/*GOTO DEF*/() { }|> +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "c", + "containerName": "A", + "isLocal": false, + "isAmbient": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 10) skipped --- +// public async c() { } +// } +// +// <|exp/*GOTO DEF*/ort function [|foo|]() { }|> + + // === Details === + [ + { + "kind": "function", + "name": "foo", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToDefinition === +// === /a.ts === +// --- (line: 10) skipped --- +// public async c() { } +// } +// +// <|export function [|{| textSpan: true |}foo|]/*GOTO DEF*/() { }|> + + // === Details === + [ + { + "kind": "function", + "name": "foo", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false + } ] \ No newline at end of file diff --git a/tests/baselines/reference/goToTypeDefinitionModifiers.baseline.jsonc b/tests/baselines/reference/goToTypeDefinitionModifiers.baseline.jsonc new file mode 100644 index 0000000000000..0971205dbcaaf --- /dev/null +++ b/tests/baselines/reference/goToTypeDefinitionModifiers.baseline.jsonc @@ -0,0 +1,597 @@ +// === goToType === +// === /a.ts === +// /*GOTO TYPE*/<|export class [|A|] { +// +// private z: string; +// +// private y: A; +// +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// <|export class [|A|]/*GOTO TYPE*/ { +// +// private z: string; +// +// private y: A; +// +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// export class A { +// +// /*GOTO TYPE*/private z: string; +// +// private y: A; +// +// --- (line: 7) skipped --- + + + +// === goToType === +// === /a.ts === +// export class A { +// +// private z/*GOTO TYPE*/: string; +// +// private y: A; +// +// --- (line: 7) skipped --- + + + +// === goToType === +// === /a.ts === +// <|export class [|A|] { +// +// private z: string; +// +// /*GOTO TYPE*/private y: A; +// +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// <|export class [|A|] { +// +// private z: string; +// +// private y/*GOTO TYPE*/: A; +// +// readonly x: string; +// +// async a() { } +// +// override b() {} +// +// public async c() { } +// }|> +// +// export function foo() { } + + // === Details === + [ + { + "kind": "class", + "name": "A", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// --- (line: 3) skipped --- +// +// private y: A; +// +// /*GOTO TYPE*/readonly x: string; +// +// async a() { } +// +// --- (line: 11) skipped --- + + + +// === goToType === +// === /a.ts === +// --- (line: 3) skipped --- +// +// private y: A; +// +// readonly x/*GOTO TYPE*/: string; +// +// async a() { } +// +// --- (line: 11) skipped --- + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 5) skipped --- +// +// readonly x: string; +// +// /*GOTO TYPE*/async a() { } +// +// override b() {} +// +// --- (line: 13) skipped --- + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 5) skipped --- +// +// readonly x: string; +// +// async a/*GOTO TYPE*/() { } +// +// override b() {} +// +// --- (line: 13) skipped --- + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// --- (line: 7) skipped --- +// +// async a() { } +// +// /*GOTO TYPE*/<|override [|b|]() {}|> +// +// public async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "b", + "containerName": "A", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// --- (line: 7) skipped --- +// +// async a() { } +// +// <|override [|b|]/*GOTO TYPE*/() {}|> +// +// public async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "method", + "name": "b", + "containerName": "A", + "isLocal": false, + "isAmbient": false + } + ] + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 9) skipped --- +// +// override b() {} +// +// /*GOTO TYPE*/public async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 9) skipped --- +// +// override b() {} +// +// public/*GOTO TYPE*/ async c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 9) skipped --- +// +// override b() {} +// +// public as/*GOTO TYPE*/ync c() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === lib.d.ts === +// --- (line: --) skipped --- +// /** +// * Represents the completion of an asynchronous operation +// */ +// <|interface [|Promise|] { +// /** +// * Attaches callbacks for the resolution and/or rejection of the Promise. +// * @param onfulfilled The callback to execute when the Promise is resolved. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of which ever callback is executed. +// */ +// then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; +// +// /** +// * Attaches a callback for only the rejection of the Promise. +// * @param onrejected The callback to execute when the Promise is rejected. +// * @returns A Promise for the completion of the callback. +// */ +// catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +// }|> +// +// /** +// * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`. +// --- (line: --) skipped --- + +// === /a.ts === +// --- (line: 9) skipped --- +// +// override b() {} +// +// public async c/*GOTO TYPE*/() { } +// } +// +// export function foo() { } + + // === Details === + [ + { + "kind": "interface", + "name": "Promise", + "containerName": "", + "isLocal": false, + "isAmbient": true, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// --- (line: 12) skipped --- +// public async c() { } +// } +// +// <|exp/*GOTO TYPE*/ort function [|foo|]() { }|> + + // === Details === + [ + { + "kind": "function", + "name": "foo", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] + + + +// === goToType === +// === /a.ts === +// --- (line: 12) skipped --- +// public async c() { } +// } +// +// <|export function [|foo|]/*GOTO TYPE*/() { }|> + + // === Details === + [ + { + "kind": "function", + "name": "foo", + "containerName": "\"/a\"", + "isLocal": false, + "isAmbient": false + } + ] \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionModifiers.ts b/tests/cases/fourslash/goToDefinitionModifiers.ts index 0bba6551563b0..224b4e5677603 100644 --- a/tests/cases/fourslash/goToDefinitionModifiers.ts +++ b/tests/cases/fourslash/goToDefinitionModifiers.ts @@ -1,30 +1,36 @@ /// // @Filename: /a.ts -//// /*export1*/expo/*export2*/rt/*export3*/ class A { +//// /*export*/export class A/*A*/ { //// -//// /*private*/private z: string; -//// -//// /*readonly*/readonly x: string; +//// /*private*/private z/*z*/: string; +//// +//// /*readonly*/readonly x/*x*/: string; //// -//// /*async*/async a() { } +//// /*async*/async a/*a*/() { } //// -//// /*override*/override b() {} +//// /*override*/override b/*b*/() {} //// -//// /*public1*/public/*public2*/ as/*multipleModifiers*/ync c() { } +//// /*public1*/public/*public2*/ as/*multipleModifiers*/ync c/*c*/() { } //// } //// -//// exp/**/ort function foo() { } +//// exp/*exportFunction*/ort function foo/*foo*/() { } verify.baselineGoToDefinition( - "export1", - "export2", - "export3", + "export", + "A", "private", + "z", "readonly", + "x", "async", + "a", "override", + "b", "public1", "public2", - "multipleModifiers" + "multipleModifiers", + "c", + "exportFunction", + "foo" ); diff --git a/tests/cases/fourslash/goToTypeDefinitionModifiers.ts b/tests/cases/fourslash/goToTypeDefinitionModifiers.ts new file mode 100644 index 0000000000000..25b79734fa40f --- /dev/null +++ b/tests/cases/fourslash/goToTypeDefinitionModifiers.ts @@ -0,0 +1,40 @@ +/// + +// @Filename: /a.ts +//// /*export*/export class A/*A*/ { +//// +//// /*private*/private z/*z*/: string; +//// +//// /*private2*/private y/*y*/: A; +//// +//// /*readonly*/readonly x/*x*/: string; +//// +//// /*async*/async a/*a*/() { } +//// +//// /*override*/override b/*b*/() {} +//// +//// /*public1*/public/*public2*/ as/*multipleModifiers*/ync c/*c*/() { } +//// } +//// +//// exp/*exportFunction*/ort function foo/*foo*/() { } + +verify.baselineGoToType( + "export", + "A", + "private", + "z", + "private2", + "y", + "readonly", + "x", + "async", + "a", + "override", + "b", + "public1", + "public2", + "multipleModifiers", + "c", + "exportFunction", + "foo" +); From 57c2f6dab5362a96469cccd020b151a1d57a36f4 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 14 Jan 2025 18:05:47 -0800 Subject: [PATCH 5/5] allow more keywords to return definitions --- src/services/goToDefinition.ts | 19 ++---------------- .../goToDefinitionAwait1.baseline.jsonc | 16 +++++++++++++-- .../goToDefinitionAwait3.baseline.jsonc | 20 ++++++++++++++++--- .../goToDefinitionReturn5.baseline.jsonc | 16 +++++++++++++-- .../goToDefinitionYield3.baseline.jsonc | 20 ++++++++++++++++--- .../goToDefinitionYield4.baseline.jsonc | 16 +++++++++++++-- 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 083c5e4d53e7c..48fdb95aa0cff 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -159,28 +159,13 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile // for keywords related to function or method definitions let findFunctionDecl: ((n: Node) => boolean | "quit") | undefined; - let checkFunctionDeclaration: ((decl: FunctionLikeDeclaration) => boolean) | undefined; switch (node.kind) { case SyntaxKind.ReturnKeyword: - findFunctionDecl = n => { - return isClassStaticBlockDeclaration(n) - ? "quit" - : isFunctionLikeDeclaration(n); - }; - break; case SyntaxKind.AwaitKeyword: - checkFunctionDeclaration = (functionDeclaration: FunctionLikeDeclaration) => some(functionDeclaration.modifiers, node => node.kind === SyntaxKind.AsyncKeyword); - findFunctionDecl = isFunctionLikeDeclaration; - break; case SyntaxKind.YieldKeyword: - checkFunctionDeclaration = functionDeclaration => !!functionDeclaration.asteriskToken; findFunctionDecl = isFunctionLikeDeclaration; - break; - } - if (findFunctionDecl) { - const functionDeclaration = findAncestor(node, findFunctionDecl) as FunctionLikeDeclaration | undefined; - const isCorrectDeclaration = functionDeclaration && (!checkFunctionDeclaration || checkFunctionDeclaration(functionDeclaration)); - return isCorrectDeclaration ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined; + const functionDeclaration = findAncestor(node, findFunctionDecl) as FunctionLikeDeclaration | undefined; + return functionDeclaration ? [createDefinitionFromSignatureDeclaration(typeChecker, functionDeclaration)] : undefined; } if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) { diff --git a/tests/baselines/reference/goToDefinitionAwait1.baseline.jsonc b/tests/baselines/reference/goToDefinitionAwait1.baseline.jsonc index 38a13e7262b99..03b0d260a7150 100644 --- a/tests/baselines/reference/goToDefinitionAwait1.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionAwait1.baseline.jsonc @@ -26,6 +26,18 @@ // async function foo() { // await Promise.resolve(0); // } -// function notAsync() { +// <|function [|notAsync|]() { // /*GOTO DEF*/await Promise.resolve(0); -// } \ No newline at end of file +// }|> + + // === Details === + [ + { + "kind": "function", + "name": "notAsync", + "containerName": "", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionAwait3.baseline.jsonc b/tests/baselines/reference/goToDefinitionAwait3.baseline.jsonc index 2815a6c96ce9f..f0e600a17c8f2 100644 --- a/tests/baselines/reference/goToDefinitionAwait3.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionAwait3.baseline.jsonc @@ -1,12 +1,26 @@ // === goToDefinition === // === /tests/cases/fourslash/goToDefinitionAwait3.ts === // class C { -// notAsync() { +// <|[|notAsync|]() { // /*GOTO DEF*/await Promise.resolve(0); -// } +// }|> // // async foo() { -// --- (line: 7) skipped --- +// await Promise.resolve(0); +// } +// } + + // === Details === + [ + { + "kind": "method", + "name": "notAsync", + "containerName": "C", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] diff --git a/tests/baselines/reference/goToDefinitionReturn5.baseline.jsonc b/tests/baselines/reference/goToDefinitionReturn5.baseline.jsonc index 27241ffa15e51..eb929a8384d79 100644 --- a/tests/baselines/reference/goToDefinitionReturn5.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionReturn5.baseline.jsonc @@ -1,7 +1,19 @@ // === goToDefinition === // === /tests/cases/fourslash/goToDefinitionReturn5.ts === -// function foo() { +// <|function [|foo|]() { // class Foo { // static { /*GOTO DEF*/return; } // } -// } \ No newline at end of file +// }|> + + // === Details === + [ + { + "kind": "function", + "name": "foo", + "containerName": "", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionYield3.baseline.jsonc b/tests/baselines/reference/goToDefinitionYield3.baseline.jsonc index 16eb5a704adca..0981fd26dfd8a 100644 --- a/tests/baselines/reference/goToDefinitionYield3.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionYield3.baseline.jsonc @@ -1,12 +1,26 @@ // === goToDefinition === // === /tests/cases/fourslash/goToDefinitionYield3.ts === // class C { -// notAGenerator() { +// <|[|notAGenerator|]() { // /*GOTO DEF*/yield 0; -// } +// }|> // // foo*() { -// --- (line: 7) skipped --- +// yield 0; +// } +// } + + // === Details === + [ + { + "kind": "method", + "name": "notAGenerator", + "containerName": "C", + "isLocal": false, + "isAmbient": false, + "unverified": false + } + ] diff --git a/tests/baselines/reference/goToDefinitionYield4.baseline.jsonc b/tests/baselines/reference/goToDefinitionYield4.baseline.jsonc index 28af052f964f8..e23f35a315ec0 100644 --- a/tests/baselines/reference/goToDefinitionYield4.baseline.jsonc +++ b/tests/baselines/reference/goToDefinitionYield4.baseline.jsonc @@ -1,5 +1,17 @@ // === goToDefinition === // === /tests/cases/fourslash/goToDefinitionYield4.ts === // function* gen() { -// class C { [/*GOTO DEF*/yield 10]() {} } -// } \ No newline at end of file +// class C { <|[|[/*GOTO DEF*/yield 10]|]() {}|> } +// } + + // === Details === + [ + { + "kind": "method", + "name": "[yield 10]", + "containerName": "C", + "isLocal": true, + "isAmbient": false, + "unverified": false + } + ] \ No newline at end of file