From 8794318ac96856933f1b0886900409813875283f Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 16 Jul 2024 13:56:53 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#59215=20(Fix=20code?= =?UTF-8?q?fix=20crash=20on=20circular=20alias...)=20into=20release-5.5=20?= =?UTF-8?q?(#59224)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andrew Branch --- src/services/exportInfoMap.ts | 2 + ...importFixes_ambientCircularDefaultCrash.js | 321 ++++++++++++++++++ ...importFixes_ambientCircularDefaultCrash.ts | 19 ++ 3 files changed, 342 insertions(+) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/importFixes_ambientCircularDefaultCrash.js create mode 100644 tests/cases/fourslash/server/importFixes_ambientCircularDefaultCrash.ts diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 24d0c7b9b8000..2de4f7d363b12 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -566,6 +566,7 @@ function isImportableSymbol(symbol: Symbol, checker: TypeChecker) { export function forEachNameOfDefaultExport(defaultExport: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions, preferCapitalizedNames: boolean, cb: (name: string) => T | undefined): T | undefined { let chain: Symbol[] | undefined; let current: Symbol | undefined = defaultExport; + const seen = new Map(); while (current) { // The predecessor to this function also looked for a name on the `localSymbol` @@ -583,6 +584,7 @@ export function forEachNameOfDefaultExport(defaultExport: Symbol, checker: Ty } chain = append(chain, current); + if (!addToSeen(seen, current)) break; current = current.flags & SymbolFlags.Alias ? checker.getImmediateAliasedSymbol(current) : undefined; } diff --git a/tests/baselines/reference/tsserver/fourslashServer/importFixes_ambientCircularDefaultCrash.js b/tests/baselines/reference/tsserver/fourslashServer/importFixes_ambientCircularDefaultCrash.js new file mode 100644 index 0000000000000..0f838a8407bbb --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/importFixes_ambientCircularDefaultCrash.js @@ -0,0 +1,321 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/index.ts] +my + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "preserve" + } +} + +//// [/types.d.ts] +declare module "mymod" { + import mymod from "mymod"; + export default mymod; +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tsconfig.json ProjectRootPath: undefined:: Result: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/index.ts", + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/types.d.ts" + ], + "options": { + "module": 200, + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /index.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /types.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /index.ts Text-1 "my" + /lib.d.ts Text-1 lib.d.ts-Text + /types.d.ts Text-1 "declare module \"mymod\" {\n import mymod from \"mymod\";\n export default mymod;\n}" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + index.ts + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + types.d.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"preserve\"\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/index.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} +/types.d.ts: *new* + {"pollingInterval":500} + +watchedDirectoriesRecursive:: +: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + noOpenRef: true + +ScriptInfos:: +/index.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 2 + /tsconfig.json + /dev/null/inferredProject1* +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 2 + /tsconfig.json + /dev/null/inferredProject1* +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 2 + /tsconfig.json + /dev/null/inferredProject1* +/tsconfig.json (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* +/types.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/index.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/index.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'my'.", + "start": 0, + "length": 2, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 3 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/index.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/index.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 3, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [] + } \ No newline at end of file diff --git a/tests/cases/fourslash/server/importFixes_ambientCircularDefaultCrash.ts b/tests/cases/fourslash/server/importFixes_ambientCircularDefaultCrash.ts new file mode 100644 index 0000000000000..31b65f11e9724 --- /dev/null +++ b/tests/cases/fourslash/server/importFixes_ambientCircularDefaultCrash.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "preserve" +//// } +//// } + +// @Filename: /types.d.ts +//// declare module "mymod" { +//// import mymod from "mymod"; +//// export default mymod; +//// } + +// @Filename: /index.ts +//// my/**/ + +verify.importFixModuleSpecifiers("", []);