diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7269462578..1857fa05f6 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -192,6 +192,11 @@ namespace ts { // Setup and perform the transformation to retrieve declarations from the input files const nonJsFiles = filter(sourceFiles, isSourceFileNotJavaScript); const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles; + if (emitOnlyDtsFiles && !compilerOptions.declaration) { + // Checker wont collect the linked aliases since thats only done when declaration is enabled. + // Do that here when emitting only dts files + nonJsFiles.forEach(collectLinkedAliases); + } const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false); if (length(declarationTransform.diagnostics)) { for (const diagnostic of declarationTransform.diagnostics!) { @@ -221,6 +226,20 @@ namespace ts { declarationTransform.dispose(); } + function collectLinkedAliases(node: Node) { + if (isExportAssignment(node)) { + if (node.expression.kind === SyntaxKind.Identifier) { + resolver.collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true); + } + return; + } + else if (isExportSpecifier(node)) { + resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); + return; + } + forEachChild(node, collectLinkedAliases); + } + function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, bundleInfoPath: string | undefined, printer: Printer, mapRecorder: SourceMapWriter) { const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined; const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b1e52d68bc..65856ca23f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3331,7 +3331,7 @@ namespace ts { getNodeCheckFlags(node: Node): NodeCheckFlags; isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; isLateBound(node: Declaration): node is LateBoundDeclaration; - collectLinkedAliases(node: Identifier): Node[] | undefined; + collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined; isImplementationOfOverload(node: FunctionLike): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 467a347410..6645e12c83 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -571,7 +571,9 @@ interface Array {}` } private addFileOrFolderInFolder(folder: FsFolder, fileOrDirectory: FsFile | FsFolder | FsSymLink, ignoreWatch?: boolean) { - insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path))); + if (!this.fs.has(fileOrDirectory.path)) { + insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path))); + } folder.modifiedTime = this.now(); this.fs.set(fileOrDirectory.path, fileOrDirectory); diff --git a/src/testRunner/unittests/tscWatchMode.ts b/src/testRunner/unittests/tscWatchMode.ts index 2aaef43f2d..ed03c6ad48 100644 --- a/src/testRunner/unittests/tscWatchMode.ts +++ b/src/testRunner/unittests/tscWatchMode.ts @@ -1218,6 +1218,58 @@ namespace ts.tscWatch { checkWatchedFiles(host, files.map(f => f.path)); } }); + + it("updates errors correctly when declaration emit is disabled in compiler options", () => { + const currentDirectory = "/user/username/projects/myproject"; + const aFile: File = { + path: `${currentDirectory}/a.ts`, + content: `import test from './b'; +test(4, 5);` + }; + const bFileContent = `function test(x: number, y: number) { + return x + y / 5; +} +export default test;`; + const bFile: File = { + path: `${currentDirectory}/b.ts`, + content: bFileContent + }; + const tsconfigFile: File = { + path: `${currentDirectory}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { + module: "commonjs", + noEmit: true, + strict: true, + } + }) + }; + const files = [aFile, bFile, libFile, tsconfigFile]; + const host = createWatchedSystem(files, { currentDirectory }); + const watch = createWatchOfConfigFile("tsconfig.json", host); + checkOutputErrorsInitial(host, emptyArray); + + changeParameterType("x", "string", [ + getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("4"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "4", "string") + ]); + changeParameterType("y", "string", [ + getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("5"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "5", "string"), + getDiagnosticOfFileFromProgram(watch(), bFile.path, bFile.content.indexOf("y /"), 1, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type) + ]); + + function changeParameterType(parameterName: string, toType: string, expectedErrors: ReadonlyArray) { + const newContent = bFileContent.replace(new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`); + + verifyErrorsWithBFileContents(newContent, expectedErrors); + verifyErrorsWithBFileContents(bFileContent, emptyArray); + } + + function verifyErrorsWithBFileContents(content: string, expectedErrors: ReadonlyArray) { + host.writeFile(bFile.path, content); + host.runQueuedTimeoutCallbacks(); + checkOutputErrorsIncremental(host, expectedErrors); + } + }); }); describe("tsc-watch emit with outFile or out setting", () => { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 114b2341fa..097a8caec5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2915,7 +2915,7 @@ declare namespace ts { getNodeCheckFlags(node: Node): NodeCheckFlags; isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; isLateBound(node: Declaration): node is LateBoundDeclaration; - collectLinkedAliases(node: Identifier): Node[] | undefined; + collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined; isImplementationOfOverload(node: FunctionLike): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;