From 8d84a687762c0a306327436a5b47cbf779b3ee19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 9 Jul 2024 22:59:54 +0200 Subject: [PATCH] Fixed crash when finding all references when `JSDocImportTag`s are involved (#59207) --- src/services/importTracker.ts | 3 +- .../findAllRefsJsDocImportTag2.baseline.jsonc | 185 ++++++++++++ .../findAllRefsJsDocImportTag3.baseline.jsonc | 185 ++++++++++++ .../findAllRefsJsDocImportTag4.baseline.jsonc | 41 +++ .../findAllRefsJsDocImportTag5.baseline.jsonc | 265 ++++++++++++++++++ .../fourslash/findAllRefsJsDocImportTag2.ts | 33 +++ .../fourslash/findAllRefsJsDocImportTag3.ts | 33 +++ .../fourslash/findAllRefsJsDocImportTag4.ts | 33 +++ .../fourslash/findAllRefsJsDocImportTag5.ts | 11 + 9 files changed, 787 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/findAllRefsJsDocImportTag2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsJsDocImportTag3.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsJsDocImportTag4.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsJsDocImportTag5.baseline.jsonc create mode 100644 tests/cases/fourslash/findAllRefsJsDocImportTag2.ts create mode 100644 tests/cases/fourslash/findAllRefsJsDocImportTag3.ts create mode 100644 tests/cases/fourslash/findAllRefsJsDocImportTag4.ts create mode 100644 tests/cases/fourslash/findAllRefsJsDocImportTag5.ts diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index ab08c189857..316d3874fb4 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -787,10 +787,9 @@ function getContainingModuleSymbol(importer: Importer, checker: TypeChecker): Sy } function getSourceFileLikeForImportDeclaration(node: ImporterOrCallExpression): SourceFileLike { - if (node.kind === SyntaxKind.CallExpression) { + if (node.kind === SyntaxKind.CallExpression || node.kind === SyntaxKind.JSDocImportTag) { return node.getSourceFile(); } - const { parent } = node; if (parent.kind === SyntaxKind.SourceFile) { return parent as SourceFile; diff --git a/tests/baselines/reference/findAllRefsJsDocImportTag2.baseline.jsonc b/tests/baselines/reference/findAllRefsJsDocImportTag2.baseline.jsonc new file mode 100644 index 00000000000..f70ad440207 --- /dev/null +++ b/tests/baselines/reference/findAllRefsJsDocImportTag2.baseline.jsonc @@ -0,0 +1,185 @@ +// === findAllReferences === +// === /player.js === +// <|import [|{| defId: 0, isWriteAccess: true |}Component|] from './component.js';|> +// +// /** +// * @extends [|{| defId: 0 |}Component|]/*FIND ALL REFS*/ +// */ +// export class Player extends [|{| defId: 0 |}Component|] {} + +// === /component.js === +// <|export default class [|{| defId: 1, isWriteAccess: true |}Component|] { +// constructor() { +// this.id_ = Math.random(); +// } +// id() { +// return this.id_; +// } +// }|> + +// === /spatial-navigation.js === +// /** <|@import [|{| defId: 2, isWriteAccess: true |}Component|] from './component.js'|> */ +// +// export class SpatialNavigation { +// /** +// * @param {[|{| defId: 2 |}Component|]} component +// */ +// add(component) {} +// } + + // === Definitions === + // === /player.js === + // <|import [|{| defId: 0 |}Component|] from './component.js';|> + // + // /** + // * @extends Component/*FIND ALL REFS*/ + // */ + // export class Player extends Component {} + + // === /component.js === + // <|export default class [|{| defId: 1 |}Component|] { + // constructor() { + // this.id_ = Math.random(); + // } + // id() { + // return this.id_; + // } + // }|> + + // === /spatial-navigation.js === + // /** <|@import [|{| defId: 2 |}Component|] from './component.js'|> */ + // + // export class SpatialNavigation { + // /** + // --- (line: 5) skipped --- + + // === Details === + [ + { + "defId": 0, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) class Component\nimport Component", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + } + ] + }, + { + "defId": 1, + "containerKind": "", + "containerName": "", + "kind": "class", + "name": "class Component", + "displayParts": [ + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "className" + } + ] + }, + { + "defId": 2, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) class Component\nimport Component", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + } + ] + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/findAllRefsJsDocImportTag3.baseline.jsonc b/tests/baselines/reference/findAllRefsJsDocImportTag3.baseline.jsonc new file mode 100644 index 00000000000..0f43433dc06 --- /dev/null +++ b/tests/baselines/reference/findAllRefsJsDocImportTag3.baseline.jsonc @@ -0,0 +1,185 @@ +// === findAllReferences === +// === /player.js === +// <|import { [|{| defId: 0, isWriteAccess: true |}Component|] } from './component.js';|> +// +// /** +// * @extends [|{| defId: 0 |}Component|]/*FIND ALL REFS*/ +// */ +// export class Player extends [|{| defId: 0 |}Component|] {} + +// === /component.js === +// <|export class [|{| defId: 1, isWriteAccess: true |}Component|] { +// constructor() { +// this.id_ = Math.random(); +// } +// id() { +// return this.id_; +// } +// }|> + +// === /spatial-navigation.js === +// /** <|@import { [|{| defId: 2, isWriteAccess: true |}Component|] } from './component.js'|> */ +// +// export class SpatialNavigation { +// /** +// * @param {[|{| defId: 2 |}Component|]} component +// */ +// add(component) {} +// } + + // === Definitions === + // === /player.js === + // <|import { [|{| defId: 0 |}Component|] } from './component.js';|> + // + // /** + // * @extends Component/*FIND ALL REFS*/ + // */ + // export class Player extends Component {} + + // === /component.js === + // <|export class [|{| defId: 1 |}Component|] { + // constructor() { + // this.id_ = Math.random(); + // } + // id() { + // return this.id_; + // } + // }|> + + // === /spatial-navigation.js === + // /** <|@import { [|{| defId: 2 |}Component|] } from './component.js'|> */ + // + // export class SpatialNavigation { + // /** + // --- (line: 5) skipped --- + + // === Details === + [ + { + "defId": 0, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) class Component\nimport Component", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + } + ] + }, + { + "defId": 1, + "containerKind": "", + "containerName": "", + "kind": "class", + "name": "class Component", + "displayParts": [ + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "className" + } + ] + }, + { + "defId": 2, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) class Component\nimport Component", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Component", + "kind": "aliasName" + } + ] + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/findAllRefsJsDocImportTag4.baseline.jsonc b/tests/baselines/reference/findAllRefsJsDocImportTag4.baseline.jsonc new file mode 100644 index 00000000000..64d26114855 --- /dev/null +++ b/tests/baselines/reference/findAllRefsJsDocImportTag4.baseline.jsonc @@ -0,0 +1,41 @@ +// === findAllReferences === +// === /player.js === +// <|import * as [|{| isWriteAccess: true |}C|] from './component.js';|> +// +// /** +// * @extends [|C|]/*FIND ALL REFS*/.Component +// */ +// export class Player extends Component {} + + // === Definitions === + // === /player.js === + // <|import * as [|C|] from './component.js';|> + // + // /** + // * @extends C/*FIND ALL REFS*/.Component + // */ + // export class Player extends Component {} + + // === Details === + [ + { + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "import C", + "displayParts": [ + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "C", + "kind": "aliasName" + } + ] + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/findAllRefsJsDocImportTag5.baseline.jsonc b/tests/baselines/reference/findAllRefsJsDocImportTag5.baseline.jsonc new file mode 100644 index 00000000000..29d2171c09a --- /dev/null +++ b/tests/baselines/reference/findAllRefsJsDocImportTag5.baseline.jsonc @@ -0,0 +1,265 @@ +// === findAllReferences === +// === /a.js === +// <|export default function /*FIND ALL REFS*/[|{| defId: 0, isWriteAccess: true, isDefinition: true |}a|]() {}|> + +// === /b.js === +// /** <|@import [|{| defId: 1, isWriteAccess: true |}a|], * as ns from "./a"|> */ + + // === Definitions === + // === /a.js === + // <|export default function /*FIND ALL REFS*/[|{| defId: 0 |}a|]() {}|> + + // === /b.js === + // /** <|@import [|{| defId: 1 |}a|], * as ns from "./a"|> */ + + // === Details === + [ + { + "defId": 0, + "containerKind": "", + "containerName": "", + "kind": "function", + "name": "function a(): void", + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ] + }, + { + "defId": 1, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) function a(): void\nimport a", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "aliasName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "aliasName" + } + ] + } + ] + + + +// === findAllReferences === +// === /b.js === +// /** <|@import /*FIND ALL REFS*/[|{| defId: 0, isWriteAccess: true, isDefinition: true |}a|], * as ns from "./a"|> */ + +// === /a.js === +// <|export default function [|{| defId: 1, isWriteAccess: true |}a|]() {}|> + + // === Definitions === + // === /b.js === + // /** <|@import /*FIND ALL REFS*/[|{| defId: 0 |}a|], * as ns from "./a"|> */ + + // === /a.js === + // <|export default function [|{| defId: 1 |}a|]() {}|> + + // === Details === + [ + { + "defId": 0, + "containerKind": "", + "containerName": "", + "kind": "alias", + "name": "(alias) function a(): void\nimport a", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "aliasName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "aliasName" + } + ] + }, + { + "defId": 1, + "containerKind": "", + "containerName": "", + "kind": "function", + "name": "function a(): void", + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ] + } + ] \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsJsDocImportTag2.ts b/tests/cases/fourslash/findAllRefsJsDocImportTag2.ts new file mode 100644 index 00000000000..647826cd637 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsJsDocImportTag2.ts @@ -0,0 +1,33 @@ +/// + +// @checkJs: true + +// @Filename: /component.js +//// export default class Component { +//// constructor() { +//// this.id_ = Math.random(); +//// } +//// id() { +//// return this.id_; +//// } +//// } + +// @Filename: /spatial-navigation.js +//// /** @import Component from './component.js' */ +//// +//// export class SpatialNavigation { +//// /** +//// * @param {Component} component +//// */ +//// add(component) {} +//// } + +// @Filename: /player.js +//// import Component from './component.js'; +//// +//// /** +//// * @extends Component/*1*/ +//// */ +//// export class Player extends Component {} + +verify.baselineFindAllReferences("1"); diff --git a/tests/cases/fourslash/findAllRefsJsDocImportTag3.ts b/tests/cases/fourslash/findAllRefsJsDocImportTag3.ts new file mode 100644 index 00000000000..24af38cc711 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsJsDocImportTag3.ts @@ -0,0 +1,33 @@ +/// + +// @checkJs: true + +// @Filename: /component.js +//// export class Component { +//// constructor() { +//// this.id_ = Math.random(); +//// } +//// id() { +//// return this.id_; +//// } +//// } + +// @Filename: /spatial-navigation.js +//// /** @import { Component } from './component.js' */ +//// +//// export class SpatialNavigation { +//// /** +//// * @param {Component} component +//// */ +//// add(component) {} +//// } + +// @Filename: /player.js +//// import { Component } from './component.js'; +//// +//// /** +//// * @extends Component/*1*/ +//// */ +//// export class Player extends Component {} + +verify.baselineFindAllReferences("1"); diff --git a/tests/cases/fourslash/findAllRefsJsDocImportTag4.ts b/tests/cases/fourslash/findAllRefsJsDocImportTag4.ts new file mode 100644 index 00000000000..631e328d9dd --- /dev/null +++ b/tests/cases/fourslash/findAllRefsJsDocImportTag4.ts @@ -0,0 +1,33 @@ +/// + +// @checkJs: true + +// @Filename: /component.js +//// export class Component { +//// constructor() { +//// this.id_ = Math.random(); +//// } +//// id() { +//// return this.id_; +//// } +//// } + +// @Filename: /spatial-navigation.js +//// /** @import * as C from './component.js' */ +//// +//// export class SpatialNavigation { +//// /** +//// * @param {C.Component} component +//// */ +//// add(component) {} +//// } + +// @Filename: /player.js +//// import * as C from './component.js'; +//// +//// /** +//// * @extends C/*1*/.Component +//// */ +//// export class Player extends Component {} + +verify.baselineFindAllReferences("1"); diff --git a/tests/cases/fourslash/findAllRefsJsDocImportTag5.ts b/tests/cases/fourslash/findAllRefsJsDocImportTag5.ts new file mode 100644 index 00000000000..c986aa7aea7 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsJsDocImportTag5.ts @@ -0,0 +1,11 @@ +/// + +// @checkJs: true + +// @Filename: /a.js +//// export default function /*0*/a() {} + +// @Filename: /b.js +//// /** @import /*1*/a, * as ns from "./a" */ + +verify.baselineFindAllReferences("0", "1");