Support using string values in enums for CompilerOptions in transpile methods

This commit is contained in:
Andy Hanson
2016-06-06 11:29:03 -07:00
parent 13ddc34607
commit d9ec5125be
3 changed files with 59 additions and 12 deletions

View File

@@ -6,7 +6,7 @@
namespace ts {
/* @internal */
export let optionDeclarations: CommandLineOption[] = [
export const optionDeclarations: CommandLineOption[] = [
{
name: "charset",
type: "string",

View File

@@ -1920,6 +1920,36 @@ namespace ts {
sourceMapText?: string;
}
/** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]) {
options = clone(options);
for (const opt of stringValuedEnums) {
if (!hasProperty(options, opt.name)) {
continue;
}
const value = options[opt.name];
// Value should be a key of opt.type
if (typeof value === "string") {
// If value is not a string, this will fail
options[opt.name] = parseCustomTypeOption(opt, value, diagnostics);
}
else {
if (!forEachValue(opt.type, v => v === value)) {
// Supplied value isn't a valid enum value.
diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt));
}
}
}
return options;
}
const stringValuedEnums = <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o => {
return typeof o.type === "object" && !forEachValue(<Map<any>> o.type, v => typeof v !== "number");
});
/*
* This function will compile source text from 'input' argument using specified compiler options.
* If not options are provided - it will use a set of default compiler options.
@@ -1930,7 +1960,9 @@ namespace ts {
* - noResolve = true
*/
export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput {
const options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
const diagnostics: Diagnostic[] = [];
const options: CompilerOptions = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : getDefaultCompilerOptions();
options.isolatedModules = true;
@@ -1988,9 +2020,7 @@ namespace ts {
const program = createProgram([inputFileName], options, compilerHost);
let diagnostics: Diagnostic[];
if (transpileOptions.reportDiagnostics) {
diagnostics = [];
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
}

View File

@@ -9,11 +9,7 @@ namespace ts {
expectedDiagnosticCodes?: number[];
}
function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) {
if (!expectedDiagnosticCodes) {
return;
}
function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes: number[] = []) {
for (let i = 0; i < expectedDiagnosticCodes.length; i++) {
assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`);
}
@@ -26,7 +22,7 @@ namespace ts {
if (!transpileOptions.compilerOptions) {
transpileOptions.compilerOptions = {};
}
if (transpileOptions.compilerOptions.newLine === undefined) { //
if (transpileOptions.compilerOptions.newLine === undefined) {
// use \r\n as default new line
transpileOptions.compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed;
}
@@ -292,13 +288,34 @@ var x = 0;`,
const output = `"use strict";\nvar a = 10;\n`;
test(input, {
expectedOutput: output,
options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true },
expectedDiagnosticCodes: []
options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true }
});
});
it("Supports urls in file name", () => {
test("var x", { expectedOutput: `"use strict";\r\nvar x;\r\n`, options: { fileName: "http://somewhere/directory//directory2/file.ts" } });
});
describe("String values for enums", () => {
it("Accepts strings instead of enum values", () => {
test(`export const x = 0`, {
options: {
compilerOptions: {
module: <ModuleKind><any>"es6",
// Capitalization and spaces ignored
target: <ScriptTarget><any>" Es6 "
}
},
expectedOutput: "export const x = 0;\r\n"
});
});
it("Fails on bad value", () => {
test(``, {
options: { compilerOptions: { module: <ModuleKind><any>{} } },
expectedDiagnosticCodes: [6046]
});
});
});
});
}