From 3adab0cec3f6139e6513796282d333a1ef312bfe Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 9 Mar 2016 16:35:01 -0800 Subject: [PATCH 01/16] revert --- src/compiler/commandLineParser.ts | 82 +++++++++++++++++-------------- src/compiler/types.ts | 9 +++- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index cf55f030c33..c0912394491 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -267,6 +267,16 @@ namespace ts { description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, }, + { + name: "list", + elementType: { + "node": ModuleResolutionKind.NodeJs, + "classic": ModuleResolutionKind.Classic, + }, + type: "list", + description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, + error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, + }, { name: "allowUnusedLabels", type: "boolean", @@ -391,42 +401,7 @@ namespace ts { } if (hasProperty(optionNameMap, s)) { - const opt = optionNameMap[s]; - - if (opt.isTSConfigOnly) { - errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name)); - } - else { - // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). - if (!args[i] && opt.type !== "boolean") { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name)); - } - - switch (opt.type) { - case "number": - options[opt.name] = parseInt(args[i]); - i++; - break; - case "boolean": - options[opt.name] = true; - break; - case "string": - options[opt.name] = args[i] || ""; - i++; - break; - // If not a primitive, the possible types are specified in what is effectively a map of options. - default: - let map = >opt.type; - let key = (args[i] || "").toLowerCase(); - i++; - if (hasProperty(map, key)) { - options[opt.name] = map[key]; - } - else { - errors.push(createCompilerDiagnostic((opt).error)); - } - } - } + parseString(optionNameMap[s], args[i]); } else { errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, s)); @@ -436,6 +411,41 @@ namespace ts { fileNames.push(s); } } + + function parseString(opt: CommandLineOption, value: string) { + // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). + if (!value && opt.type !== "boolean") { + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name)); + } + + switch (opt.type) { + case "number": + options[opt.name] = parseInt(value); + i++; + break; + case "boolean": + options[opt.name] = true; + break; + case "string": + options[opt.name] = value || ""; + i++; + break; + case "list": + forEach((value || "").split(","), s => parseString(opt.name, opti ); + break; + // If not a primitive, the possible types are specified in what is effectively a map of options. + default: + let map = >opt.type; + let key = (value || "").toLowerCase(); + i++; + if (hasProperty(map, key)) { + options[opt.name] = map[key]; + } + else { + errors.push(createCompilerDiagnostic((opt).error)); + } + } + } } function parseResponseFile(fileName: string) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 155f5c1a77f..6273ea990df 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2529,7 +2529,7 @@ namespace ts { /* @internal */ export interface CommandLineOptionBase { name: string; - type: "string" | "number" | "boolean" | "object" | Map; // a value of a primitive type, or an object literal mapping named values to actual values + type: "string" | "number" | "boolean" | "object" | "list" | Map; // a value of a primitive type, or an object literal mapping named values to actual values isFilePath?: boolean; // True if option value is a path or fileName shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help' description?: DiagnosticMessage; // The message describing what the command line switch does @@ -2554,8 +2554,13 @@ namespace ts { type: "object"; } + export interface CommandlineOptionOfListType extends CommandLineOptionBase { + type: "list", + elementType: Map | "string" | "number"; + } + /* @internal */ - export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption; + export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption | CommandlineOptionOfListType; /* @internal */ export const enum CharacterCodes { From 0735f465f0e30444cda2771db6e3ab063abdd1fa Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 10 Mar 2016 11:14:29 -0800 Subject: [PATCH 02/16] Add support for list types consolidate typings options and commmandline option parsing from json files Fix --- src/compiler/commandLineParser.ts | 271 ++++++++++++++++-------------- src/compiler/types.ts | 13 +- 2 files changed, 149 insertions(+), 135 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c0912394491..36aef619888 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -186,8 +186,8 @@ namespace ts { name: "rootDir", type: "string", isFilePath: true, - description: Diagnostics.Specifies_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, paramType: Diagnostics.LOCATION, + description: Diagnostics.Specifies_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, { name: "isolatedModules", @@ -268,14 +268,17 @@ namespace ts { error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, }, { - name: "list", - elementType: { - "node": ModuleResolutionKind.NodeJs, - "classic": ModuleResolutionKind.Classic, - }, + name: "lib", type: "list", + element: { + name: "lib", + type: { + "node": ModuleResolutionKind.NodeJs, + "classic": ModuleResolutionKind.Classic, + }, + error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, + }, description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, - error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, }, { name: "allowUnusedLabels", @@ -319,9 +322,13 @@ namespace ts { // this option can only be specified in tsconfig.json // use type = object to copy the value as-is name: "rootDirs", - type: "object", + type: "list", isTSConfigOnly: true, - isFilePath: true + element: { + name: "rootDirs", + type: "string", + isFilePath: true + } }, { name: "traceModuleResolution", @@ -345,6 +352,30 @@ namespace ts { } ]; + /* @internal */ + export let typingOptionDeclarations: CommandLineOption[] = [ + { + name: "enableAutoDiscovery", + type: "boolean", + }, + { + name: "include", + type: "list", + element: { + name: "include", + type: "string" + } + }, + { + name: "exclude", + type: "list", + element: { + name: "include", + type: "string" + } + } + ]; + /* @internal */ export interface OptionNameMap { optionNameMap: Map; @@ -401,7 +432,40 @@ namespace ts { } if (hasProperty(optionNameMap, s)) { - parseString(optionNameMap[s], args[i]); + const opt = optionNameMap[s]; + + if (opt.isTSConfigOnly) { + errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name)); + } + else { + // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). + if (!args[i] && opt.type !== "boolean") { + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name)); + } + + switch (opt.type) { + case "number": + options[opt.name] = parseInt(args[i]); + i++; + break; + case "boolean": + options[opt.name] = true; + break; + case "string": + options[opt.name] = args[i] || ""; + i++; + break; + case "list": + options[opt.name] = parseListTypeOption(opt, args[i]); + i++; + break; + // If not a primitive, the possible types are specified in what is effectively a map of options. + default: + options[opt.name] = parseCustomTypeOption(opt, args[i]); + i++; + break; + } + } } else { errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, s)); @@ -410,40 +474,25 @@ namespace ts { else { fileNames.push(s); } - } - function parseString(opt: CommandLineOption, value: string) { - // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). - if (!value && opt.type !== "boolean") { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name)); + function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string) { + const map = >opt.type; + const key = (value || "").toLowerCase(); + if (hasProperty(map, key)) { + return map[key]; + } + else { + errors.push(createCompilerDiagnostic(opt.error)); + } } - switch (opt.type) { - case "number": - options[opt.name] = parseInt(value); - i++; - break; - case "boolean": - options[opt.name] = true; - break; - case "string": - options[opt.name] = value || ""; - i++; - break; - case "list": - forEach((value || "").split(","), s => parseString(opt.name, opti ); - break; - // If not a primitive, the possible types are specified in what is effectively a map of options. - default: - let map = >opt.type; - let key = (value || "").toLowerCase(); - i++; - if (hasProperty(map, key)) { - options[opt.name] = map[key]; - } - else { - errors.push(createCompilerDiagnostic((opt).error)); - } + function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): number[] | string[] { + const values = (value || "").split(","); + switch (opt.element.type) { + case "number": return ts.map(values, parseInt); + case "string": return ts.map(values, v => v || ""); + default: return ts.map(values, v => parseCustomTypeOption(opt.element, v)); + } } } } @@ -512,7 +561,6 @@ namespace ts { } } - /** * Remove the comments from a json like text. * Comments can be single line comments (starting with # or //) or multiline comments using / * * / @@ -546,18 +594,20 @@ namespace ts { * file to. e.g. outDir */ export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine { - const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName); - + 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 fileNames = getFileNames(errors); return { options, - fileNames: getFileNames(), - typingOptions: getTypingOptions(), + fileNames, + typingOptions, errors }; - function getFileNames(): string[] { + function getFileNames(errors: Diagnostic[]): string[] { let fileNames: string[] = []; if (hasProperty(json, "files")) { if (json["files"] instanceof Array) { @@ -618,47 +668,24 @@ namespace ts { } return fileNames; } - - function getTypingOptions(): TypingOptions { - const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json" - ? { enableAutoDiscovery: true, include: [], exclude: [] } - : { enableAutoDiscovery: false, include: [], exclude: [] }; - const jsonTypingOptions = json["typingOptions"]; - if (jsonTypingOptions) { - for (const id in jsonTypingOptions) { - if (id === "enableAutoDiscovery") { - if (typeof jsonTypingOptions[id] === "boolean") { - options.enableAutoDiscovery = jsonTypingOptions[id]; - } - else { - errors.push(createCompilerDiagnostic(Diagnostics.Unknown_typing_option_0, id)); - } - } - else if (id === "include") { - options.include = convertJsonOptionToStringArray(id, jsonTypingOptions[id], errors); - } - else if (id === "exclude") { - options.exclude = convertJsonOptionToStringArray(id, jsonTypingOptions[id], errors); - } - else { - errors.push(createCompilerDiagnostic(Diagnostics.Unknown_typing_option_0, id)); - } - } - } - return options; - } } export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } { - const options: CompilerOptions = {}; const errors: Diagnostic[] = []; + const options = convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, configFileName, errors); - if (configFileName && getBaseFileName(configFileName) === "jsconfig.json") { + if (configFileName && getBaseFileName(configFileName) === "jsconfig.json" && typeof options.allowJs === "undefined") { options.allowJs = true; } + return { options, errors }; + } + + function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, configFileName: string, errors: Diagnostic[]): T { + const options = {} as T; + if (!jsonOptions) { - return { options, errors }; + return options; } const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name); @@ -666,69 +693,53 @@ namespace ts { for (const id in jsonOptions) { if (hasProperty(optionNameMap, id)) { const opt = optionNameMap[id]; - const optType = opt.type; - let value = jsonOptions[id]; - const expectedType = typeof optType === "string" ? optType : "string"; - if (typeof value === expectedType) { - if (typeof optType !== "string") { - const key = value.toLowerCase(); - if (hasProperty(optType, key)) { - value = optType[key]; - } - else { - errors.push(createCompilerDiagnostic((opt).error)); - value = 0; - } - } - if (opt.isFilePath) { - switch (typeof value) { - case "string": - value = normalizePath(combinePaths(basePath, value)); - break; - case "object": - // "object" options with 'isFilePath' = true expected to be string arrays - value = convertJsonOptionToStringArray(opt.name, value, errors, (element) => normalizePath(combinePaths(basePath, element))); - break; - } - if (value === "") { - value = "."; - } - } - options[opt.name] = value; - } - else { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, id, expectedType)); - } + options[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); } else { errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, id)); } } - return { options, errors }; + return options; } - function convertJsonOptionToStringArray(optionName: string, optionJson: any, errors: Diagnostic[], func?: (element: string) => string): string[] { - const items: string[] = []; - let invalidOptionType = false; - if (!isArray(optionJson)) { - invalidOptionType = true; + function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): number | string | number[] | string[] { + const optType = opt.type; + const expectedType = typeof optType === "string" ? optType : "string"; + if (optType === "list" && isArray(value)) { + return convertJsonOptionOfListType(opt, value, basePath, errors); } - else { - for (const element of optionJson) { - if (typeof element === "string") { - const item = func ? func(element) : element; - items.push(item); - } - else { - invalidOptionType = true; - break; + else if (typeof value === expectedType) { + if (typeof optType !== "string") { + return convertJsonOptionOfCustomType(opt, value, errors); + } + else { + if (opt.isFilePath) { + value = normalizePath(combinePaths(basePath, value)); + if (value === "") { + value = "."; + } } } + return value; } - if (invalidOptionType) { - errors.push(createCompilerDiagnostic(Diagnostics.Option_0_should_have_array_of_strings_as_a_value, optionName)); + else { + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, expectedType)); } - return items; + } + + function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) { + const key = value.toLowerCase(); + if (hasProperty(opt.type, key)) { + return opt.type[key]; + } + else { + errors.push(createCompilerDiagnostic(opt.error)); + return 0; + } + } + + function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] { + return ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6273ea990df..2945fac0b09 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2444,7 +2444,9 @@ namespace ts { // Do not perform validation of output file name in transpile scenarios /* @internal */ suppressOutputPathCheck?: boolean; - [option: string]: string | number | boolean | TsConfigOnlyOptions; + list?: string[]; + + [option: string]: string | number | boolean | TsConfigOnlyOptions | string[] | number[]; } export interface TypingOptions { @@ -2554,13 +2556,14 @@ namespace ts { type: "object"; } - export interface CommandlineOptionOfListType extends CommandLineOptionBase { - type: "list", - elementType: Map | "string" | "number"; + /* @internal */ + export interface CommandLineOptionOfListType extends CommandLineOptionBase { + type: "list"; + element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType; } /* @internal */ - export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption | CommandlineOptionOfListType; + export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption | CommandLineOptionOfListType; /* @internal */ export const enum CharacterCodes { From eb8282469712bb7d9d152370d0f44ea8ab34fcd8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Mar 2016 15:49:29 -0700 Subject: [PATCH 03/16] Chagne specifies -> specify --- src/compiler/commandLineParser.ts | 14 +++++++------- src/compiler/diagnosticMessages.json | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 36aef619888..fd0e42e60bf 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -63,7 +63,7 @@ namespace ts { { name: "reactNamespace", type: "string", - description: Diagnostics.Specifies_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit + description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit }, { name: "listFiles", @@ -77,7 +77,7 @@ namespace ts { name: "mapRoot", type: "string", isFilePath: true, - description: Diagnostics.Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, paramType: Diagnostics.LOCATION, }, { @@ -102,7 +102,7 @@ namespace ts { "crlf": NewLineKind.CarriageReturnLineFeed, "lf": NewLineKind.LineFeed }, - description: Diagnostics.Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, + description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, paramType: Diagnostics.NEWLINE, error: Diagnostics.Argument_for_newLine_option_must_be_CRLF_or_LF }, @@ -187,7 +187,7 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - description: Diagnostics.Specifies_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, + description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, { name: "isolatedModules", @@ -202,7 +202,7 @@ namespace ts { name: "sourceRoot", type: "string", isFilePath: true, - description: Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: Diagnostics.LOCATION, }, { @@ -231,7 +231,7 @@ namespace ts { "es6": ScriptTarget.ES6, "es2015": ScriptTarget.ES2015, }, - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_experimental, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015, paramType: Diagnostics.VERSION, error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES2015 }, @@ -264,7 +264,7 @@ namespace ts { "node": ModuleResolutionKind.NodeJs, "classic": ModuleResolutionKind.Classic, }, - description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, + description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, }, { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 15a3a4e5ef4..a264285d95f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2240,11 +2240,11 @@ "category": "Message", "code": 6002 }, - "Specifies the location where debugger should locate map files instead of generated locations.": { + "Specify the location where debugger should locate map files instead of generated locations.": { "category": "Message", "code": 6003 }, - "Specifies the location where debugger should locate TypeScript files instead of source locations.": { + "Specify the location where debugger should locate TypeScript files instead of source locations.": { "category": "Message", "code": 6004 }, @@ -2276,7 +2276,7 @@ "category": "Message", "code": 6011 }, - "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": { + "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'": { "category": "Message", "code": 6015 }, @@ -2408,7 +2408,7 @@ "category": "Message", "code": 6056 }, - "Specifies the root directory of input files. Use to control the output directory structure with --outDir.": { + "Specify the root directory of input files. Use to control the output directory structure with --outDir.": { "category": "Message", "code": 6058 }, @@ -2416,7 +2416,7 @@ "category": "Error", "code": 6059 }, - "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": { + "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": { "category": "Message", "code": 6060 }, @@ -2448,7 +2448,7 @@ "category": "Message", "code": 6068 }, - "Specifies module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": { + "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": { "category": "Message", "code": 6069 }, @@ -2504,7 +2504,7 @@ "category": "Message", "code": 6083 }, - "Specifies the object invoked for createElement and __spread when targeting 'react' JSX emit": { + "Specify the object invoked for createElement and __spread when targeting 'react' JSX emit": { "category": "Message", "code": 6084 }, From be0592da3bff1a144d1918ea63265b84ad73ffe8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Mar 2016 15:53:42 -0700 Subject: [PATCH 04/16] Add correct options for --lib --- src/compiler/commandLineParser.ts | 53 +++++++++++++++++++++++++--- src/compiler/diagnosticMessages.json | 9 ++++- src/compiler/types.ts | 4 +-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index fd0e42e60bf..ad0a8e7b3d1 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -273,12 +273,33 @@ namespace ts { element: { name: "lib", type: { - "node": ModuleResolutionKind.NodeJs, - "classic": ModuleResolutionKind.Classic, + // JavaScript only + "es5": "lib.es5.d.ts", + "es6": "lib.es6.d.ts", + "es7": "lib.es7.d.ts", + // Host only + "dom": "lib.dom.d.ts", + "webworker": "lib.webworker.d.ts", + "scripthost": "lib.scripthost.d.ts", + // ES6 Or ESNext By-feature options + "es6.array": "lib.es6.array.d.ts", + "es6.collection": "lib.es6.collection.d.ts", + "es6.function": "lib.es6.function.d.ts", + "es6.iterable": "lib.es6.iterable.d.ts", + "es6.math": "lib.es6.math.d.ts", + "es6.number": "lib.es6.number.d.ts", + "es6.object": "lib.es6.object.d.ts", + "es6.promise": "lib.es6.promise.d.ts", + "es6.proxy": "lib.es6.proxy.d.ts", + "es6.reflect": "lib.es6.reflect.d.ts", + "es6.regexp": "lib.es6.regexp.d.ts", + "es6.symbol": "lib.es6.symbol.d.ts", + "es6.symbol.wellknown": "lib.es6.symbol.wellknown.d.ts", + "es7.array.include": "lib.es7.array.include.d.ts" }, - error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, + error: Diagnostics.Arguments_for_library_option_must_be_Colon_0, }, - description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, + description: Diagnostics.Specify_library_to_be_included_in_the_compilation_Colon, }, { name: "allowUnusedLabels", @@ -402,6 +423,27 @@ namespace ts { return optionNameMapCache; } + // Cache between the name of commandline which is a custom type and a list of all possible custom types + const namesOfCustomTypeMapCache: Map = {}; + + /* @internal */ + export function getNamesOfCustomTypeFromCommandLineOptionsOfCustomType(opt: CommandLineOptionOfCustomType): string[] { + if (hasProperty(namesOfCustomTypeMapCache, opt.name)) { + return namesOfCustomTypeMapCache[opt.name]; + } + + const type = opt.type; + const namesOfType: string[] = []; + for (const typeName in type) { + if (hasProperty(type, typeName)) { + namesOfType.push(typeName); + } + } + + namesOfCustomTypeMapCache[opt.name] = namesOfType; + return namesOfCustomTypeMapCache[opt.name]; + } + export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine { const options: CompilerOptions = {}; const fileNames: string[] = []; @@ -482,7 +524,8 @@ namespace ts { return map[key]; } else { - errors.push(createCompilerDiagnostic(opt.error)); + const suggestedOption = getNamesOfCustomTypeFromCommandLineOptionsOfCustomType(opt); + errors.push(createCompilerDiagnostic(opt.error, suggestedOption ? suggestedOption : undefined)); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a264285d95f..c655faf4f3c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2620,7 +2620,14 @@ "category": "Message", "code": 6112 }, - + "Specify library to be included in the compilation:": { + "category": "Message", + "code": 6113 + }, + "Arguments for library option must be: {0}": { + "category": "Error", + "code": 6114 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2945fac0b09..b1efda95a30 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2531,7 +2531,7 @@ namespace ts { /* @internal */ export interface CommandLineOptionBase { name: string; - type: "string" | "number" | "boolean" | "object" | "list" | Map; // a value of a primitive type, or an object literal mapping named values to actual values + type: "string" | "number" | "boolean" | "object" | "list" | Map; // a value of a primitive type, or an object literal mapping named values to actual values isFilePath?: boolean; // True if option value is a path or fileName shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help' description?: DiagnosticMessage; // The message describing what the command line switch does @@ -2547,7 +2547,7 @@ namespace ts { /* @internal */ export interface CommandLineOptionOfCustomType extends CommandLineOptionBase { - type: Map; // an object literal mapping named values to actual values + type: Map; // an object literal mapping named values to actual values error: DiagnosticMessage; // The error given when the argument does not fit a customized 'type' } From c7df7770cd474bd884ca57b4f7450e1c02fcf6f2 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 4 Mar 2016 16:52:31 -0800 Subject: [PATCH 05/16] Add unittest for parsing --lib in tsconfig --- tests/cases/unittests/tsconfigParsing.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/cases/unittests/tsconfigParsing.ts b/tests/cases/unittests/tsconfigParsing.ts index 3603d22f314..118f15745cb 100644 --- a/tests/cases/unittests/tsconfigParsing.ts +++ b/tests/cases/unittests/tsconfigParsing.ts @@ -82,5 +82,25 @@ namespace ts { it("returns object with error when json is invalid", () => { assertParseError("invalid"); }); + + it("returns object when users correctly specify library", () => { + assertParseResult( + `{ + "compilerOptions": { + "library": "es5" + } + }`, { + config: { compilerOptions: { library: "es5" } } + }); + + assertParseResult( + `{ + "compilerOptions": { + "library": "es5,es6" + } + }`, { + config: { compilerOptions: { library: "es5,es6" } } + }); + }); }); } From 157b8e7456a7a34faca007883bb620c8b599173b Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Mar 2016 11:44:33 -0700 Subject: [PATCH 06/16] Add a new unittest for command line parsing for --lib --- Jakefile.js | 3 +- src/compiler/commandLineParser.ts | 15 +- src/compiler/types.ts | 3 +- tests/cases/unittests/commandLineParsing.ts | 160 ++++++++++++++++++++ tests/cases/unittests/tsconfigParsing.ts | 18 +-- 5 files changed, 182 insertions(+), 17 deletions(-) create mode 100644 tests/cases/unittests/commandLineParsing.ts diff --git a/Jakefile.js b/Jakefile.js index 2ffdfc37807..8932e6d976a 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -150,7 +150,8 @@ var harnessSources = harnessCoreSources.concat([ "reuseProgramStructure.ts", "cachingInServerLSHost.ts", "moduleResolution.ts", - "tsconfigParsing.ts" + "tsconfigParsing.ts", + "commandLineParsing.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ad0a8e7b3d1..024a202b2f9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -518,7 +518,7 @@ namespace ts { } function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string) { - const map = >opt.type; + const map = opt.type; const key = (value || "").toLowerCase(); if (hasProperty(map, key)) { return map[key]; @@ -529,12 +529,15 @@ namespace ts { } } - function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): number[] | string[] { - const values = (value || "").split(","); + function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (number | string)[] { + const values = (value || "").split(",").filter(v => { return v != undefined; }); switch (opt.element.type) { - case "number": return ts.map(values, parseInt); - case "string": return ts.map(values, v => v || ""); - default: return ts.map(values, v => parseCustomTypeOption(opt.element, v)); + case "number": + return ts.map(values, parseInt); + case "string": + return ts.map(values, v => v || ""); + default: + return ts.map(values, v => parseCustomTypeOption(opt.element, v)).filter(v => { return v != undefined; }); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b1efda95a30..85febc5e968 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2437,6 +2437,7 @@ namespace ts { allowSyntheticDefaultImports?: boolean; allowJs?: boolean; noImplicitUseStrict?: boolean; + lib?: string[]; /* @internal */ stripInternal?: boolean; // Skip checking lib.d.ts to help speed up tests. @@ -2446,7 +2447,7 @@ namespace ts { list?: string[]; - [option: string]: string | number | boolean | TsConfigOnlyOptions | string[] | number[]; + [option: string]: string | number | boolean | TsConfigOnlyOptions | (string | number)[]; } export interface TypingOptions { diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts new file mode 100644 index 00000000000..a77d1e56494 --- /dev/null +++ b/tests/cases/unittests/commandLineParsing.ts @@ -0,0 +1,160 @@ +/// +/// + +namespace ts { + describe('parseCommandLine', () => { + + function assertParseResult(commandLine: string[], expectedParsedCommandLine: ts.ParsedCommandLine) { + const parsed = ts.parseCommandLine(commandLine); + const parsedCompilerOptions = JSON.stringify(parsed.options); + const expectedCompilerOptions = JSON.stringify(expectedParsedCommandLine.options); + assert.equal(parsedCompilerOptions, expectedCompilerOptions); + + const parsedErrors = parsed.errors; + const expectedErrors = expectedParsedCommandLine.errors; + assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`); + for (let i = 0; i < parsedErrors.length; ++i) { + const parsedError = parsedErrors[i]; + const expectedError = expectedErrors[i]; + assert.equal(parsedError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(parsedError.code)}.`); + assert.equal(parsedError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(parsedError.category)}.`); + } + + const parsedFileNames = parsed.fileNames; + const expectedFileNames = expectedParsedCommandLine.fileNames; + assert.isTrue(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`); + for (let i = 0; i < parsedFileNames.length; ++i) { + const parsedFileName = parsedFileNames[i]; + const expectedFileName = expectedFileNames[i]; + assert.equal(parsedFileName, expectedFileName, `Expected filename: ${JSON.stringify(expectedFileName)}. Actual fileName: ${JSON.stringify(parsedFileName)}.`); + } + } + + it("Parse single option of library flag ", () => { + // --lib es6 0.ts + assertParseResult(["--lib", "es6", "0.ts"], + { + errors: [], + fileNames: ["0.ts"], + options: { + lib: ["lib.es6.d.ts"] + } + }); + }); + + it("Parse multiple options of library flags ", () => { + // --lib es5,es6.symbol.wellknown 0.ts + assertParseResult(["--lib", "es5,es6.symbol.wellknown", "0.ts"], + { + errors: [], + fileNames: ["0.ts"], + options: { + lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"] + } + }); + }); + + it("Parse unavailable options of library flags ", () => { + // --lib es5,es7 0.ts + assertParseResult(["--lib", "es5,es8", "0.ts"], + { + errors: [{ + messageText: "", + category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, + code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: { + lib: ["lib.es5.d.ts"] + } + }); + }); + + it("Parse incorrect form of library flags ", () => { + // --lib es5, es7 0.ts + assertParseResult(["--lib", "es5,", "es7", "0.ts"], + { + errors: [{ + messageText: "", + category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, + code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["es7", "0.ts"], + options: { + lib: ["lib.es5.d.ts"] + } + }); + }); + + it("Parse multiple compiler flags with input files at the end", () => { + // --lib es5,es6.symbol.wellknown --target es5 0.ts + assertParseResult(["--lib", "es5,es6.symbol.wellknown", "--target", "es5", "0.ts"], + { + errors: [], + fileNames: ["0.ts"], + options: { + lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"], + target: ts.ScriptTarget.ES5, + } + }); + }); + + it("Parse multiple compiler flags with input files in the middle", () => { + // --module commonjs --target es5 0.ts --lib es5,es6.symbol.wellknown + assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,es6.symbol.wellknown"], + { + errors: [], + fileNames: ["0.ts"], + options: { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, + lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"], + } + }); + }); + + it("Parse incorrect form of multiple compiler flags with input files in the middle", () => { + // --module commonjs --target es5 0.ts --lib es5, es6.symbol.wellknown + assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,", "es6.symbol.wellknown"], + { + errors: [{ + messageText: "", + category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, + code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts", "es6.symbol.wellknown"], + options: { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, + lib: ["lib.es5.d.ts"], + } + }); + }); + + it("Parse multiple library compiler flags ", () => { + // --module commonjs --target es5 --lib es5 0.ts --library es6.array,es6.symbol.wellknown + assertParseResult(["--module", "commonjs", "--target", "es5", "--lib", "es5", "0.ts", "--lib", "es6.array,es6.symbol.wellknown"], + { + errors: [], + fileNames: ["0.ts"], + options: { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, + lib: ["lib.es6.array.d.ts", "lib.es6.symbol.wellknown.d.ts"], + } + }); + }); + }); +} diff --git a/tests/cases/unittests/tsconfigParsing.ts b/tests/cases/unittests/tsconfigParsing.ts index 118f15745cb..622c3abfff2 100644 --- a/tests/cases/unittests/tsconfigParsing.ts +++ b/tests/cases/unittests/tsconfigParsing.ts @@ -87,20 +87,20 @@ namespace ts { assertParseResult( `{ "compilerOptions": { - "library": "es5" + "lib": "es5" } - }`, { - config: { compilerOptions: { library: "es5" } } - }); - + }`, { + config: { compilerOptions: { lib: "es5" } } + }); + assertParseResult( `{ "compilerOptions": { - "library": "es5,es6" + "lib": "es5,es6" } - }`, { - config: { compilerOptions: { library: "es5,es6" } } - }); + }`, { + config: { compilerOptions: { lib: "es5,es6" } } + }); }); }); } From f4e920e2c16209258dc9c4a341f9448ddbf2aed8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Mar 2016 11:45:21 -0700 Subject: [PATCH 07/16] Add unittest for testing convert compiler-options and typing-options --- Jakefile.js | 6 +- src/compiler/commandLineParser.ts | 21 ++--- .../convertCompilerOptionsFromJson.ts | 78 +++++++++++++++++++ .../unittests/convertTypingOptionsFromJson.ts | 44 +++++++++++ 4 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 tests/cases/unittests/convertCompilerOptionsFromJson.ts create mode 100644 tests/cases/unittests/convertTypingOptionsFromJson.ts diff --git a/Jakefile.js b/Jakefile.js index 8932e6d976a..299ce1c77c4 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -146,12 +146,14 @@ var harnessSources = harnessCoreSources.concat([ "session.ts", "versionCache.ts", "convertToBase64.ts", - "transpile.ts", + "transpile.ts", "reuseProgramStructure.ts", "cachingInServerLSHost.ts", "moduleResolution.ts", "tsconfigParsing.ts", - "commandLineParsing.ts" + "commandLineParsing.ts", + "convertCompilerOptionsFromJson.ts", + "convertTypingOptionsFromJson.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 024a202b2f9..d7d60fd2304 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -656,7 +656,7 @@ namespace ts { function getFileNames(errors: Diagnostic[]): string[] { let fileNames: string[] = []; if (hasProperty(json, "files")) { - if (json["files"] instanceof Array) { + if (isArray(json["files"])) { fileNames = map(json["files"], s => combinePaths(basePath, s)); } else { @@ -667,7 +667,7 @@ namespace ts { const filesSeen: Map = {}; let exclude: string[] = []; - if (json["exclude"] instanceof Array) { + if (isArray(json["exclude"])) { exclude = json["exclude"]; } else { @@ -716,18 +716,8 @@ namespace ts { } } - export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } { - const errors: Diagnostic[] = []; - const options = convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, configFileName, errors); - - if (configFileName && getBaseFileName(configFileName) === "jsconfig.json" && typeof options.allowJs === "undefined") { - options.allowJs = true; - } - - return { options, errors }; - } - - function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, configFileName: string, errors: Diagnostic[]): T { + /* @internal */ + export function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, configFileName: string, errors: Diagnostic[]): T { const options = {} as T; if (!jsonOptions) { @@ -781,11 +771,10 @@ namespace ts { } else { errors.push(createCompilerDiagnostic(opt.error)); - return 0; } } function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] { - return ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)); + return ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)).filter(v => { return v != undefined; }); } } diff --git a/tests/cases/unittests/convertCompilerOptionsFromJson.ts b/tests/cases/unittests/convertCompilerOptionsFromJson.ts new file mode 100644 index 00000000000..bd572757631 --- /dev/null +++ b/tests/cases/unittests/convertCompilerOptionsFromJson.ts @@ -0,0 +1,78 @@ +/// +/// + +namespace ts { + describe('convertCompilerOptionsFromJson', () => { + function assertCompilerOptions(json: any, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) { + const actualErrors: Diagnostic[] = []; + const actualCompilerOptions = convertOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", "tsconfig.json", actualErrors); + + const parsedCompilerOptions = JSON.stringify(actualCompilerOptions); + const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions); + assert.equal(parsedCompilerOptions, expectedCompilerOptions); + + const expectedErrors = expectedResult.errors; + assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`); + for (let i = 0; i < actualErrors.length; ++i) { + const actualError = actualErrors[i]; + const expectedError = expectedErrors[i]; + assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`); + assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`); + } + } + + 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: [] + }); + }); + + 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 + }] + }); + }); + }); +} diff --git a/tests/cases/unittests/convertTypingOptionsFromJson.ts b/tests/cases/unittests/convertTypingOptionsFromJson.ts new file mode 100644 index 00000000000..89a44836e45 --- /dev/null +++ b/tests/cases/unittests/convertTypingOptionsFromJson.ts @@ -0,0 +1,44 @@ +/// +/// + +namespace ts { + describe('convertTypingOptionsFromJson', () => { + function assertTypingOptions(json: any, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) { + const actualErrors: Diagnostic[] = []; + const actualTypingOptions = convertOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", "tsconfig.json", actualErrors); + + const parsedTypingOptions = JSON.stringify(actualTypingOptions); + const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions); + assert.equal(parsedTypingOptions, parsedTypingOptions); + + const expectedErrors = expectedResult.errors; + assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`); + for (let i = 0; i < actualErrors.length; ++i) { + const actualError = actualErrors[i]; + const expectedError = expectedErrors[i]; + assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`); + 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"] + }, + errors: [] + }); + }); + }); +} From 95b43dac2920e653918794c3fd102c7c90e09037 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Mar 2016 16:30:11 -0700 Subject: [PATCH 08/16] Handle default compiler-options and typing-options --- src/compiler/commandLineParser.ts | 38 ++- .../convertCompilerOptionsFromJson.ts | 280 ++++++++++++++---- .../unittests/convertTypingOptionsFromJson.ts | 186 ++++++++++-- 3 files changed, 422 insertions(+), 82 deletions(-) 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: [] + }); + }); }); } From 4d915e59d9e60996ae56482d5287d9e8d4195c02 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Mar 2016 17:04:18 -0700 Subject: [PATCH 09/16] Using ts.filter instead of just .filter --- src/compiler/commandLineParser.ts | 6 +++--- tests/cases/unittests/commandLineParsing.ts | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a9f40ab053c..cd05bb0b2c8 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -530,14 +530,14 @@ namespace ts { } function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (number | string)[] { - const values = (value || "").split(",").filter(v => { return v != undefined; }); + const values = (value.trim() || "").split(","); switch (opt.element.type) { case "number": return ts.map(values, parseInt); case "string": return ts.map(values, v => v || ""); default: - return ts.map(values, v => parseCustomTypeOption(opt.element, v)).filter(v => { return v != undefined; }); + return ts.filter(ts.map(values, v => parseCustomTypeOption(opt.element, v)), v => !!v); } } } @@ -793,6 +793,6 @@ namespace ts { } function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] { - return ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)).filter(v => { return v != undefined; }); + return ts.filter(ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v); } } diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts index a77d1e56494..275bba54f01 100644 --- a/tests/cases/unittests/commandLineParsing.ts +++ b/tests/cases/unittests/commandLineParsing.ts @@ -94,6 +94,26 @@ namespace ts { }); }); + it("Parse incorrect form of library flags with trailing white-space ", () => { + // --lib es5, es7 0.ts + assertParseResult(["--lib", "es5, ", "es7", "0.ts"], + { + errors: [{ + messageText: "", + category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, + code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["es7", "0.ts"], + options: { + lib: ["lib.es5.d.ts"] + } + }); + }); + it("Parse multiple compiler flags with input files at the end", () => { // --lib es5,es6.symbol.wellknown --target es5 0.ts assertParseResult(["--lib", "es5,es6.symbol.wellknown", "--target", "es5", "0.ts"], From 92bee6a533ed621602af5e550366bf80c88700c0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 13:49:36 -0700 Subject: [PATCH 10/16] Unify error message for custom-type compiler option --- src/compiler/commandLineParser.ts | 35 +- src/compiler/diagnosticMessages.json | 10 +- src/compiler/types.ts | 1 - tests/cases/unittests/commandLineParsing.ts | 195 +++++++++-- .../convertCompilerOptionsFromJson.ts | 304 +++++++++++++++--- 5 files changed, 451 insertions(+), 94 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index cd05bb0b2c8..edac2891a58 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -58,7 +58,6 @@ namespace ts { }, paramType: Diagnostics.KIND, description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react, - error: Diagnostics.Argument_for_jsx_must_be_preserve_or_react }, { name: "reactNamespace", @@ -94,7 +93,6 @@ namespace ts { }, description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, paramType: Diagnostics.KIND, - error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_es2015_or_none }, { name: "newLine", @@ -104,7 +102,6 @@ namespace ts { }, description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, paramType: Diagnostics.NEWLINE, - error: Diagnostics.Argument_for_newLine_option_must_be_CRLF_or_LF }, { name: "noEmit", @@ -233,7 +230,6 @@ namespace ts { }, description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015, paramType: Diagnostics.VERSION, - error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES2015 }, { name: "version", @@ -265,7 +261,6 @@ namespace ts { "classic": ModuleResolutionKind.Classic, }, description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, - error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, }, { name: "lib", @@ -297,7 +292,6 @@ namespace ts { "es6.symbol.wellknown": "lib.es6.symbol.wellknown.d.ts", "es7.array.include": "lib.es7.array.include.d.ts" }, - error: Diagnostics.Arguments_for_library_option_must_be_Colon_0, }, description: Diagnostics.Specify_library_to_be_included_in_the_compilation_Colon, }, @@ -423,25 +417,15 @@ namespace ts { return optionNameMapCache; } - // Cache between the name of commandline which is a custom type and a list of all possible custom types - const namesOfCustomTypeMapCache: Map = {}; - /* @internal */ - export function getNamesOfCustomTypeFromCommandLineOptionsOfCustomType(opt: CommandLineOptionOfCustomType): string[] { - if (hasProperty(namesOfCustomTypeMapCache, opt.name)) { - return namesOfCustomTypeMapCache[opt.name]; - } + export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic { - const type = opt.type; const namesOfType: string[] = []; - for (const typeName in type) { - if (hasProperty(type, typeName)) { - namesOfType.push(typeName); - } - } + ts.forEachKey(opt.type, key => { + namesOfType.push(` '${key}'`); + }); - namesOfCustomTypeMapCache[opt.name] = namesOfType; - return namesOfCustomTypeMapCache[opt.name]; + return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType); } export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine { @@ -518,19 +502,18 @@ namespace ts { } function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string) { + const key = (value || "").trim().toLowerCase(); const map = opt.type; - const key = (value || "").toLowerCase(); if (hasProperty(map, key)) { return map[key]; } else { - const suggestedOption = getNamesOfCustomTypeFromCommandLineOptionsOfCustomType(opt); - errors.push(createCompilerDiagnostic(opt.error, suggestedOption ? suggestedOption : undefined)); + errors.push(createCompilerDiagnosticForInvalidCustomType(opt)); } } function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (number | string)[] { - const values = (value.trim() || "").split(","); + const values = (value || "").trim().split(","); switch (opt.element.type) { case "number": return ts.map(values, parseInt); @@ -788,7 +771,7 @@ namespace ts { return opt.type[key]; } else { - errors.push(createCompilerDiagnostic(opt.error)); + errors.push(createCompilerDiagnosticForInvalidCustomType(opt)); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c655faf4f3c..1abcc7a8d0a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2364,14 +2364,10 @@ "category": "Error", "code": 6045 }, - "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'none'.": { + "Argument for '{0}' option must be: {1}": { "category": "Error", "code": 6046 }, - "Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": { - "category": "Error", - "code": 6047 - }, "Locale must be of the form or -. For example '{0}' or '{1}'.": { "category": "Error", "code": 6048 @@ -2424,10 +2420,6 @@ "category": "Message", "code": 6061 }, - "Argument for '--newLine' option must be 'CRLF' or 'LF'.": { - "category": "Error", - "code": 6062 - }, "Argument for '--moduleResolution' option must be 'node' or 'classic'.": { "category": "Error", "code": 6063 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 85febc5e968..0fdcc6300b8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2549,7 +2549,6 @@ namespace ts { /* @internal */ export interface CommandLineOptionOfCustomType extends CommandLineOptionBase { type: Map; // an object literal mapping named values to actual values - error: DiagnosticMessage; // The error given when the argument does not fit a customized 'type' } /* @internal */ diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts index 275bba54f01..5476ec0a5b9 100644 --- a/tests/cases/unittests/commandLineParsing.ts +++ b/tests/cases/unittests/commandLineParsing.ts @@ -16,8 +16,9 @@ namespace ts { for (let i = 0; i < parsedErrors.length; ++i) { const parsedError = parsedErrors[i]; const expectedError = expectedErrors[i]; - assert.equal(parsedError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(parsedError.code)}.`); - assert.equal(parsedError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(parsedError.category)}.`); + assert.equal(parsedError.code, expectedError.code); + assert.equal(parsedError.category, expectedError.category); + assert.equal(parsedError.messageText, expectedError.messageText); } const parsedFileNames = parsed.fileNames; @@ -26,7 +27,7 @@ namespace ts { for (let i = 0; i < parsedFileNames.length; ++i) { const parsedFileName = parsedFileNames[i]; const expectedFileName = expectedFileNames[i]; - assert.equal(parsedFileName, expectedFileName, `Expected filename: ${JSON.stringify(expectedFileName)}. Actual fileName: ${JSON.stringify(parsedFileName)}.`); + assert.equal(parsedFileName, expectedFileName); } } @@ -59,9 +60,9 @@ namespace ts { assertParseResult(["--lib", "es5,es8", "0.ts"], { errors: [{ - messageText: "", - category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, - code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -74,14 +75,172 @@ namespace ts { }); }); - it("Parse incorrect form of library flags ", () => { + it("Parse empty options of --jsx ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--jsx"], + { + errors: [{ + messageText: "Compiler option 'jsx' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: {} + }); + }); + + it("Parse empty options of --module ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--module"], + { + errors: [{ + messageText: "Compiler option 'module' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: {} + }); + }); + + it("Parse empty options of --newLine ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--newLine"], + { + errors: [{ + messageText: "Compiler option 'newLine' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: {} + }); + }); + + it("Parse empty options of --target ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--target"], + { + errors: [{ + messageText: "Compiler option 'target' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: {} + }); + }); + + it("Parse empty options of --moduleResolution ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--moduleResolution"], + { + errors: [{ + messageText: "Compiler option 'moduleResolution' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: {} + }); + }); + + it("Parse empty options of --lib ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--lib"], + { + errors: [{ + messageText: "Compiler option 'lib' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, + + file: undefined, + start: undefined, + length: undefined, + }, { + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + + file: undefined, + start: undefined, + length: undefined, + }], + fileNames: ["0.ts"], + options: { + lib: [] + } + }); + }); + + it("Parse --lib option with extra comma ", () => { // --lib es5, es7 0.ts assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "", - category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, - code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -94,14 +253,14 @@ namespace ts { }); }); - it("Parse incorrect form of library flags with trailing white-space ", () => { + it("Parse --lib option with trailing white-space ", () => { // --lib es5, es7 0.ts assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "", - category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, - code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -141,14 +300,14 @@ namespace ts { }); }); - it("Parse incorrect form of multiple compiler flags with input files in the middle", () => { + it("Parse --lib as the last arguments", () => { // --module commonjs --target es5 0.ts --lib es5, es6.symbol.wellknown assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,", "es6.symbol.wellknown"], { errors: [{ - messageText: "", - category: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.category, - code: ts.Diagnostics.Arguments_for_library_option_must_be_Colon_0.code, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, diff --git a/tests/cases/unittests/convertCompilerOptionsFromJson.ts b/tests/cases/unittests/convertCompilerOptionsFromJson.ts index 14674e18e3f..5c172e33af1 100644 --- a/tests/cases/unittests/convertCompilerOptionsFromJson.ts +++ b/tests/cases/unittests/convertCompilerOptionsFromJson.ts @@ -16,8 +16,9 @@ namespace ts { for (let i = 0; i < actualErrors.length; ++i) { const actualError = actualErrors[i]; const expectedError = expectedErrors[i]; - assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`); - assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`); + assert.equal(actualError.code, expectedError.code); + assert.equal(actualError.category, expectedError.category); + assert.equal(actualError.messageText, expectedError.messageText); } } @@ -71,7 +72,145 @@ namespace ts { } ); }); - + + it("Convert incorrectly option of jsx to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "jsx": "" + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert incorrectly option of module to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + } + }, "tsconfig.json", + { + compilerOptions: { + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert incorrectly option of newLine to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "newLine": "", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + } + }, "tsconfig.json", + { + compilerOptions: { + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert incorrectly option of target to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "target": "", + "noImplicitAny": false, + "sourceMap": false, + } + }, "tsconfig.json", + { + compilerOptions: { + noImplicitAny: false, + sourceMap: false, + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert incorrectly option of module-resolution to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "moduleResolution": "", + "noImplicitAny": false, + "sourceMap": false, + } + }, "tsconfig.json", + { + compilerOptions: { + noImplicitAny: false, + sourceMap: false, + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + it("Convert incorrectly option of libs to compiler-options ", () => { assertCompilerOptions( { @@ -95,14 +234,131 @@ namespace ts { 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 + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] } ); }); + it("Convert empty string option of libs to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": ["es5", ""] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: ["lib.es5.d.ts"] + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert empty string option of libs to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": [""] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: [] + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert trailing-whitespace string option of libs to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": [" "] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: [] + }, + errors: [{ + file: undefined, + start: 0, + length: 0, + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", + code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + }] + } + ); + }); + + it("Convert empty option of libs to compiler-options ", () => { + assertCompilerOptions( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": false, + "sourceMap": false, + "lib": [] + } + }, "tsconfig.json", + { + compilerOptions: { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES5, + noImplicitAny: false, + sourceMap: false, + lib: [] + }, + errors: [] + } + ); + }); + it("Convert incorrectly format tsconfig.json to compiler-options ", () => { assertCompilerOptions( { @@ -116,7 +372,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "", + messageText: "Unknown compiler option 'modu'.", code: Diagnostics.Unknown_compiler_option_0.code, category: Diagnostics.Unknown_compiler_option_0.category }] @@ -185,38 +441,6 @@ namespace ts { ); }); - 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( { @@ -233,7 +457,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "", + messageText: "Unknown compiler option 'modu'.", code: Diagnostics.Unknown_compiler_option_0.code, category: Diagnostics.Unknown_compiler_option_0.category }] From f7a55fa5a232c87cb0178db50be2ff35cd58d0f8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 14:08:49 -0700 Subject: [PATCH 11/16] Remove --lib --- src/compiler/commandLineParser.ts | 35 +--- tests/cases/unittests/commandLineParsing.ts | 170 ++---------------- .../convertCompilerOptionsFromJson.ts | 156 ---------------- 3 files changed, 12 insertions(+), 349 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index edac2891a58..67176e05980 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -262,39 +262,6 @@ namespace ts { }, description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, - { - name: "lib", - type: "list", - element: { - name: "lib", - type: { - // JavaScript only - "es5": "lib.es5.d.ts", - "es6": "lib.es6.d.ts", - "es7": "lib.es7.d.ts", - // Host only - "dom": "lib.dom.d.ts", - "webworker": "lib.webworker.d.ts", - "scripthost": "lib.scripthost.d.ts", - // ES6 Or ESNext By-feature options - "es6.array": "lib.es6.array.d.ts", - "es6.collection": "lib.es6.collection.d.ts", - "es6.function": "lib.es6.function.d.ts", - "es6.iterable": "lib.es6.iterable.d.ts", - "es6.math": "lib.es6.math.d.ts", - "es6.number": "lib.es6.number.d.ts", - "es6.object": "lib.es6.object.d.ts", - "es6.promise": "lib.es6.promise.d.ts", - "es6.proxy": "lib.es6.proxy.d.ts", - "es6.reflect": "lib.es6.reflect.d.ts", - "es6.regexp": "lib.es6.regexp.d.ts", - "es6.symbol": "lib.es6.symbol.d.ts", - "es6.symbol.wellknown": "lib.es6.symbol.wellknown.d.ts", - "es7.array.include": "lib.es7.array.include.d.ts" - }, - }, - description: Diagnostics.Specify_library_to_be_included_in_the_compilation_Colon, - }, { name: "allowUnusedLabels", type: "boolean", @@ -385,7 +352,7 @@ namespace ts { name: "exclude", type: "list", element: { - name: "include", + name: "exclude", type: "string" } } diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts index 5476ec0a5b9..2b6b470a3b3 100644 --- a/tests/cases/unittests/commandLineParsing.ts +++ b/tests/cases/unittests/commandLineParsing.ts @@ -31,52 +31,8 @@ namespace ts { } } - it("Parse single option of library flag ", () => { - // --lib es6 0.ts - assertParseResult(["--lib", "es6", "0.ts"], - { - errors: [], - fileNames: ["0.ts"], - options: { - lib: ["lib.es6.d.ts"] - } - }); - }); - - it("Parse multiple options of library flags ", () => { - // --lib es5,es6.symbol.wellknown 0.ts - assertParseResult(["--lib", "es5,es6.symbol.wellknown", "0.ts"], - { - errors: [], - fileNames: ["0.ts"], - options: { - lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"] - } - }); - }); - - it("Parse unavailable options of library flags ", () => { - // --lib es5,es7 0.ts - assertParseResult(["--lib", "es5,es8", "0.ts"], - { - errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - - file: undefined, - start: undefined, - length: undefined, - }], - fileNames: ["0.ts"], - options: { - lib: ["lib.es5.d.ts"] - } - }); - }); - it("Parse empty options of --jsx ", () => { - // 0.ts --lib + // 0.ts --jsx assertParseResult(["0.ts", "--jsx"], { errors: [{ @@ -102,7 +58,7 @@ namespace ts { }); it("Parse empty options of --module ", () => { - // 0.ts --lib + // 0.ts -- assertParseResult(["0.ts", "--module"], { errors: [{ @@ -128,7 +84,7 @@ namespace ts { }); it("Parse empty options of --newLine ", () => { - // 0.ts --lib + // 0.ts --newLine assertParseResult(["0.ts", "--newLine"], { errors: [{ @@ -154,7 +110,7 @@ namespace ts { }); it("Parse empty options of --target ", () => { - // 0.ts --lib + // 0.ts --target assertParseResult(["0.ts", "--target"], { errors: [{ @@ -180,7 +136,7 @@ namespace ts { }); it("Parse empty options of --moduleResolution ", () => { - // 0.ts --lib + // 0.ts --moduleResolution assertParseResult(["0.ts", "--moduleResolution"], { errors: [{ @@ -205,133 +161,29 @@ namespace ts { }); }); - it("Parse empty options of --lib ", () => { - // 0.ts --lib - assertParseResult(["0.ts", "--lib"], - { - errors: [{ - messageText: "Compiler option 'lib' expects an argument.", - category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, - code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, - - file: undefined, - start: undefined, - length: undefined, - }, { - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - - file: undefined, - start: undefined, - length: undefined, - }], - fileNames: ["0.ts"], - options: { - lib: [] - } - }); - }); - - it("Parse --lib option with extra comma ", () => { - // --lib es5, es7 0.ts - assertParseResult(["--lib", "es5,", "es7", "0.ts"], - { - errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - - file: undefined, - start: undefined, - length: undefined, - }], - fileNames: ["es7", "0.ts"], - options: { - lib: ["lib.es5.d.ts"] - } - }); - }); - - it("Parse --lib option with trailing white-space ", () => { - // --lib es5, es7 0.ts - assertParseResult(["--lib", "es5, ", "es7", "0.ts"], - { - errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - - file: undefined, - start: undefined, - length: undefined, - }], - fileNames: ["es7", "0.ts"], - options: { - lib: ["lib.es5.d.ts"] - } - }); - }); - it("Parse multiple compiler flags with input files at the end", () => { - // --lib es5,es6.symbol.wellknown --target es5 0.ts - assertParseResult(["--lib", "es5,es6.symbol.wellknown", "--target", "es5", "0.ts"], + // --module commonjs --target es5 0.ts + assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { - lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"], + module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES5, } }); }); it("Parse multiple compiler flags with input files in the middle", () => { - // --module commonjs --target es5 0.ts --lib es5,es6.symbol.wellknown - assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,es6.symbol.wellknown"], + // --module commonjs --target es5 0.ts --noImplicitAny + assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--noImplicitAny"], { errors: [], fileNames: ["0.ts"], options: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES5, - lib: ["lib.es5.d.ts", "lib.es6.symbol.wellknown.d.ts"], - } - }); - }); - - it("Parse --lib as the last arguments", () => { - // --module commonjs --target es5 0.ts --lib es5, es6.symbol.wellknown - assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,", "es6.symbol.wellknown"], - { - errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - - file: undefined, - start: undefined, - length: undefined, - }], - fileNames: ["0.ts", "es6.symbol.wellknown"], - options: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES5, - lib: ["lib.es5.d.ts"], - } - }); - }); - - it("Parse multiple library compiler flags ", () => { - // --module commonjs --target es5 --lib es5 0.ts --library es6.array,es6.symbol.wellknown - assertParseResult(["--module", "commonjs", "--target", "es5", "--lib", "es5", "0.ts", "--lib", "es6.array,es6.symbol.wellknown"], - { - errors: [], - fileNames: ["0.ts"], - options: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES5, - lib: ["lib.es6.array.d.ts", "lib.es6.symbol.wellknown.d.ts"], + noImplicitAny: true, } }); }); diff --git a/tests/cases/unittests/convertCompilerOptionsFromJson.ts b/tests/cases/unittests/convertCompilerOptionsFromJson.ts index 5c172e33af1..c68d8b97271 100644 --- a/tests/cases/unittests/convertCompilerOptionsFromJson.ts +++ b/tests/cases/unittests/convertCompilerOptionsFromJson.ts @@ -31,7 +31,6 @@ namespace ts { "target": "es5", "noImplicitAny": false, "sourceMap": false, - "lib": ["es5", "es6.array", "es6.symbol"] } }, "tsconfig.json", { @@ -40,7 +39,6 @@ namespace ts { target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] }, errors: [] } @@ -56,7 +54,6 @@ namespace ts { "noImplicitAny": false, "sourceMap": false, "allowJs": false, - "lib": ["es5", "es6.array", "es6.symbol"] } }, "tsconfig.json", { @@ -66,7 +63,6 @@ namespace ts { noImplicitAny: false, sourceMap: false, allowJs: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] }, errors: [] } @@ -211,154 +207,6 @@ namespace ts { ); }); - it("Convert incorrectly option of libs to compiler-options ", () => { - 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: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category - }] - } - ); - }); - - it("Convert empty string option of libs to compiler-options ", () => { - assertCompilerOptions( - { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", ""] - } - }, "tsconfig.json", - { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: ["lib.es5.d.ts"] - }, - errors: [{ - file: undefined, - start: 0, - length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category - }] - } - ); - }); - - it("Convert empty string option of libs to compiler-options ", () => { - assertCompilerOptions( - { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [""] - } - }, "tsconfig.json", - { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: [] - }, - errors: [{ - file: undefined, - start: 0, - length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category - }] - } - ); - }); - - it("Convert trailing-whitespace string option of libs to compiler-options ", () => { - assertCompilerOptions( - { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [" "] - } - }, "tsconfig.json", - { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: [] - }, - errors: [{ - file: undefined, - start: 0, - length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es7', 'dom', 'webworker', 'scripthost', 'es6.array', 'es6.collection', 'es6.function', 'es6.iterable', 'es6.math', 'es6.number', 'es6.object', 'es6.promise', 'es6.proxy', 'es6.reflect', 'es6.regexp', 'es6.symbol', 'es6.symbol.wellknown', 'es7.array.include'", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category - }] - } - ); - }); - - it("Convert empty option of libs to compiler-options ", () => { - assertCompilerOptions( - { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [] - } - }, "tsconfig.json", - { - compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, - lib: [] - }, - errors: [] - } - ); - }); - it("Convert incorrectly format tsconfig.json to compiler-options ", () => { assertCompilerOptions( { @@ -398,7 +246,6 @@ namespace ts { "target": "es5", "noImplicitAny": false, "sourceMap": false, - "lib": ["es5", "es6.array", "es6.symbol"] } }, "jsconfig.json", { @@ -408,7 +255,6 @@ namespace ts { target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] }, errors: [] } @@ -424,7 +270,6 @@ namespace ts { "noImplicitAny": false, "sourceMap": false, "allowJs": false, - "lib": ["es5", "es6.array", "es6.symbol"] } }, "jsconfig.json", { @@ -434,7 +279,6 @@ namespace ts { target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, - lib: ["lib.es5.d.ts", "lib.es6.array.d.ts", "lib.es6.symbol.d.ts"] }, errors: [] } From 03bf75bf0604ae076eafdbe80ad4b6e95328c624 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 14:09:02 -0700 Subject: [PATCH 12/16] Remove unused error message --- src/compiler/diagnosticMessages.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1abcc7a8d0a..68ce847148f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2612,14 +2612,6 @@ "category": "Message", "code": 6112 }, - "Specify library to be included in the compilation:": { - "category": "Message", - "code": 6113 - }, - "Arguments for library option must be: {0}": { - "category": "Error", - "code": 6114 - }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 From 120c6eba25c59d7f74b463790ae6fc4d86748afe Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 14:09:45 -0700 Subject: [PATCH 13/16] Remove trailing whitespace --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 299ce1c77c4..a6570c3c710 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -146,7 +146,7 @@ var harnessSources = harnessCoreSources.concat([ "session.ts", "versionCache.ts", "convertToBase64.ts", - "transpile.ts", + "transpile.ts", "reuseProgramStructure.ts", "cachingInServerLSHost.ts", "moduleResolution.ts", From 9a5542b1fde2ea5f304db78211429f3443b2ee16 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 14:21:20 -0700 Subject: [PATCH 14/16] Remove unused error message --- src/compiler/diagnosticMessages.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 68ce847148f..b8dd62efa8e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2420,10 +2420,6 @@ "category": "Message", "code": 6061 }, - "Argument for '--moduleResolution' option must be 'node' or 'classic'.": { - "category": "Error", - "code": 6063 - }, "Option '{0}' can only be specified in 'tsconfig.json' file.": { "category": "Error", "code": 6064 @@ -2484,10 +2480,6 @@ "category": "Message", "code": 6080 }, - "Argument for '--jsx' must be 'preserve' or 'react'.": { - "category": "Message", - "code": 6081 - }, "Only 'amd' and 'system' modules are supported alongside --{0}.": { "category": "Error", "code": 6082 From 266a92b1f348005260e7770c06af65b72b3b63dc Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 15:29:13 -0700 Subject: [PATCH 15/16] Address PR --- src/compiler/commandLineParser.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 67176e05980..221ef5b87a8 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -386,9 +386,8 @@ namespace ts { /* @internal */ export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic { - const namesOfType: string[] = []; - ts.forEachKey(opt.type, key => { + forEachKey(opt.type, key => { namesOfType.push(` '${key}'`); }); @@ -487,7 +486,7 @@ namespace ts { case "string": return ts.map(values, v => v || ""); default: - return ts.filter(ts.map(values, v => parseCustomTypeOption(opt.element, v)), v => !!v); + return filter(map(values, v => parseCustomTypeOption(opt.element, v)), v => !!v); } } } @@ -743,6 +742,6 @@ namespace ts { } function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] { - return ts.filter(ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v); + return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v); } } From 9e2df0459eb1c144b15d8c2b6e02705886495675 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Mar 2016 16:35:51 -0700 Subject: [PATCH 16/16] Address PR --- src/compiler/commandLineParser.ts | 22 +++++++++---------- src/compiler/types.ts | 4 +++- .../convertCompilerOptionsFromJson.ts | 2 +- .../unittests/convertTypingOptionsFromJson.ts | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 221ef5b87a8..2f10a8103c4 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -478,7 +478,7 @@ namespace ts { } } - function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (number | string)[] { + function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (string | number)[] { const values = (value || "").trim().split(","); switch (opt.element.type) { case "number": @@ -590,9 +590,9 @@ namespace ts { */ export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine { const errors: Diagnostic[] = []; - const compilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], basePath, configFileName, errors); + const compilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], basePath, errors, configFileName); const options = extend(existingOptions, compilerOptions); - const typingOptions: TypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], basePath, configFileName, errors); + const typingOptions: TypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], basePath, errors, configFileName); const fileNames = getFileNames(errors); @@ -667,27 +667,27 @@ namespace ts { } /* @internal */ - export function convertCompilerOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, - configFileName: string, errors: Diagnostic[]): CompilerOptions { + export function convertCompilerOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, + basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions { const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {}; - convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, configFileName, options, Diagnostics.Unknown_compiler_option_0, errors); + convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors); return options; } /* @internal */ - export function convertTypingOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, basePath: string, - configFileName: string, errors: Diagnostic[]): TypingOptions { + export function convertTypingOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any, + basePath: string, errors: Diagnostic[], configFileName?: string): 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); + convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, 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[]) { + defaultOptions: T, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) { if (!jsonOptions) { return ; @@ -706,7 +706,7 @@ namespace ts { } } - function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): number | string | number[] | string[] { + function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): CompilerOptionsValue { const optType = opt.type; const expectedType = typeof optType === "string" ? optType : "string"; if (optType === "list" && isArray(value)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0fdcc6300b8..3fc172e39fd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2381,6 +2381,8 @@ namespace ts { export type PathSubstitutions = Map; export type TsConfigOnlyOptions = RootPaths | PathSubstitutions; + export type CompilerOptionsValue = string | number | boolean | (string | number)[] | TsConfigOnlyOptions; + export interface CompilerOptions { allowNonTsExtensions?: boolean; charset?: string; @@ -2447,7 +2449,7 @@ namespace ts { list?: string[]; - [option: string]: string | number | boolean | TsConfigOnlyOptions | (string | number)[]; + [option: string]: CompilerOptionsValue; } export interface TypingOptions { diff --git a/tests/cases/unittests/convertCompilerOptionsFromJson.ts b/tests/cases/unittests/convertCompilerOptionsFromJson.ts index c68d8b97271..4edc3bdd200 100644 --- a/tests/cases/unittests/convertCompilerOptionsFromJson.ts +++ b/tests/cases/unittests/convertCompilerOptionsFromJson.ts @@ -5,7 +5,7 @@ namespace ts { describe('convertCompilerOptionsFromJson', () => { function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) { const actualErrors: Diagnostic[] = []; - const actualCompilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", configFileName, actualErrors); + const actualCompilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", actualErrors, configFileName); const parsedCompilerOptions = JSON.stringify(actualCompilerOptions); const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions); diff --git a/tests/cases/unittests/convertTypingOptionsFromJson.ts b/tests/cases/unittests/convertTypingOptionsFromJson.ts index 898dee0a18b..92b450555a9 100644 --- a/tests/cases/unittests/convertTypingOptionsFromJson.ts +++ b/tests/cases/unittests/convertTypingOptionsFromJson.ts @@ -5,7 +5,7 @@ namespace ts { describe('convertTypingOptionsFromJson', () => { function assertTypingOptions(json: any, configFileName: string, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) { const actualErrors: Diagnostic[] = []; - const actualTypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", configFileName, actualErrors); + const actualTypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", actualErrors, configFileName); const parsedTypingOptions = JSON.stringify(actualTypingOptions); const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions); assert.equal(parsedTypingOptions, expectedTypingOptions);