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 <andrewbranch@users.noreply.github.com>

* Update src/compiler/commandLineParser.ts

Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>

Co-authored-by: Andrew Branch <andrewbranch@users.noreply.github.com>
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
Orta Therox 2021-09-08 09:17:43 +00:00 committed by GitHub
parent c8ada74862
commit 32168ed653
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 13 deletions

View file

@ -2852,6 +2852,7 @@ namespace ts {
let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined;
let watchOptions: WatchOptions | undefined;
let extendedConfigPath: string | undefined;
let rootCompilerOptions: PropertyName[] | undefined;
const optionsIterator: JsonConversionNotifier = {
onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) {
@ -2894,6 +2895,9 @@ namespace ts {
if (key === "excludes") {
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
}
if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) {
rootCompilerOptions = append(rootCompilerOptions, keyNode);
}
}
};
const json = convertConfigFileToObject(sourceFile, errors, /*reportOptionsErrors*/ true, optionsIterator);
@ -2913,6 +2917,10 @@ namespace ts {
}
}
if (rootCompilerOptions && json && json.compilerOptions === undefined) {
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));
}
return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath };
}

View file

@ -4834,6 +4834,10 @@
"category": "Message",
"code": 6257
},
"'{0}' should be set inside the 'compilerOptions' object of the config json file": {
"category": "Error",
"code": 6258
},
"Enable project compilation": {
"category": "Message",

View file

@ -663,7 +663,36 @@ namespace ts {
});
});
it("Don't crash when root expression is not objecty at all", () => {
it("raises an error if you've set a compiler flag in the root without including 'compilerOptions'", () => {
assertCompilerOptionsWithJsonText(`{
"module": "esnext",
}`, "tsconfig.json", {
compilerOptions: {},
errors: [{
...Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file,
messageText: "'module' should be set inside the 'compilerOptions' object of the config json file.",
file: undefined,
start: 0,
length: 0
}]
});
});
it("does not raise an error if you've set a compiler flag in the root when you have included 'compilerOptions'", () => {
assertCompilerOptionsWithJsonText(`{
"target": "esnext",
"compilerOptions": {
"module": "esnext"
}
}`, "tsconfig.json", {
compilerOptions: {
module: ModuleKind.ESNext
},
errors: []
});
});
it("Don't crash when root expression is not object at all", () => {
assertCompilerOptionsWithJsonText(`42`, "tsconfig.json", {
compilerOptions: {},
errors: [{

View file

@ -718,7 +718,9 @@ export function someFn() { }`),
const alphaExtendedConfigFile: File = {
path: "/a/b/alpha.tsconfig.json",
content: JSON.stringify({
strict: true
compilerOptions: {
strict: true
}
})
};
const project1Config: File = {
@ -734,7 +736,9 @@ export function someFn() { }`),
const bravoExtendedConfigFile: File = {
path: "/a/b/bravo.tsconfig.json",
content: JSON.stringify({
strict: true
compilerOptions: {
strict: true
}
})
};
const otherFile: File = {

View file

@ -16,7 +16,7 @@ interface Array<T> { length: number; [n: number]: T; }
{"references":[{"path":"./project1.tsconfig.json"},{"path":"./project2.tsconfig.json"}],"files":[]}
//// [/a/b/alpha.tsconfig.json]
{"strict":true}
{"compilerOptions":{"strict":true}}
//// [/a/b/project1.tsconfig.json]
{"extends":"./alpha.tsconfig.json","compilerOptions":{"composite":true},"files":["/a/b/commonFile1.ts","/a/b/commonFile2.ts"]}
@ -28,7 +28,7 @@ let x = 1
let y = 1
//// [/a/b/bravo.tsconfig.json]
{"strict":true}
{"compilerOptions":{"strict":true}}
//// [/a/b/project2.tsconfig.json]
{"extends":"./bravo.tsconfig.json","compilerOptions":{"composite":true},"files":["/a/b/other.ts"]}
@ -60,7 +60,7 @@ Output::
Program root files: ["/a/b/commonFile1.ts","/a/b/commonFile2.ts"]
Program options: {"composite":true,"watch":true,"configFilePath":"/a/b/project1.tsconfig.json"}
Program options: {"strict":true,"composite":true,"watch":true,"configFilePath":"/a/b/project1.tsconfig.json"}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
@ -78,7 +78,7 @@ Shape signatures in builder refreshed for::
/a/b/commonfile2.ts (used version)
Program root files: ["/a/b/other.ts"]
Program options: {"composite":true,"watch":true,"configFilePath":"/a/b/project2.tsconfig.json"}
Program options: {"strict":true,"composite":true,"watch":true,"configFilePath":"/a/b/project2.tsconfig.json"}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
@ -117,6 +117,7 @@ FsWatchesRecursive::
exitCode:: ExitStatus.undefined
//// [/a/b/commonFile1.js]
"use strict";
var x = 1;
@ -125,6 +126,7 @@ declare let x: number;
//// [/a/b/commonFile2.js]
"use strict";
var y = 1;
@ -133,7 +135,7 @@ declare let y: number;
//// [/a/b/project1.tsconfig.tsbuildinfo]
{"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"}
{"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"}
//// [/a/b/project1.tsconfig.tsbuildinfo.readable.baseline.txt]
{
@ -161,7 +163,8 @@ declare let y: number;
}
},
"options": {
"composite": true
"composite": true,
"strict": true
},
"referencedMap": {},
"exportedModulesMap": {},
@ -172,10 +175,11 @@ declare let y: number;
]
},
"version": "FakeTSVersion",
"size": 753
"size": 767
}
//// [/a/b/other.js]
"use strict";
var z = 0;
@ -184,7 +188,7 @@ declare let z: number;
//// [/a/b/project2.tsconfig.tsbuildinfo]
{"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"}
{"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"}
//// [/a/b/project2.tsconfig.tsbuildinfo.readable.baseline.txt]
{
@ -206,7 +210,8 @@ declare let z: number;
}
},
"options": {
"composite": true
"composite": true,
"strict": true
},
"referencedMap": {},
"exportedModulesMap": {},
@ -216,7 +221,7 @@ declare let z: number;
]
},
"version": "FakeTSVersion",
"size": 666
"size": 680
}