Skip to content

Commit 32168ed

Browse files
Orta TheroxandrewbranchDanielRosenwasser
authored
Add support for raising if you set a tsconfig entry of target/module with the right setting in the root (#44964)
* Add support for raising if you set a tsconfig entry of target/module with the right setting in the root * Switch to check for any compiler option in the root which doesn't include compilerOptions * Get green * Apply suggestions from code review Co-authored-by: Andrew Branch <[email protected]> * Update src/compiler/commandLineParser.ts Co-authored-by: Daniel Rosenwasser <[email protected]> Co-authored-by: Andrew Branch <[email protected]> Co-authored-by: Daniel Rosenwasser <[email protected]>
1 parent c8ada74 commit 32168ed

File tree

5 files changed

+63
-13
lines changed

5 files changed

+63
-13
lines changed

Diff for: src/compiler/commandLineParser.ts

+8
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,7 @@ namespace ts {
28522852
let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined;
28532853
let watchOptions: WatchOptions | undefined;
28542854
let extendedConfigPath: string | undefined;
2855+
let rootCompilerOptions: PropertyName[] | undefined;
28552856

28562857
const optionsIterator: JsonConversionNotifier = {
28572858
onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) {
@@ -2894,6 +2895,9 @@ namespace ts {
28942895
if (key === "excludes") {
28952896
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
28962897
}
2898+
if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) {
2899+
rootCompilerOptions = append(rootCompilerOptions, keyNode);
2900+
}
28972901
}
28982902
};
28992903
const json = convertConfigFileToObject(sourceFile, errors, /*reportOptionsErrors*/ true, optionsIterator);
@@ -2913,6 +2917,10 @@ namespace ts {
29132917
}
29142918
}
29152919

2920+
if (rootCompilerOptions && json && json.compilerOptions === undefined) {
2921+
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, rootCompilerOptions[0], Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, getTextOfPropertyName(rootCompilerOptions[0]) as string));
2922+
}
2923+
29162924
return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath };
29172925
}
29182926

Diff for: src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -4834,6 +4834,10 @@
48344834
"category": "Message",
48354835
"code": 6257
48364836
},
4837+
"'{0}' should be set inside the 'compilerOptions' object of the config json file": {
4838+
"category": "Error",
4839+
"code": 6258
4840+
},
48374841

48384842
"Enable project compilation": {
48394843
"category": "Message",

Diff for: src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,36 @@ namespace ts {
663663
});
664664
});
665665

