fix(49629): fix crash in find-all-refs when using module.exports/export= with arrays/primitives (#50291)

This commit is contained in:
Oleksandr T
2022-08-15 15:14:26 -07:00
committed by GitHub
parent bc52ff6f4b
commit 61d8a8d7f3
3 changed files with 522 additions and 6 deletions
+7 -6
View File
@@ -555,6 +555,7 @@ namespace ts.FindAllReferences {
// Similarly, skip past the symbol for 'export ='
if (importedSymbol.escapedName === "export=") {
importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
if (importedSymbol === undefined) return undefined;
}
// If the import has a different name than the export, do not continue searching.
@@ -577,22 +578,22 @@ namespace ts.FindAllReferences {
}
}
function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker): Symbol {
function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker): Symbol | undefined {
if (importedSymbol.flags & SymbolFlags.Alias) {
return Debug.checkDefined(checker.getImmediateAliasedSymbol(importedSymbol));
return checker.getImmediateAliasedSymbol(importedSymbol);
}
const decl = Debug.checkDefined(importedSymbol.valueDeclaration);
if (isExportAssignment(decl)) { // `export = class {}`
return Debug.checkDefined(decl.expression.symbol);
return decl.expression.symbol;
}
else if (isBinaryExpression(decl)) { // `module.exports = class {}`
return Debug.checkDefined(decl.right.symbol);
return decl.right.symbol;
}
else if (isSourceFile(decl)) { // json module
return Debug.checkDefined(decl.symbol);
return decl.symbol;
}
return Debug.fail();
return undefined;
}
// If a reference is a class expression, the exported node would be its parent.
@@ -0,0 +1,479 @@
// === /foo.ts ===
// import * as /*FIND ALL REFS*/[|a|] from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import a",
"textSpan": {
"start": 12,
"length": 1
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "a",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 0,
"length": 27
}
},
"references": [
{
"textSpan": {
"start": 12,
"length": 1
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 0,
"length": 27
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import /*FIND ALL REFS*/[|aDefault|] from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import aDefault",
"textSpan": {
"start": 35,
"length": 8
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "aDefault",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 28,
"length": 29
}
},
"references": [
{
"textSpan": {
"start": 35,
"length": 8
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 28,
"length": 29
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as /*FIND ALL REFS*/[|b|] from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import b",
"textSpan": {
"start": 70,
"length": 1
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "b",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 58,
"length": 27
}
},
"references": [
{
"textSpan": {
"start": 70,
"length": 1
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 58,
"length": 27
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import /*FIND ALL REFS*/[|bDefault|] from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import bDefault",
"textSpan": {
"start": 93,
"length": 8
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "bDefault",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 86,
"length": 29
}
},
"references": [
{
"textSpan": {
"start": 93,
"length": 8
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 86,
"length": 29
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as /*FIND ALL REFS*/[|c|] from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import c",
"textSpan": {
"start": 129,
"length": 1
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "c",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 117,
"length": 24
}
},
"references": [
{
"textSpan": {
"start": 129,
"length": 1
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 117,
"length": 24
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import /*FIND ALL REFS*/[|cDefault|] from "./c"
// import * as d from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import cDefault",
"textSpan": {
"start": 149,
"length": 8
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "cDefault",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 142,
"length": 26
}
},
"references": [
{
"textSpan": {
"start": 149,
"length": 8
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 142,
"length": 26
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as /*FIND ALL REFS*/[|d|] from "./d"
// import dDefault from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import d",
"textSpan": {
"start": 181,
"length": 1
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "d",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 169,
"length": 24
}
},
"references": [
{
"textSpan": {
"start": 181,
"length": 1
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 169,
"length": 24
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
// === /foo.ts ===
// import * as a from "./a.js"
// import aDefault from "./a.js"
// import * as b from "./b.js"
// import bDefault from "./b.js"
//
// import * as c from "./c"
// import cDefault from "./c"
// import * as d from "./d"
// import /*FIND ALL REFS*/[|dDefault|] from "./d"
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/foo.ts",
"kind": "alias",
"name": "import dDefault",
"textSpan": {
"start": 201,
"length": 8
},
"displayParts": [
{
"text": "import",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "dDefault",
"kind": "aliasName"
}
],
"contextSpan": {
"start": 194,
"length": 26
}
},
"references": [
{
"textSpan": {
"start": 201,
"length": 8
},
"fileName": "/foo.ts",
"contextSpan": {
"start": 194,
"length": 26
},
"isWriteAccess": true,
"isDefinition": true
}
]
}
]
@@ -0,0 +1,36 @@
/// <reference path="fourslash.ts" />
// @filename: /tsconfig.json
////{
//// "compilerOptions": {
//// "target": "esnext",
//// "strict": true,
//// "outDir": "./out",
//// "allowSyntheticDefaultImports": true
//// }
////}
// @filename: /a.js
////module.exports = [];
// @filename: /b.js
////module.exports = 1;
// @filename: /c.ts
////export = [];
// @filename: /d.ts
////export = 1;
// @filename: /foo.ts
////import * as /*0*/a from "./a.js"
////import /*1*/aDefault from "./a.js"
////import * as /*2*/b from "./b.js"
////import /*3*/bDefault from "./b.js"
////
////import * as /*4*/c from "./c"
////import /*5*/cDefault from "./c"
////import * as /*6*/d from "./d"
////import /*7*/dDefault from "./d"
verify.baselineFindAllReferences("0", "1", "2", "3", "4", "5", "6", "7");