diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d7d60fd2304..a9f40ab053c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -641,9 +641,10 @@ namespace ts { */ export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine { const errors: Diagnostic[] = []; - const optionsFromJsonConfigFile = convertOptionsFromJson(optionDeclarations, json["compilerOptions"], basePath, configFileName, errors); - const options = extend(existingOptions, optionsFromJsonConfigFile); - const typingOptions = convertOptionsFromJson(typingOptionDeclarations, json["typingOptions"], basePath, configFileName, errors); + const compilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], basePath, configFileName, errors); + const options = extend(existingOptions, compilerOptions); + const typingOptions: TypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], basePath, configFileName, errors); + const fileNames = getFileNames(errors); return { @@ -717,11 +718,30 @@ namespace ts { } /* @internal */ - export function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, configFileName: string, errors: Diagnostic[]): T { - const options = {} as T; + export function convertCompilerOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, + configFileName: string, errors: Diagnostic[]): CompilerOptions { + + const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {}; + convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, configFileName, options, Diagnostics.Unknown_compiler_option_0, errors); + return options; + } + + /* @internal */ + export function convertTypingOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, + configFileName: string, errors: Diagnostic[]): TypingOptions { + + const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json" + ? { enableAutoDiscovery: true, include: [], exclude: [] } + : { enableAutoDiscovery: false, include: [], exclude: [] }; + convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, configFileName, options, Diagnostics.Unknown_typing_option_0, errors); + return options; + } + + function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, + configFileName: string, defaultOptions: T, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) { if (!jsonOptions) { - return options; + return ; } const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name); @@ -729,14 +749,12 @@ namespace ts { for (const id in jsonOptions) { if (hasProperty(optionNameMap, id)) { const opt = optionNameMap[id]; - options[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); + defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); } else { - errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, id)); + errors.push(createCompilerDiagnostic(diagnosticMessage, id)); } } - - return options; } function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): number | string | number[] | string[] { diff --git a/tests/cases/unittests/convertCompilerOptionsFromJson.ts b/tests/cases/unittests/convertCompilerOptionsFromJson.ts index bd572757631..14674e18e3f 100644 --- a/tests/cases/unittests/convertCompilerOptionsFromJson.ts +++ b/tests/cases/unittests/convertCompilerOptionsFromJson.ts @@ -3,9 +3,9 @@ namespace ts { describe('convertCompilerOptionsFromJson', () => { - function assertCompilerOptions(json: any, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) { + function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) { const actualErrors: Diagnostic[] = []; - const actualCompilerOptions = convertOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", "tsconfig.json", actualErrors); + const actualCompilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", configFileName, actualErrors); const parsedCompilerOptions = JSON.stringify(actualCompilerOptions); const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions); @@ -21,58 +21,236 @@ namespace ts { } } - const correctFormatOptions = { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", "es6.array", "es6.symbol"] - } - } - - const incorrectLibOption = { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", "es6.array", "es8"] - } - } - - it("Convert correctly format JSON to compiler-options ", () => { - assertCompilerOptions(correctFormatOptions, { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] - }, - errors: [] - }); + // tsconfig.json tests + it("Convert correctly format tsconfig.json to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": ["es5", "es6.array", "es6.symbol"] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] + }, + errors: [] + } + ); + }); + + it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "allowJs": false, + "lib": ["es5", "es6.array", "es6.symbol"] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + allowJs: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] + }, + errors: [] + } + ); }); it("Convert incorrectly option of libs to compiler-options ", () => { - debugger; - assertCompilerOptions(incorrectLibOption, { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts"] - }, - errors: [{ - file: undefined, - start: 0, - length: 0, - messageText: "", - code: Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, - category: Diagnostics.Arguments_for_library_option_must_be_Colon_0.category - }] - }); + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": ["es5", "es6.array", "es8"] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts"] + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "", + code: Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + category: Diagnostics.Arguments_for_library_option_must_be_Colon_0.category + }] + } + ); + }); + + it("Convert incorrectly format tsconfig.json to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "modu": "commonjs", + } + }, "tsconfig.json", + { + compilerOptions: {}, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "", + code: Diagnostics.Unknown_compiler_option_0.code, + category: Diagnostics.Unknown_compiler_option_0.category + }] + } + ); + }); + + it("Convert default tsconfig.json to compiler-options ", () => { + assertCompilerOptions({}, "tsconfig.json", + { + compilerOptions: {} as CompilerOptions, + errors: [] + } + ); + }); + + // jsconfig.json + it("Convert correctly format jsconfig.json to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": ["es5", "es6.array", "es6.symbol"] + } + }, "jsconfig.json", + { + compilerOptions: { + allowJs: true, + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] + }, + errors: [] + } + ); + }); + + it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "allowJs": false, + "lib": ["es5", "es6.array", "es6.symbol"] + } + }, "jsconfig.json", + { + compilerOptions: { + allowJs: false, + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] + }, + errors: [] + } + ); + }); + + it("Convert incorrectly option of libs to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": ["es5", "es6.array", "es8"] + } + }, "jsconfig.json", + { + compilerOptions: { + allowJs: true, + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts", "lib.es6.array.d.ts"] + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "", + code: Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + category: Diagnostics.Arguments_for_library_option_must_be_Colon_0.category + }] + } + ); + }); + + it("Convert incorrectly format jsconfig.json to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "modu": "commonjs", + } + }, "jsconfig.json", + { + compilerOptions: + { + allowJs: true + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "", + code: Diagnostics.Unknown_compiler_option_0.code, + category: Diagnostics.Unknown_compiler_option_0.category + }] + } + ); + }); + + it("Convert default jsconfig.json to compiler-options ", () => { + assertCompilerOptions({}, "jsconfig.json", + { + compilerOptions: + { + allowJs: true + }, + errors: [] + } + ); }); }); } diff --git a/tests/cases/unittests/convertTypingOptionsFromJson.ts b/tests/cases/unittests/convertTypingOptionsFromJson.ts index 89a44836e45..898dee0a18b 100644 --- a/tests/cases/unittests/convertTypingOptionsFromJson.ts +++ b/tests/cases/unittests/convertTypingOptionsFromJson.ts @@ -3,13 +3,12 @@ namespace ts { describe('convertTypingOptionsFromJson', () => { - function assertTypingOptions(json: any, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) { + function assertTypingOptions(json: any, configFileName: string, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) { const actualErrors: Diagnostic[] = []; - const actualTypingOptions = convertOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", "tsconfig.json", actualErrors); - + const actualTypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", configFileName, actualErrors); const parsedTypingOptions = JSON.stringify(actualTypingOptions); const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions); - assert.equal(parsedTypingOptions, parsedTypingOptions); + assert.equal(parsedTypingOptions, expectedTypingOptions); const expectedErrors = expectedResult.errors; assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`); @@ -20,25 +19,170 @@ namespace ts { assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`); } } - - const correctFormatOptions = { - "typingOptions": { - "enableAutoDiscovery": true, - "include": ["0.d.ts", "1.d.ts"], - "exclude": ["0.js", "1.js"] - } - } - - it("Convert correctly format JSON to compiler-options ", () => { - debugger; - assertTypingOptions(correctFormatOptions, { - typingOptions: { - enableAutoDiscovery: true, - include: ["/apath/0.d.ts", "/apath/1.d.ts"], - exclude: ["/apath/0.js", "/apath/1.js"] + + // tsconfig.json + it("Convert correctly format tsconfig.json to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovery": true, + "include": ["0.d.ts", "1.d.ts"], + "exclude": ["0.js", "1.js"] + } }, - errors: [] + "tsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: true, + include: ["0.d.ts", "1.d.ts"], + exclude: ["0.js", "1.js"] + }, + errors: [] }); }); + + it("Convert incorrect format tsconfig.json to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovy": true, + } + }, "tsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: false, + include: [], + exclude: [] + }, + errors: [ + { + category: Diagnostics.Unknown_typing_option_0.category, + code: Diagnostics.Unknown_typing_option_0.code, + file: undefined, + start: 0, + length: 0, + messageText: undefined + } + ] + }); + }); + + it("Convert default tsconfig.json to typing-options ", () => { + assertTypingOptions({}, "tsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: false, + include: [], + exclude: [] + }, + errors: [] + }); + }); + + it("Convert tsconfig.json with only enableAutoDiscovery property to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovery": true + } + }, "tsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: true, + include: [], + exclude: [] + }, + errors: [] + }); + }); + + // jsconfig.json + it("Convert jsconfig.json to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovery": false, + "include": ["0.d.ts"], + "exclude": ["0.js"] + } + }, "jsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: false, + include: ["0.d.ts"], + exclude: ["0.js"] + }, + errors: [] + }); + }); + + it("Convert default jsconfig.json to typing-options ", () => { + assertTypingOptions({ }, "jsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: true, + include: [], + exclude: [] + }, + errors: [] + }); + }); + + it("Convert incorrect format jsconfig.json to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovy": true, + } + }, "jsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: true, + include: [], + exclude: [] + }, + errors: [ + { + category: Diagnostics.Unknown_compiler_option_0.category, + code: Diagnostics.Unknown_typing_option_0.code, + file: undefined, + start: 0, + length: 0, + messageText: undefined + } + ] + }); + }); + + it("Convert jsconfig.json with only enableAutoDiscovery property to typing-options ", () => { + assertTypingOptions( + { + "typingOptions": + { + "enableAutoDiscovery": false + } + }, "jsconfig.json", + { + typingOptions: + { + enableAutoDiscovery: false, + include: [], + exclude: [] + }, + errors: [] + }); + }); }); }