diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 361b38d402b07..1434cbbadf06d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -488,13 +488,20 @@ namespace ts { } /* @internal */ - export function parseListTypeOption(opt: CommandLineOptionOfListType, value: string, errors: Diagnostic[]): (string | number)[] { - const values = trimString((value || "")).split(","); + export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): (string | number)[] | undefined { + value = trimString(value); + if (startsWith(value, "-")) { + return undefined; + } + if (value === "") { + return []; + } + const values = value.split(","); switch (opt.element.type) { case "number": - return ts.map(values, parseInt); + return map(values, parseInt); case "string": - return ts.map(values, v => v || ""); + return map(values, v => v || ""); default: return filter(map(values, v => parseCustomTypeOption(opt.element, v, errors)), v => !!v); } @@ -555,8 +562,11 @@ namespace ts { i++; break; case "list": - options[opt.name] = parseListTypeOption(opt, args[i], errors); - i++; + const result = parseListTypeOption(opt, args[i], errors); + options[opt.name] = result || []; + if (result) { + i++; + } break; // If not a primitive, the possible types are specified in what is effectively a map of options. default: diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts index 8212ff03da48c..095f912ac1c95 100644 --- a/tests/cases/unittests/commandLineParsing.ts +++ b/tests/cases/unittests/commandLineParsing.ts @@ -216,10 +216,23 @@ namespace ts { file: undefined, start: undefined, length: undefined, - }, { - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + }], + fileNames: ["0.ts"], + options: { + lib: [] + } + }); + }); + + it("Parse empty string of --lib ", () => { + // 0.ts --lib + // This test is an error because the empty string is falsey + 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, @@ -232,6 +245,19 @@ namespace ts { }); }); + it("Parse immediately following command line argument of --lib ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--lib", "--sourcemap"], + { + errors: [], + fileNames: ["0.ts"], + options: { + lib: [], + sourceMap: true + } + }); + }); + it("Parse --lib option with extra comma ", () => { // --lib es5, es7 0.ts assertParseResult(["--lib", "es5,", "es7", "0.ts"],