From a6f7ec3464eda6db7eec9bf8a23216259cbb4c70 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 14 Mar 2019 09:21:20 -0700 Subject: [PATCH] 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 1b2c52afd9b..395f6cfdc91 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 514defb3583..44c6da45e0b 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 00000000000..96fe3ccef3f --- /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 00000000000..22911a0231a --- /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 00000000000..90505326a2c --- /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 00000000000..321325a02c5 --- /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 00000000000..9156a2d91df --- /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" + } + ] +}