From a6f7ec3464eda6db7eec9bf8a23216259cbb4c70 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 14 Mar 2019 09:21:20 -0700 Subject: [PATCH 1/3] Handle outDir and declrationDir correctly to generate output file names for the tsbuild --- src/compiler/emitter.ts | 23 ++++- .../unittests/tsbuild/resolveJsonModule.ts | 85 +++++++++++++++++-- .../main/index.ts | 3 + .../main/tsconfig.json | 11 +++ .../strings/foo.json | 3 + .../strings/tsconfig.json | 8 ++ .../tsconfig.json | 19 +++++ 7 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 tests/projects/importJsonFromProjectReference/main/index.ts create mode 100644 tests/projects/importJsonFromProjectReference/main/tsconfig.json create mode 100644 tests/projects/importJsonFromProjectReference/strings/foo.json create mode 100644 tests/projects/importJsonFromProjectReference/strings/tsconfig.json create mode 100644 tests/projects/importJsonFromProjectReference/tsconfig.json diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1b2c52afd9..395f6cfdc9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -138,14 +138,27 @@ namespace ts { /* @internal */ export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) { Debug.assert(!fileExtensionIs(inputFileName, Extension.Dts) && hasTSFileExtension(inputFileName)); - const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); - const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath); + let outputPath: string; + const declarationDir = configFile.options.declarationDir || configFile.options.outDir; + if (declarationDir) { + const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); + outputPath = resolvePath(declarationDir, relativePath); + } + else { + outputPath = inputFileName; + } return changeExtension(outputPath, Extension.Dts); } function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) { - const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); - const outputPath = resolvePath(configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath); + let outputPath: string; + if (configFile.options.outDir) { + const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); + outputPath = resolvePath(configFile.options.outDir, relativePath); + } + else { + outputPath = inputFileName; + } const isJsonFile = fileExtensionIs(inputFileName, Extension.Json); const outputFileName = changeExtension(outputPath, isJsonFile ? Extension.Json : @@ -203,6 +216,8 @@ namespace ts { const jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase); if (jsFilePath) return jsFilePath; } + const buildInfoPath = getOutputPathForBuildInfo(configFile.options); + if (buildInfoPath) return buildInfoPath; return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`); } diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index 514defb358..44c6da45e0 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -1,5 +1,5 @@ namespace ts { - describe("unittests:: tsbuild:: with resolveJsonModule option", () => { + describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => { let projFs: vfs.FileSystem; const allExpectedOutputs = ["/src/dist/src/index.js", "/src/dist/src/index.d.ts", "/src/dist/src/hello.json"]; before(() => { @@ -63,19 +63,92 @@ export default hello.hello`); const configFile = "src/tsconfig_withFiles.json"; replaceText(fs, configFile, `"composite": true,`, `"composite": true, "sourceMap": true,`); const host = new fakes.SolutionBuilderHost(fs); - const builder = createSolutionBuilder(host, [configFile], { verbose: false }); + const builder = createSolutionBuilder(host, [configFile], { verbose: true }); builder.buildAllProjects(); - host.assertDiagnosticMessages(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild(configFile), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/dist/src/index.js"], + [Diagnostics.Building_project_0, `/${configFile}`] + ); for (const output of [...allExpectedOutputs, "/src/dist/src/index.js.map"]) { assert(fs.existsSync(output), `Expect file ${output} to exist`); } - - const newBuilder = createSolutionBuilder(host, [configFile], { verbose: true }); - newBuilder.buildAllProjects(); + host.clearDiagnostics(); + builder.resetBuildContext(); + builder.buildAllProjects(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(configFile), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/dist/src/index.js"] ); }); + + it("with resolveJsonModule and without outDir", () => { + const fs = projFs.shadow(); + const configFile = "src/tsconfig_withFiles.json"; + replaceText(fs, configFile, `"outDir": "dist",`, ""); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, [configFile], { verbose: true }); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild(configFile), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/src/index.js"], + [Diagnostics.Building_project_0, `/${configFile}`] + ); + for (const output of ["/src/src/index.js", "/src/src/index.d.ts"]) { + assert(fs.existsSync(output), `Expect file ${output} to exist`); + } + host.clearDiagnostics(); + builder.resetBuildContext(); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild(configFile), + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/src/index.js"] + ); + }); + }); + + describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => { + let projFs: vfs.FileSystem; + before(() => { + projFs = loadProjectFromDisk("tests/projects/importJsonFromProjectReference"); + }); + + after(() => { + projFs = undefined!; // Release the contents + }); + + it("when importing json module from project reference", () => { + const expectedOutput = "/src/main/index.js"; + const fs = projFs.shadow(); + const configFile = "src/tsconfig.json"; + const stringsConfigFile = "src/strings/tsconfig.json"; + const mainConfigFile = "src/main/tsconfig.json"; + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, [configFile], { verbose: true }); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, stringsConfigFile, "src/strings/tsconfig.tsbuildinfo"], + [Diagnostics.Building_project_0, `/${stringsConfigFile}`], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"], + [Diagnostics.Building_project_0, `/${mainConfigFile}`], + [Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"], + [Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile], + [Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`] + ); + assert.isFalse(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to not exist because of errors`); + host.clearDiagnostics(); + builder.resetBuildContext(); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile), + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"], + [Diagnostics.Building_project_0, `/${mainConfigFile}`], + [Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"], + [Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile], + [Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`] + ); + }); }); } diff --git a/tests/projects/importJsonFromProjectReference/main/index.ts b/tests/projects/importJsonFromProjectReference/main/index.ts new file mode 100644 index 0000000000..96fe3ccef3 --- /dev/null +++ b/tests/projects/importJsonFromProjectReference/main/index.ts @@ -0,0 +1,3 @@ +import { foo } from '../strings/foo.json'; + +console.log(foo); \ No newline at end of file diff --git a/tests/projects/importJsonFromProjectReference/main/tsconfig.json b/tests/projects/importJsonFromProjectReference/main/tsconfig.json new file mode 100644 index 0000000000..22911a0231 --- /dev/null +++ b/tests/projects/importJsonFromProjectReference/main/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "./**/*.ts" + ], + "references": [ + { + "path": "../strings/tsconfig.json" + } + ] +} \ No newline at end of file diff --git a/tests/projects/importJsonFromProjectReference/strings/foo.json b/tests/projects/importJsonFromProjectReference/strings/foo.json new file mode 100644 index 0000000000..90505326a2 --- /dev/null +++ b/tests/projects/importJsonFromProjectReference/strings/foo.json @@ -0,0 +1,3 @@ +{ + "foo": "bar baz" +} \ No newline at end of file diff --git a/tests/projects/importJsonFromProjectReference/strings/tsconfig.json b/tests/projects/importJsonFromProjectReference/strings/tsconfig.json new file mode 100644 index 0000000000..321325a02c --- /dev/null +++ b/tests/projects/importJsonFromProjectReference/strings/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "./**/*.ts", + "./**/*.json" + ], + "references": [] +} \ No newline at end of file diff --git a/tests/projects/importJsonFromProjectReference/tsconfig.json b/tests/projects/importJsonFromProjectReference/tsconfig.json new file mode 100644 index 0000000000..9156a2d91d --- /dev/null +++ b/tests/projects/importJsonFromProjectReference/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "rootDir": "./", + "composite": true, + "resolveJsonModule": true, + "strict": true, + "esModuleInterop": true + }, + "references": [ + { + "path": "./strings/tsconfig.json" + }, + { + "path": "./main/tsconfig.json" + } + ] +} From bd229b5ed1f3bade727ce7d508dfc4a1fdc66f54 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 14 Mar 2019 10:58:57 -0700 Subject: [PATCH 2/3] Exclude Json files from Project reference redirects from files to be emitted list Fixes #30382 --- src/compiler/builder.ts | 2 +- src/compiler/core.ts | 3 ++ src/compiler/emitter.ts | 7 ++-- src/compiler/factory.ts | 2 +- src/compiler/program.ts | 20 ++++++----- src/compiler/tsbuild.ts | 11 ++++--- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 12 ++++--- .../unittests/tsbuild/resolveJsonModule.ts | 11 ++----- src/testRunner/unittests/tsserver/helpers.ts | 2 +- .../unittests/tsserver/projectErrors.ts | 2 +- src/testRunner/unittests/tsserver/session.ts | 2 +- .../strings/tsconfig.json | 5 +-- .../tsconfig.json | 33 ++++++++++--------- 14 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index a97e07b132..faf5156824 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -980,7 +980,7 @@ namespace ts { backupState: noop, restoreState: noop, getProgram: notImplemented, - getProgramOrUndefined: () => undefined, + getProgramOrUndefined: returnUndefined, releaseProgram: noop, getCompilerOptions: () => state.compilerOptions, getSourceFile: notImplemented, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 0bf648ffb1..ec5eafd6ca 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1614,6 +1614,9 @@ namespace ts { /** Do nothing and return true */ export function returnTrue(): true { return true; } + /** Do nothing and return undefined */ + export function returnUndefined(): undefined { return undefined; } + /** Returns its argument. */ export function identity(x: T) { return x; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 395f6cfdc9..bf69228152 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -680,11 +680,12 @@ namespace ts { getCompilerOptions: () => config.options, getCurrentDirectory: () => host.getCurrentDirectory(), getNewLine: () => host.getNewLine(), - getSourceFile: () => undefined, - getSourceFileByPath: () => undefined, + getSourceFile: returnUndefined, + getSourceFileByPath: returnUndefined, getSourceFiles: () => sourceFilesForJsEmit, getLibFileFromReference: notImplemented, isSourceFileFromExternalLibrary: returnFalse, + getResolvedProjectReferenceToRedirect: returnUndefined, writeFile: (name, text, writeByteOrderMark) => { switch (name) { case jsFilePath: @@ -721,7 +722,7 @@ namespace ts { fileExists: f => host.fileExists(f), directoryExists: host.directoryExists && (f => host.directoryExists!(f)), useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), - getProgramBuildInfo: () => undefined + getProgramBuildInfo: returnUndefined }; emitFiles(notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, /*emitOnlyDtsFiles*/ false, getTransformers(config.options)); return outputFiles; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 59fd4efb5f..5f4299f1e2 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3405,7 +3405,7 @@ namespace ts { export const nullTransformationContext: TransformationContext = { enableEmitNotification: noop, enableSubstitution: noop, - endLexicalEnvironment: () => undefined, + endLexicalEnvironment: returnUndefined, getCompilerOptions: notImplemented, getEmitHost: notImplemented, getEmitResolver: notImplemented, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e2ba32b9c6..757fd69b3f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -979,7 +979,7 @@ namespace ts { function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { - const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary)); + const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect)); if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) { // If a rootDir is specified use it as the commonSourceDirectory commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory); @@ -1425,6 +1425,7 @@ namespace ts { getSourceFiles: program.getSourceFiles, getLibFileFromReference: program.getLibFileFromReference, isSourceFileFromExternalLibrary, + getResolvedProjectReferenceToRedirect, writeFile: writeFileCallback || ( (fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)), isEmitBlocked, @@ -2740,13 +2741,14 @@ namespace ts { // List of collected files is complete; validate exhautiveness if this is a project with a file list if (options.composite) { - const sourceFiles = files.filter(f => !f.isDeclarationFile); - if (rootNames.length < sourceFiles.length) { - const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase()); - for (const file of sourceFiles.map(f => normalizePath(f.path).toLowerCase())) { - if (normalizedRootNames.indexOf(file) === -1) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file)); - } + const rootPaths = rootNames.map(r => toPath(r)); + for (const file of files) { + // Ignore declaration files + if (file.isDeclarationFile) continue; + // Ignore json file thats from project reference + if (isJsonSourceFile(file) && getResolvedProjectReferenceToRedirect(file.fileName)) continue; + if (rootPaths.indexOf(file.path) === -1) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file.fileName)); } } } @@ -3158,7 +3160,7 @@ namespace ts { readFile: f => directoryStructureHost.readFile(f), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(), getCurrentDirectory: () => host.getCurrentDirectory(), - onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || (() => undefined), + onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || returnUndefined, trace: host.trace ? (s) => host.trace!(s) : undefined }; } diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 3e2c7c0f24..b058720b1d 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -339,7 +339,7 @@ namespace ts { function createSolutionBuilderHostBase(system: System, createProgram: CreateProgram | undefined, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) { const host = createProgramHost(system, createProgram) as SolutionBuilderHostBase; - host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined; + host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : returnUndefined; host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop; host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop; host.reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system); @@ -660,15 +660,16 @@ namespace ts { } } - // Collect the expected outputs of this project - const outputs = getAllProjectOutputs(project, !host.useCaseSensitiveFileNames()); - - if (outputs.length === 0) { + // Container if no files are specified in the project + if (!project.fileNames.length && !canJsonReportNoInutFiles(project.raw)) { return { type: UpToDateStatusType.ContainerOnly }; } + // Collect the expected outputs of this project + const outputs = getAllProjectOutputs(project, !host.useCaseSensitiveFileNames()); + // Now see if all outputs are newer than the newest input let oldestOutputFileName = "(none)"; let oldestOutputFileTime = maximumDate; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e75943a9b9..fbf83e6a20 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5337,6 +5337,7 @@ namespace ts { getCurrentDirectory(): string; isSourceFileFromExternalLibrary(file: SourceFile): boolean; + getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined; getLibFileFromReference(ref: FileReference): SourceFile | undefined; getCommonSourceDirectory(): string; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1c239880dc..f489aceae2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3422,22 +3422,26 @@ namespace ts { export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): ReadonlyArray { const options = host.getCompilerOptions(); const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file); + const getResolvedProjectReferenceToRedirect = (fileName: string) => host.getResolvedProjectReferenceToRedirect(fileName); if (options.outFile || options.out) { const moduleKind = getEmitModuleKind(options); const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified return filter(host.getSourceFiles(), sourceFile => - (moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); + (moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect)); } else { const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; - return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); + return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect)); } } /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */ - export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean) { - return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile); + export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean, getResolvedProjectReferenceToRedirect: (fileName: string) => ResolvedProjectReference | undefined) { + return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) && + !sourceFile.isDeclarationFile && + !isSourceFileFromExternalLibrary(sourceFile) && + !(isJsonSourceFile(sourceFile) && getResolvedProjectReferenceToRedirect(sourceFile.fileName)); } export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string { diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index 44c6da45e0..7c035e503e 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -132,22 +132,15 @@ export default hello.hello`); [Diagnostics.Building_project_0, `/${stringsConfigFile}`], [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"], [Diagnostics.Building_project_0, `/${mainConfigFile}`], - [Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"], - [Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile], - [Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`] ); - assert.isFalse(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to not exist because of errors`); + assert(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to exist`); host.clearDiagnostics(); builder.resetBuildContext(); builder.buildAllProjects(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"], - [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"], - [Diagnostics.Building_project_0, `/${mainConfigFile}`], - [Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"], - [Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile], - [Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`] + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, mainConfigFile, "src/main/index.ts", "src/main/index.js"], ); }); }); diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 3e79451cd1..3cd1d60599 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -64,7 +64,7 @@ namespace ts.projectSystem { msg: noop, startGroup: noop, endGroup: noop, - getLogFileName: () => undefined, + getLogFileName: returnUndefined, }; export function createHasErrorMessageLogger() { diff --git a/src/testRunner/unittests/tsserver/projectErrors.ts b/src/testRunner/unittests/tsserver/projectErrors.ts index 9e24771f3a..41201c3650 100644 --- a/src/testRunner/unittests/tsserver/projectErrors.ts +++ b/src/testRunner/unittests/tsserver/projectErrors.ts @@ -216,7 +216,7 @@ namespace ts.projectSystem { }, startGroup: noop, endGroup: noop, - getLogFileName: () => undefined + getLogFileName: returnUndefined }; return { errorLogger, diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index bf21228405..715c0ab332 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -8,7 +8,7 @@ namespace ts.server { newLine: "\n", useCaseSensitiveFileNames: true, write(s): void { lastWrittenToHost = s; }, - readFile: () => undefined, + readFile: returnUndefined, writeFile: noop, resolvePath(): string { return undefined!; }, // TODO: GH#18217 fileExists: () => false, diff --git a/tests/projects/importJsonFromProjectReference/strings/tsconfig.json b/tests/projects/importJsonFromProjectReference/strings/tsconfig.json index 321325a02c..6d3c89089e 100644 --- a/tests/projects/importJsonFromProjectReference/strings/tsconfig.json +++ b/tests/projects/importJsonFromProjectReference/strings/tsconfig.json @@ -1,8 +1,5 @@ { "extends": "../tsconfig.json", - "include": [ - "./**/*.ts", - "./**/*.json" - ], + "include": [ "foo.json" ], "references": [] } \ No newline at end of file diff --git a/tests/projects/importJsonFromProjectReference/tsconfig.json b/tests/projects/importJsonFromProjectReference/tsconfig.json index 9156a2d91d..ae6564321c 100644 --- a/tests/projects/importJsonFromProjectReference/tsconfig.json +++ b/tests/projects/importJsonFromProjectReference/tsconfig.json @@ -1,19 +1,20 @@ { - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "rootDir": "./", - "composite": true, - "resolveJsonModule": true, - "strict": true, - "esModuleInterop": true - }, - "references": [ - { - "path": "./strings/tsconfig.json" + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "rootDir": "./", + "composite": true, + "resolveJsonModule": true, + "strict": true, + "esModuleInterop": true }, - { - "path": "./main/tsconfig.json" - } - ] + "references": [ + { + "path": "./strings/tsconfig.json" + }, + { + "path": "./main/tsconfig.json" + } + ], + "files": [] } From 03aee9278274ac3ae43d402dc4809d7daf094c6b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 14 Mar 2019 14:15:06 -0700 Subject: [PATCH 3/3] PR feedback --- src/compiler/emitter.ts | 44 +++++++++++++++++++-------------------- src/compiler/program.ts | 2 +- src/compiler/utilities.ts | 7 ++++++- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index bf69228152..be867db68f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -135,36 +135,34 @@ namespace ts { return configFile.options.rootDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)); } + function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined) { + return outputDir ? + resolvePath( + outputDir, + getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase) + ) : + inputFileName; + } + /* @internal */ export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) { Debug.assert(!fileExtensionIs(inputFileName, Extension.Dts) && hasTSFileExtension(inputFileName)); - let outputPath: string; - const declarationDir = configFile.options.declarationDir || configFile.options.outDir; - if (declarationDir) { - const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); - outputPath = resolvePath(declarationDir, relativePath); - } - else { - outputPath = inputFileName; - } - return changeExtension(outputPath, Extension.Dts); + return changeExtension( + getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir), + Extension.Dts + ); } function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) { - let outputPath: string; - if (configFile.options.outDir) { - const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase); - outputPath = resolvePath(configFile.options.outDir, relativePath); - } - else { - outputPath = inputFileName; - } const isJsonFile = fileExtensionIs(inputFileName, Extension.Json); - const outputFileName = changeExtension(outputPath, isJsonFile ? - Extension.Json : - fileExtensionIs(inputFileName, Extension.Tsx) && configFile.options.jsx === JsxEmit.Preserve ? - Extension.Jsx : - Extension.Js); + const outputFileName = changeExtension( + getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir), + isJsonFile ? + Extension.Json : + fileExtensionIs(inputFileName, Extension.Tsx) && configFile.options.jsx === JsxEmit.Preserve ? + Extension.Jsx : + Extension.Js + ); return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.assertDefined(configFile.options.configFilePath), ignoreCase) !== Comparison.EqualTo ? outputFileName : undefined; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 757fd69b3f..979423cdfa 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2741,7 +2741,7 @@ namespace ts { // List of collected files is complete; validate exhautiveness if this is a project with a file list if (options.composite) { - const rootPaths = rootNames.map(r => toPath(r)); + const rootPaths = rootNames.map(toPath); for (const file of files) { // Ignore declaration files if (file.isDeclarationFile) continue; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f489aceae2..73e32241f8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3437,7 +3437,12 @@ namespace ts { } /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */ - export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean, getResolvedProjectReferenceToRedirect: (fileName: string) => ResolvedProjectReference | undefined) { + export function sourceFileMayBeEmitted( + sourceFile: SourceFile, + options: CompilerOptions, + isSourceFileFromExternalLibrary: (file: SourceFile) => boolean, + getResolvedProjectReferenceToRedirect: (fileName: string) => ResolvedProjectReference | undefined + ) { return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile) &&