Skip to content

Commit dd18dc1

Browse files
authored
If outDir is not specified, dont need to include json files explicitly in the config since they will not be emitted (#55389)
1 parent eb374c2 commit dd18dc1

File tree

39 files changed

+1850
-830
lines changed

39 files changed

+1850
-830
lines changed

src/compiler/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8085,6 +8085,9 @@ export interface SourceFileMayBeEmittedHost {
80858085
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
80868086
getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
80878087
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
8088+
getCurrentDirectory(): string;
8089+
getCanonicalFileName: GetCanonicalFileName;
8090+
useCaseSensitiveFileNames(): boolean;
80888091
}
80898092

80908093
/** @internal */

src/compiler/utilities.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import {
6262
CommentDirectivesMap,
6363
CommentDirectiveType,
6464
CommentRange,
65+
comparePaths,
6566
compareStringsCaseSensitive,
6667
compareValues,
6768
Comparison,
@@ -162,6 +163,7 @@ import {
162163
GetCanonicalFileName,
163164
getCombinedModifierFlags,
164165
getCombinedNodeFlags,
166+
getCommonSourceDirectory,
165167
getContainerFlags,
166168
getDirectoryPath,
167169
getJSDocAugmentsTag,
@@ -6368,13 +6370,31 @@ export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFi
63686370
*/
63696371
export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileMayBeEmittedHost, forceDtsEmit?: boolean) {
63706372
const options = host.getCompilerOptions();
6371-
return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) &&
6372-
!sourceFile.isDeclarationFile &&
6373-
!host.isSourceFileFromExternalLibrary(sourceFile) &&
6374-
(forceDtsEmit || (
6375-
!(isJsonSourceFile(sourceFile) && host.getResolvedProjectReferenceToRedirect(sourceFile.fileName)) &&
6376-
!host.isSourceOfProjectReferenceRedirect(sourceFile.fileName)
6377-
));
6373+
// Js files are emitted only if option is enabled
6374+
if (options.noEmitForJsFiles && isSourceFileJS(sourceFile)) return false;
6375+
// Declaration files are not emitted
6376+
if (sourceFile.isDeclarationFile) return false;
6377+
// Source file from node_modules are not emitted
6378+
if (host.isSourceFileFromExternalLibrary(sourceFile)) return false;
6379+
// forcing dts emit => file needs to be emitted
6380+
if (forceDtsEmit) return true;
6381+
// Check other conditions for file emit
6382+
// Source files from referenced projects are not emitted
6383+
if (host.isSourceOfProjectReferenceRedirect(sourceFile.fileName)) return false;
6384+
// Any non json file should be emitted
6385+
if (!isJsonSourceFile(sourceFile)) return true;
6386+
if (host.getResolvedProjectReferenceToRedirect(sourceFile.fileName)) return false;
6387+
// Emit json file if outFile is specified
6388+
if (outFile(options)) return true;
6389+
// Json file is not emitted if outDir is not specified
6390+
if (!options.outDir) return false;
6391+
// Otherwise if rootDir or composite config file, we know common sourceDir and can check if file would be emitted in same location
6392+
if (options.rootDir || (options.composite && options.configFilePath)) {
6393+
const commonDir = getNormalizedAbsolutePath(getCommonSourceDirectory(options, () => [], host.getCurrentDirectory(), host.getCanonicalFileName), host.getCurrentDirectory());
6394+
const outputPath = getSourceFilePathInNewDirWorker(sourceFile.fileName, options.outDir, host.getCurrentDirectory(), commonDir, host.getCanonicalFileName);
6395+
if (comparePaths(sourceFile.fileName, outputPath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo) return false;
6396+
}
6397+
return true;
63786398
}
63796399

63806400
/** @internal */

src/harness/fakesHosts.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ export class System implements ts.System {
153153
}
154154

155155
public setModifiedTime(path: string, time: Date) {
156-
this.vfs.utimesSync(path, time, time);
156+
try {
157+
this.vfs.utimesSync(path, time, time);
158+
}
159+
catch { /* ignored */ }
157160
}
158161

159162
public createHash(data: string): string {

src/testRunner/unittests/tsbuild/resolveJsonModule.ts

Lines changed: 189 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,228 @@
1-
import * as vfs from "../../_namespaces/vfs";
1+
import {
2+
CompilerOptions,
3+
} from "../../_namespaces/ts";
4+
import {
5+
dedent,
6+
} from "../../_namespaces/Utils";
27
import {
38
noChangeOnlyRuns,
49
verifyTsc,
10+
VerifyTscWithEditsInput,
511
} from "../helpers/tsc";
612
import {
7-
loadProjectFromDisk,
13+
loadProjectFromFiles,
814
replaceText,
915
} from "../helpers/vfs";
1016

1117
describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => {
12-
let projFs: vfs.FileSystem;
13-
before(() => {
14-
projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite");
15-
});
18+
function getProjFs(tsconfigFiles: object, additionalCompilerOptions?: CompilerOptions) {
19+
return loadProjectFromFiles({
20+
"/src/src/hello.json": JSON.stringify(
21+
{
22+
hello: "world",
23+
},
24+
undefined,
25+
" ",
26+
),
27+
"/src/src/index.ts": dedent`
28+
import hello from "./hello.json"
29+
export default hello.hello
30+
`,
31+
"/src/tsconfig.json": JSON.stringify(
32+
{
33+
compilerOptions: {
34+
composite: true,
35+
moduleResolution: "node",
36+
module: "commonjs",
37+
resolveJsonModule: true,
38+
esModuleInterop: true,
39+
allowSyntheticDefaultImports: true,
40+
outDir: "dist",
41+
skipDefaultLibCheck: true,
42+
...additionalCompilerOptions,
43+
},
44+
...tsconfigFiles,
45+
},
46+
undefined,
47+
" ",
48+
),
49+
});
50+
}
51+
52+
function verfiyJson(
53+
input: Pick<VerifyTscWithEditsInput, "subScenario" | "modifyFs" | "edits"> | string,
54+
tsconfigFiles: object,
55+
additionalCompilerOptions?: CompilerOptions,
56+
) {
57+
if (typeof input === "string") input = { subScenario: input };
58+
verifyTsc({
59+
scenario: "resolveJsonModule",
60+
fs: () => getProjFs(tsconfigFiles, additionalCompilerOptions),
61+
commandLineArgs: ["--b", "/src/tsconfig.json", "--v", "--explainFiles", "--listEmittedFiles"],
62+
...input,
63+
});
64+
verifyTsc({
65+
scenario: "resolveJsonModule",
66+
fs: () => getProjFs(tsconfigFiles, { composite: undefined, ...additionalCompilerOptions }),
67+
commandLineArgs: ["--b", "/src/tsconfig.json", "--v", "--explainFiles", "--listEmittedFiles"],
68+
...input,
69+
subScenario: `${input.subScenario} non-composite`,
70+
});
71+
}
1672

17-
after(() => {
18-
projFs = undefined!; // Release the contents
73+
verfiyJson("include only", {
74+
include: [
75+
"src/**/*",
76+
],
1977
});
2078

21-
verifyTsc({
22-
scenario: "resolveJsonModule",
23-
subScenario: "include only",
24-
fs: () => projFs,
25-
commandLineArgs: ["--b", "/src/tsconfig_withInclude.json", "--v", "--explainFiles"],
79+
verfiyJson("include only without outDir", {
80+
include: [
81+
"src/**/*",
82+
],
83+
}, { outDir: undefined });
84+
85+
verfiyJson({
86+
subScenario: "include only with json not in rootDir",
87+
modifyFs: fs => {
88+
fs.renameSync("/src/src/hello.json", "/src/hello.json");
89+
replaceText(fs, "/src/src/index.ts", "./hello.json", "../hello.json");
90+
},
91+
}, {
92+
include: [
93+
"src/**/*",
94+
],
95+
}, { rootDir: "src" });
96+
97+
verfiyJson({
98+
subScenario: "include only with json without rootDir but outside configDirectory",
99+
modifyFs: fs => {
100+
fs.renameSync("/src/src/hello.json", "/hello.json");
101+
replaceText(fs, "/src/src/index.ts", "./hello.json", "../../hello.json");
102+
},
103+
}, {
104+
include: [
105+
"src/**/*",
106+
],
26107
});
27108

28-
verifyTsc({
29-
scenario: "resolveJsonModule",
30-
subScenario: "include of json along with other include",
31-
fs: () => projFs,
32-
commandLineArgs: ["--b", "/src/tsconfig_withIncludeOfJson.json", "--v", "--explainFiles"],
109+
verfiyJson("include of json along with other include", {
110+
include: [
111+
"src/**/*",
112+
"src/**/*.json",
113+
],
33114
});
34115

35-
verifyTsc({
36-
scenario: "resolveJsonModule",
116+
verfiyJson({
37117
subScenario: "include of json along with other include and file name matches ts file",
38-
fs: () => projFs,
39-
commandLineArgs: ["--b", "/src/tsconfig_withIncludeOfJson.json", "--v", "--explainFiles"],
40118
modifyFs: fs => {
41-
fs.rimrafSync("/src/src/hello.json");
42-
fs.writeFileSync("/src/src/index.json", JSON.stringify({ hello: "world" }));
43-
fs.writeFileSync(
44-
"/src/src/index.ts",
45-
`import hello from "./index.json"
46-
47-
export default hello.hello`,
48-
);
119+
fs.renameSync("/src/src/hello.json", "/src/src/index.json");
120+
replaceText(fs, "/src/src/index.ts", "hello.json", "index.json");
49121
},
122+
}, {
123+
include: [
124+
"src/**/*",
125+
"src/**/*.json",
126+
],
50127
});
51128

52-
verifyTsc({
53-
scenario: "resolveJsonModule",
54-
subScenario: "files containing json file",
55-
fs: () => projFs,
56-
commandLineArgs: ["--b", "/src/tsconfig_withFiles.json", "--v", "--explainFiles"],
129+
verfiyJson("files containing json file", {
130+
files: [
131+
"src/index.ts",
132+
"src/hello.json",
133+
],
57134
});
58135

59-
verifyTsc({
60-
scenario: "resolveJsonModule",
61-
subScenario: "include and files",
62-
fs: () => projFs,
63-
commandLineArgs: ["--b", "/src/tsconfig_withIncludeAndFiles.json", "--v", "--explainFiles"],
136+
verfiyJson("include and files", {
137+
files: [
138+
"src/hello.json",
139+
],
140+
include: [
141+
"src/**/*",
142+
],
64143
});
65144

66-
verifyTsc({
67-
scenario: "resolveJsonModule",
145+
verfiyJson({
68146
subScenario: "sourcemap",
69-
fs: () => projFs,
70-
commandLineArgs: ["--b", "src/tsconfig_withFiles.json", "--verbose", "--explainFiles"],
71-
modifyFs: fs => replaceText(fs, "src/tsconfig_withFiles.json", `"composite": true,`, `"composite": true, "sourceMap": true,`),
72147
edits: noChangeOnlyRuns,
73-
});
148+
}, {
149+
files: [
150+
"src/index.ts",
151+
"src/hello.json",
152+
],
153+
}, { sourceMap: true });
74154

75-
verifyTsc({
76-
scenario: "resolveJsonModule",
155+
verfiyJson({
77156
subScenario: "without outDir",
78-
fs: () => projFs,
79-
commandLineArgs: ["--b", "src/tsconfig_withFiles.json", "--verbose"],
80-
modifyFs: fs => replaceText(fs, "src/tsconfig_withFiles.json", `"outDir": "dist",`, ""),
81157
edits: noChangeOnlyRuns,
82-
});
158+
}, {
159+
files: [
160+
"src/index.ts",
161+
"src/hello.json",
162+
],
163+
}, { outDir: undefined });
83164
});
84165

85166
describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => {
86167
verifyTsc({
87168
scenario: "resolveJsonModule",
88169
subScenario: "importing json module from project reference",
89-
fs: () => loadProjectFromDisk("tests/projects/importJsonFromProjectReference"),
170+
fs: () =>
171+
loadProjectFromFiles({
172+
"/src/strings/foo.json": JSON.stringify(
173+
{
174+
foo: "bar baz",
175+
},
176+
undefined,
177+
" ",
178+
),
179+
"/src/strings/tsconfig.json": JSON.stringify(
180+
{
181+
extends: "../tsconfig.json",
182+
include: ["foo.json"],
183+
references: [],
184+
},
185+
undefined,
186+
" ",
187+
),
188+
"/src/main/index.ts": dedent`
189+
import { foo } from '../strings/foo.json';
190+
console.log(foo);
191+
`,
192+
"/src/main/tsconfig.json": JSON.stringify(
193+
{
194+
extends: "../tsconfig.json",
195+
include: [
196+
"./**/*.ts",
197+
],
198+
references: [{
199+
path: "../strings/tsconfig.json",
200+
}],
201+
},
202+
undefined,
203+
" ",
204+
),
205+
"/src/tsconfig.json": JSON.stringify(
206+
{
207+
compilerOptions: {
208+
target: "es5",
209+
module: "commonjs",
210+
rootDir: "./",
211+
composite: true,
212+
resolveJsonModule: true,
213+
strict: true,
214+
esModuleInterop: true,
215+
},
216+
references: [
217+
{ path: "./strings/tsconfig.json" },
218+
{ path: "./main/tsconfig.json" },
219+
],
220+
files: [],
221+
},
222+
undefined,
223+
" ",
224+
),
225+
}),
90226
commandLineArgs: ["--b", "src/tsconfig.json", "--verbose", "--explainFiles"],
91227
edits: noChangeOnlyRuns,
92228
});

src/testRunner/unittests/tsserver/projectErrors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ console.log(blabla);`,
710710
compilerOptions: {
711711
resolveJsonModule: true,
712712
composite: true,
713+
outDir: "dist",
713714
},
714715
include,
715716
}),

0 commit comments

Comments
 (0)