diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7d72d3950e49..c003090aaf45d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -414,7 +414,8 @@ namespace ts { }, getSymbolAtLocation: node => { node = getParseTreeNode(node); - return node ? getSymbolAtLocation(node) : undefined; + // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors + return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined; }, getShorthandAssignmentValueSymbol: node => { node = getParseTreeNode(node); @@ -34412,7 +34413,7 @@ namespace ts { return undefined; } - function getSymbolAtLocation(node: Node): Symbol | undefined { + function getSymbolAtLocation(node: Node, ignoreErrors?: boolean): Symbol | undefined { if (node.kind === SyntaxKind.SourceFile) { return isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined; } @@ -34496,7 +34497,7 @@ namespace ts { ((isInJSFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) || (isLiteralTypeNode(node.parent) && isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent) ) { - return resolveExternalModuleName(node, node); + return resolveExternalModuleName(node, node, ignoreErrors); } if (isCallExpression(parent) && isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) { return getSymbolOfNode(parent); @@ -34518,7 +34519,7 @@ namespace ts { case SyntaxKind.ClassKeyword: return getSymbolOfNode(node.parent); case SyntaxKind.ImportType: - return isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal) : undefined; + return isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal, ignoreErrors) : undefined; case SyntaxKind.ExportKeyword: return isExportAssignment(node.parent) ? Debug.assertDefined(node.parent.symbol) : undefined; diff --git a/src/testRunner/unittests/programApi.ts b/src/testRunner/unittests/programApi.ts index 5f5251afaf253..3b71fea7238c1 100644 --- a/src/testRunner/unittests/programApi.ts +++ b/src/testRunner/unittests/programApi.ts @@ -178,4 +178,19 @@ namespace ts { assert.isNotNaN(program.getIdentifierCount()); }); }); + + describe("unittests:: programApi:: Program.getDiagnosticsProducingTypeChecker / Program.getSemanticDiagnostics", () => { + it("getSymbolAtLocation does not cause additional error to be added on module resolution failure", () => { + const main = new documents.TextDocument("/main.ts", "import \"./module\";"); + const mod = new documents.TextDocument("/module.d.ts", "declare const foo: any;"); + + const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main, mod], cwd: "/" }); + const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + + const sourceFile = program.getSourceFile("main.ts")!; + const typeChecker = program.getDiagnosticsProducingTypeChecker(); + typeChecker.getSymbolAtLocation((sourceFile.statements[0] as ImportDeclaration).moduleSpecifier); + assert.isEmpty(program.getSemanticDiagnostics()); + }); + }); }