666-
it("Don't crash when root expression is not objecty at all", () => {
666+
it("raises an error if you've set a compiler flag in the root without including 'compilerOptions'", () => {
667+
assertCompilerOptionsWithJsonText(`{
668+
"module": "esnext",
669+
}`, "tsconfig.json", {
670+
compilerOptions: {},
671+
errors: [{
672+
...Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file,
673+
messageText: "'module' should be set inside the 'compilerOptions' object of the config json file.",
674+
file: undefined,
675+
start: 0,
676+
length: 0
677+
}]
678+
});
679+
});
680+
681+
it("does not raise an error if you've set a compiler flag in the root when you have included 'compilerOptions'", () => {
682+
assertCompilerOptionsWithJsonText(`{
683+
"target": "esnext",
684+
"compilerOptions": {
685+
"module": "esnext"
686+
}
687+
}`, "tsconfig.json", {
688+
compilerOptions: {
689+
module: ModuleKind.ESNext
690+
},
691+
errors: []
692+
});
693+
});
694+
695+
it("Don't crash when root expression is not object at all", () => {
667696
assertCompilerOptionsWithJsonText(`42`, "tsconfig.json", {
668697
compilerOptions: {},
669698
errors: [{

Diff for: src/testRunner/unittests/tsbuildWatch/programUpdates.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,9 @@ export function someFn() { }`),
718718
const alphaExtendedConfigFile: File = {
719719
path: "/a/b/alpha.tsconfig.json",
720720
content: JSON.stringify({
721-
strict: true
721+
compilerOptions: {
722+
strict: true
723+
}
722724
})
723725
};
724726
const project1Config: File = {
@@ -734,7 +736,9 @@ export function someFn() { }`),
734736
const bravoExtendedConfigFile: File = {
735737
path: "/a/b/bravo.tsconfig.json",
736738
content: JSON.stringify({
737-
strict: true
739+
compilerOptions: {
740+
strict: true
741+
}
738742
})
739743
};
740744
const otherFile: File = {

Diff for: tests/baselines/reference/tsbuild/watchMode/programUpdates/works-correctly-when-project-with-extended-config-is-removed.js

+15-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface Array<T> { length: number; [n: number]: T; }
1616
{"references":[{"path":"./project1.tsconfig.json"},{"path":"./project2.tsconfig.json"}],"files":[]}
1717

1818
//// [/a/b/alpha.tsconfig.json]
19-
{"strict":true}
19+
{"compilerOptions":{"strict":true}}
2020

2121
//// [/a/b/project1.tsconfig.json]
2222
{"extends":"./alpha.tsconfig.json","compilerOptions":{"composite":true},"files":["/a/b/commonFile1.ts","/a/b/commonFile2.ts"]}
@@ -28,7 +28,7 @@ let x = 1
2828
let y = 1
2929

3030
//// [/a/b/bravo.tsconfig.json]
31-
{"strict":true}
31+
{"compilerOptions":{"strict":true}}
3232

3333
//// [/a/b/project2.tsconfig.json]
3434
{"extends":"./bravo.tsconfig.json","compilerOptions":{"composite":true},"files":["/a/b/other.ts"]}
@@ -60,7 +60,7 @@ Output::
6060

6161

6262
Program root files: ["/a/b/commonFile1.ts","/a/b/commonFile2.ts"]
63-
Program options: {"composite":true,"watch":true,"configFilePath":"/a/b/project1.tsconfig.json"}
63+
Program options: {"strict":true,"composite":true,"watch":true,"configFilePath":"/a/b/project1.tsconfig.json"}
6464
Program structureReused: Not
6565
Program files::
6666
/a/lib/lib.d.ts
@@ -78,7 +78,7 @@ Shape signatures in builder refreshed for::
7878
/a/b/commonfile2.ts (used version)
7979

8080
Program root files: ["/a/b/other.ts"]
81-
Program options: {"composite":true,"watch":true,"configFilePath":"/a/b/project2.tsconfig.json"}
81+
Program options: {"strict":true,"composite":true,"watch":true,"configFilePath":"/a/b/project2.tsconfig.json"}
8282
Program structureReused: Not
8383
Program files::
8484
/a/lib/lib.d.ts
@@ -117,6 +117,7 @@ FsWatchesRecursive::
117117
exitCode:: ExitStatus.undefined
118118

119119
//// [/a/b/commonFile1.js]
120+
"use strict";
120121
var x = 1;
121122

122123

@@ -125,6 +126,7 @@ declare let x: number;
125126

126127

127128
//// [/a/b/commonFile2.js]
129+
"use strict";
128130
var y = 1;
129131

130132

@@ -133,7 +135,7 @@ declare let y: number;
133135

134136

135137
//// [/a/b/project1.tsconfig.tsbuildinfo]
136-
{"program":{"fileNames":["../lib/lib.d.ts","./commonfile1.ts","./commonfile2.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"2167136208-let x = 1","affectsGlobalScope":true},{"version":"2168322129-let y = 1","affectsGlobalScope":true}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[2,3,1]},"version":"FakeTSVersion"}
138+
{"program":{"fileNames":["../lib/lib.d.ts","./commonfile1.ts","./commonfile2.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"2167136208-let x = 1","affectsGlobalScope":true},{"version":"2168322129-let y = 1","affectsGlobalScope":true}],"options":{"composite":true,"strict":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[2,3,1]},"version":"FakeTSVersion"}
137139

138140
//// [/a/b/project1.tsconfig.tsbuildinfo.readable.baseline.txt]
139141
{
@@ -161,7 +163,8 @@ declare let y: number;
161163
}
162164
},
163165
"options": {
164-
"composite": true
166+
"composite": true,
167+
"strict": true
165168
},
166169
"referencedMap": {},
167170
"exportedModulesMap": {},
@@ -172,10 +175,11 @@ declare let y: number;
172175
]
173176
},
174177
"version": "FakeTSVersion",
175-
"size": 753
178+
"size": 767
176179
}
177180

178181
//// [/a/b/other.js]
182+
"use strict";
179183
var z = 0;
180184

181185

@@ -184,7 +188,7 @@ declare let z: number;
184188

185189

186190
//// [/a/b/project2.tsconfig.tsbuildinfo]
187-
{"program":{"fileNames":["../lib/lib.d.ts","./other.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"2874288940-let z = 0;","affectsGlobalScope":true}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[2,1]},"version":"FakeTSVersion"}
191+
{"program":{"fileNames":["../lib/lib.d.ts","./other.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"2874288940-let z = 0;","affectsGlobalScope":true}],"options":{"composite":true,"strict":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[2,1]},"version":"FakeTSVersion"}
188192

189193
//// [/a/b/project2.tsconfig.tsbuildinfo.readable.baseline.txt]
190194
{
@@ -206,7 +210,8 @@ declare let z: number;
206210
}
207211
},
208212
"options": {
209-
"composite": true
213+
"composite": true,
214+
"strict": true
210215
},
211216
"referencedMap": {},
212217
"exportedModulesMap": {},
@@ -216,7 +221,7 @@ declare let z: number;
216221
]
217222
},
218223
"version": "FakeTSVersion",
219-
"size": 666
224+
"size": 680
220225
}
221226

222227

0 commit comments

Comments
 (0)