Remove the logic for parsing compilation of comma seperated list of strings on command line
Also removed logic to accept multiple values for the option
This commit is contained in:
parent
ea57efa430
commit
a8eb76fde1
|
@ -312,23 +312,31 @@ namespace ts {
|
|||
if (hasProperty(optionNameMap, s)) {
|
||||
let opt = optionNameMap[s];
|
||||
|
||||
if (opt.type === "boolean") {
|
||||
// This needs to be treated specially since it doesnt accept argument
|
||||
options[opt.name] = true;
|
||||
// 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));
|
||||
}
|
||||
else {
|
||||
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
|
||||
if (!args[i]) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
|
||||
}
|
||||
|
||||
let { hasError, value} = parseOption(opt, args[i++], options[opt.name]);
|
||||
if (hasError) {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
}
|
||||
else {
|
||||
options[opt.name] = value;
|
||||
}
|
||||
switch (opt.type) {
|
||||
case "number":
|
||||
options[opt.name] = parseInt(args[i++]);
|
||||
break;
|
||||
case "boolean":
|
||||
options[opt.name] = true;
|
||||
break;
|
||||
case "string":
|
||||
options[opt.name] = args[i++] || "";
|
||||
break;
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
default:
|
||||
let map = <Map<number>>opt.type;
|
||||
let key = (args[i++] || "").toLowerCase();
|
||||
if (hasProperty(map, key)) {
|
||||
options[opt.name] = map[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -375,68 +383,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses non quoted strings separated by comma e.g. "a,b" would result in string array ["a", "b"]
|
||||
* @param s
|
||||
* @param existingValue
|
||||
*/
|
||||
function parseMultiValueStringArray(s: string, existingValue: string[]) {
|
||||
let value: string[] = existingValue || [];
|
||||
let hasError = false;
|
||||
let currentString = "";
|
||||
if (s) {
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
let ch = s.charCodeAt(i);
|
||||
if (ch === CharacterCodes.comma) {
|
||||
pushCurrentStringToResult();
|
||||
}
|
||||
else {
|
||||
currentString += s.charAt(i);
|
||||
}
|
||||
}
|
||||
// push last string
|
||||
pushCurrentStringToResult();
|
||||
}
|
||||
return { value, hasError };
|
||||
|
||||
function pushCurrentStringToResult() {
|
||||
if (currentString) {
|
||||
value.push(currentString);
|
||||
currentString = "";
|
||||
}
|
||||
else {
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function parseOption(option: CommandLineOption, stringValue: string, existingValue: CompilerOptionsValueType) {
|
||||
let hasError: boolean;
|
||||
let value: CompilerOptionsValueType;
|
||||
switch (option.type) {
|
||||
case "number":
|
||||
value = parseInt(stringValue);
|
||||
break;
|
||||
case "string":
|
||||
value = stringValue || "";
|
||||
break;
|
||||
case "string[]":
|
||||
return parseMultiValueStringArray(stringValue, <string[]>existingValue);
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
default:
|
||||
let map = <Map<number>>option.type;
|
||||
let key = (stringValue || "").toLowerCase();
|
||||
if (hasProperty(map, key)) {
|
||||
value = map[key];
|
||||
}
|
||||
else {
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
return { hasError, value };
|
||||
}
|
||||
|
||||
/**
|
||||
* Read tsconfig.json file
|
||||
* @param fileName The path to the config file
|
||||
|
@ -466,44 +412,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function parseJsonCompilerOption(opt: CommandLineOption, jsonValue: any, errors: Diagnostic[]) {
|
||||
let optType = opt.type;
|
||||
let expectedType = typeof optType === "string" ? optType : "string";
|
||||
let hasValidValue = true;
|
||||
if (typeof jsonValue === expectedType) {
|
||||
if (typeof optType !== "string") {
|
||||
let key = jsonValue.toLowerCase();
|
||||
if (hasProperty(optType, key)) {
|
||||
jsonValue = optType[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
jsonValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if the value asked was string[] and value provided was not string[]
|
||||
else if (expectedType !== "string[]" ||
|
||||
!(jsonValue instanceof Array) ||
|
||||
forEach(<string[]>jsonValue, individualValue => typeof individualValue !== "string")) {
|
||||
// Not expectedType
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, expectedType));
|
||||
hasValidValue = false;
|
||||
}
|
||||
|
||||
return {
|
||||
value: <CompilerOptionsValueType>jsonValue,
|
||||
hasValidValue
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the contents of a config file (tsconfig.json).
|
||||
* @param json The contents of the config file to parse
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
* @param existingOptions optional existing options to extend into
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine {
|
||||
let errors: Diagnostic[] = [];
|
||||
|
@ -526,16 +439,31 @@ namespace ts {
|
|||
for (let id in jsonOptions) {
|
||||
if (hasProperty(optionNameMap, id)) {
|
||||
let opt = optionNameMap[id];
|
||||
let { hasValidValue, value } = parseJsonCompilerOption(opt, jsonOptions[id], errors);
|
||||
if (hasValidValue) {
|
||||
let optType = opt.type;
|
||||
let value = jsonOptions[id];
|
||||
let expectedType = typeof optType === "string" ? optType : "string";
|
||||
if (typeof value === expectedType) {
|
||||
if (typeof optType !== "string") {
|
||||
let key = value.toLowerCase();
|
||||
if (hasProperty(optType, key)) {
|
||||
value = optType[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
if (opt.isFilePath) {
|
||||
value = normalizePath(combinePaths(basePath, <string>value));
|
||||
value = normalizePath(combinePaths(basePath, value));
|
||||
if (value === "") {
|
||||
value = ".";
|
||||
}
|
||||
}
|
||||
options[opt.name] = value;
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, id, expectedType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, id));
|
||||
|
|
|
@ -588,8 +588,8 @@ namespace ts {
|
|||
|
||||
return;
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValueType> {
|
||||
let result: Map<CompilerOptionsValueType> = {};
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
|
||||
let result: Map<string | number | boolean> = {};
|
||||
let optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (let name in options) {
|
||||
|
@ -606,8 +606,8 @@ namespace ts {
|
|||
let optionDefinition = optionsNameMap[name.toLowerCase()];
|
||||
if (optionDefinition) {
|
||||
if (typeof optionDefinition.type === "string") {
|
||||
// string, number, boolean or string[]
|
||||
result[name] = <string | number | boolean | string[]>value;
|
||||
// string, number or boolean
|
||||
result[name] = value;
|
||||
}
|
||||
else {
|
||||
// Enum
|
||||
|
|
|
@ -2095,11 +2095,9 @@ namespace ts {
|
|||
// Skip checking lib.d.ts to help speed up tests.
|
||||
/* @internal */ skipDefaultLibCheck?: boolean;
|
||||
|
||||
[option: string]: CompilerOptionsValueType;
|
||||
[option: string]: string | number | boolean;
|
||||
}
|
||||
|
||||
export type CompilerOptionsValueType = string | number | boolean | string[];
|
||||
|
||||
export const enum ModuleKind {
|
||||
None = 0,
|
||||
CommonJS = 1,
|
||||
|
@ -2166,7 +2164,7 @@ namespace ts {
|
|||
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfCustomType extends CommandLineOptionBase {
|
||||
type: Map<number> | string; // an object literal mapping named values to actual values | string if it is string[]
|
||||
type: Map<number>; // an object literal mapping named values to actual values
|
||||
error: DiagnosticMessage; // The error given when the argument does not fit a customized 'type'
|
||||
}
|
||||
|
||||
|
|
|
@ -1006,17 +1006,23 @@ namespace Harness {
|
|||
}
|
||||
let option = getCommandLineOption(name);
|
||||
if (option) {
|
||||
if (option.type === "boolean") {
|
||||
options[option.name] = value.toLowerCase() === "true";
|
||||
}
|
||||
else {
|
||||
let { hasError, value: parsedValue } = ts.parseOption(option, value, options[option.name]);
|
||||
if (hasError) {
|
||||
throw new Error(`Unknown value '${value}' for compiler option '${name}'.`);
|
||||
}
|
||||
else {
|
||||
options[option.name] = parsedValue;
|
||||
}
|
||||
switch (option.type) {
|
||||
case "boolean":
|
||||
options[option.name] = value.toLowerCase() === "true";
|
||||
break;
|
||||
case "string":
|
||||
options[option.name] = value;
|
||||
break;
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
default:
|
||||
let map = <ts.Map<number>>option.type;
|
||||
let key = value.toLowerCase();
|
||||
if (ts.hasProperty(map, key)) {
|
||||
options[option.name] = map[key];
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unknown value '${value}' for compiler option '${name}'.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/* tslint:disable:no-null */
|
||||
|
||||
// Test case is json of below type in tests/cases/project/
|
||||
interface ProjectRunnerTestCase extends ts.CompilerOptions {
|
||||
interface ProjectRunnerTestCase {
|
||||
scenario: string;
|
||||
projectRoot: string; // project where it lives - this also is the current directory when compiling
|
||||
inputFiles: string[]; // list of input files to be given to program
|
||||
|
@ -51,7 +51,7 @@ class ProjectRunner extends RunnerBase {
|
|||
}
|
||||
|
||||
private runProjectTestCase(testCaseFileName: string) {
|
||||
let testCase: ProjectRunnerTestCase;
|
||||
let testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
|
||||
let testFileText: string = null;
|
||||
try {
|
||||
|
@ -62,7 +62,7 @@ class ProjectRunner extends RunnerBase {
|
|||
}
|
||||
|
||||
try {
|
||||
testCase = <ProjectRunnerTestCase>JSON.parse(testFileText);
|
||||
testCase = <ProjectRunnerTestCase & ts.CompilerOptions>JSON.parse(testFileText);
|
||||
}
|
||||
catch (e) {
|
||||
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
|
@ -183,13 +183,7 @@ class ProjectRunner extends RunnerBase {
|
|||
|
||||
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
let inputFiles = testCase.inputFiles;
|
||||
let { errors, compilerOptions } = createCompilerOptions();
|
||||
if (errors.length) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors
|
||||
};
|
||||
}
|
||||
let compilerOptions = createCompilerOptions();
|
||||
|
||||
let configFileName: string;
|
||||
if (compilerOptions.project) {
|
||||
|
@ -240,7 +234,6 @@ class ProjectRunner extends RunnerBase {
|
|||
module: moduleKind,
|
||||
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
|
||||
};
|
||||
let errors: ts.Diagnostic[] = [];
|
||||
// Set the values specified using json
|
||||
let optionNameMap: ts.Map<ts.CommandLineOption> = {};
|
||||
ts.forEach(ts.optionDeclarations, option => {
|
||||
|
@ -249,14 +242,19 @@ class ProjectRunner extends RunnerBase {
|
|||
for (let name in testCase) {
|
||||
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
|
||||
let option = optionNameMap[name];
|
||||
let { hasValidValue, value } = ts.parseJsonCompilerOption(option, testCase[name], errors);
|
||||
if (hasValidValue) {
|
||||
compilerOptions[option.name] = value;
|
||||
let optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
let key = value.toLowerCase();
|
||||
if (ts.hasProperty(optType, key)) {
|
||||
value = optType[key];
|
||||
}
|
||||
}
|
||||
compilerOptions[option.name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return { errors, compilerOptions };
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
function getFileNameInTheProjectTest(fileName: string): string {
|
||||
|
|
Loading…
Reference in a new issue