From db6e46df120bbec4fa9325315e5887e1d256143a Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Wed, 29 Jul 2015 10:26:18 +0800 Subject: [PATCH] Removes trailing comma logic and fixes default values --- Jakefile.js | 2 +- src/compiler/commandLineParser.ts | 70 +++--- src/compiler/emitter.ts | 184 --------------- src/compiler/program.ts | 218 +++++++++++++++++- src/compiler/tsc.ts | 4 +- ...dTrailingCommas.ts => jsonWithComments.ts} | 24 -- tests/cases/unittests/projectInit.ts | 46 ++-- 7 files changed, 275 insertions(+), 273 deletions(-) rename tests/cases/unittests/{jsonWithCommentsAndTrailingCommas.ts => jsonWithComments.ts} (65%) diff --git a/Jakefile.js b/Jakefile.js index e3f2e8c22c7..4f922dd3ab8 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -143,7 +143,7 @@ var harnessSources = harnessCoreSources.concat([ "convertToBase64.ts", "transpile.ts", "projectInit.ts", - "jsonWithCommentsAndTrailingCommas.ts" + "jsonWithComments.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6ba05473b7c..38faf0a43fb 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -386,49 +386,35 @@ namespace ts { continue; } - if(ch === CharacterCodes.slash) { - if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { - pos += 2; - - while (pos <= end) { - if (isLineBreak(text.charCodeAt(pos))) { - break; - } - pos++; - } - continue; - } - else if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { - pos += 2; - - while (pos <= end) { - ch = text.charCodeAt(pos); - - if (ch === CharacterCodes.asterisk && - text.charCodeAt(pos + 1) === CharacterCodes.slash) { - - pos += 2; - break; - } - pos++; - } - continue; - } - } - - if (pendingCommaInsertion) { - if (ch !== CharacterCodes.closeBracket && - ch !== CharacterCodes.closeBrace) { - - result += ','; - } - pendingCommaInsertion = false; - } - switch (ch) { - case CharacterCodes.comma: - pendingCommaInsertion = true; - break; + case CharacterCodes.slash: + if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { + pos += 2; + + while (pos <= end) { + if (isLineBreak(text.charCodeAt(pos))) { + break; + } + pos++; + } + break; + } + else if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { + pos += 2; + + while (pos <= end) { + ch = text.charCodeAt(pos); + + if (ch === CharacterCodes.asterisk && + text.charCodeAt(pos + 1) === CharacterCodes.slash) { + + pos += 2; + break; + } + pos++; + } + break; + } case CharacterCodes.doubleQuote: result += text[pos]; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 46a44d7b268..b707fc77894 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3,190 +3,6 @@ /* @internal */ namespace ts { - export const defaultInitCompilerOptions: CompilerOptions = { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES3, - noImplicitAny: true, - outDir: "built", - rootDir: ".", - sourceMap: false, - } - - export function buildConfigFile(writer: EmitTextWriter, compilerOptions: CompilerOptions, fileNames?: string[], excludes?: string[]) { - compilerOptions = extend(compilerOptions, defaultInitCompilerOptions); - let { write, writeLine, increaseIndent, decreaseIndent } = writer; - let { optionNameMap } = getOptionNameMap(); - writeTsConfigDotJsonFile(); - - function writeTsConfigDotJsonFile() { - write("{"); - writeLine(); - increaseIndent(); - writeCompilerOptions(); - if (fileNames && fileNames.length > 0) { - write(","); - writeLine(); - writeFileNames(); - } - if (excludes) { - write(","); - writeLine(); - writeExcludeOptions(); - } - writeLine(); - decreaseIndent(); - write("}"); - } - - function writeCompilerOptions() { - write(`"compilerOptions": {`); - writeLine(); - increaseIndent(); - - for (var option in compilerOptions) { - switch (option) { - case "init": - case "watch": - case "help": - case "version": - continue; - - case "module": - case "target": - case "newLine": - writeComplexCompilerOption(option); - break; - - default: - writeSimpleCompilerOption(option); - } - } - - decreaseIndent(); - write("}"); - } - - function writeOptionalOptionDescription(option: string) { - option = option.toLowerCase(); - if (optionNameMap[option].description && - optionNameMap[option].description.key) { - - write(`// ${optionNameMap[option].description.key}`); - writeLine(); - } - } - - /** - * Write simple compiler option. A simple compiler option is an option - * with boolean or non string set value. - */ - function writeSimpleCompilerOption(option: string) { - writeOptionalOptionDescription(option); - - write(`"${option}": `); - if (typeof compilerOptions[option] === "string") { - write(`"${compilerOptions[option]}",`); - writeLine(); - } - else { - if (compilerOptions[option]) { - write("true,"); - } - else { - write("false,"); - } - writeLine(); - } - } - - function writeComplexCompilerOption(option: string) { - writeOptionalOptionDescription(option); - - outer: switch (option) { - case "module": - var moduleValue: string; - switch (compilerOptions.module) { - case ModuleKind.None: - break outer; - case ModuleKind.CommonJS: - moduleValue = "commonjs"; - break; - case ModuleKind.System: - moduleValue = "system"; - break; - case ModuleKind.UMD: - moduleValue = "umd"; - break; - default: - moduleValue = "amd"; - break; - } - write(`"module": "${moduleValue}",`); - writeLine(); - break; - - case "target": - var targetValue: string; - switch (compilerOptions.target) { - case ScriptTarget.ES5: - targetValue = "es5"; - break; - case ScriptTarget.ES6: - targetValue = "es6"; - break; - default: - targetValue = "es3"; - break; - } - write(`"target": "${targetValue}",`); - writeLine(); - break; - - case "newLine": - var newlineValue: string; - switch (compilerOptions.newLine) { - case NewLineKind.CarriageReturnLineFeed: - newlineValue = "CRLF"; - break; - default: - newlineValue = "LF"; - break; - } - write(`"newLine": "${newlineValue}",`); - writeLine(); - break; - } - } - - function writeFileNames() { - write(`"files": [`); - writeLine(); - increaseIndent(); - - for (let fileName of fileNames) { - write(`"${fileName}",`); - writeLine(); - } - - decreaseIndent(); - write("]"); - } - - function writeExcludeOptions() { - write(`"exclude": [`); - writeLine(); - increaseIndent(); - - for (let exclude of excludes) { - write(`"${exclude}",`); - writeLine(); - } - - decreaseIndent(); - write("]"); - } - } - export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) { return isExternalModule(sourceFile) || isDeclarationFile(sourceFile); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ce6dac19f91..70b89db4eaf 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,5 +1,6 @@ /// /// +/// namespace ts { /* @internal */ export let programTime = 0; @@ -26,10 +27,219 @@ namespace ts { return undefined; } - export function writeConfigFile(file: string, compilerOptions: CompilerOptions, fileNames: string[]): void { - let writer = createTextWriter("\n"); - buildConfigFile(writer, compilerOptions, fileNames, ["node_modules"]); - sys.writeFile(file, writer.getText()); + export const defaultInitCompilerOptions: CompilerOptions = { + module: ModuleKind.CommonJS, + target: ScriptTarget.ES3, + noImplicitAny: false, + outDir: "built", + rootDir: ".", + sourceMap: false, + } + + export function buildConfigFile(writer: EmitTextWriter, compilerOptions: CompilerOptions, fileNames?: string[], excludes?: string[]) { + compilerOptions = extend(compilerOptions, defaultInitCompilerOptions); + let { write, writeLine, increaseIndent, decreaseIndent } = writer; + let { optionNameMap } = getOptionNameMap(); + writeConfigFile(); + + function writeConfigFile() { + write("{"); + writeLine(); + increaseIndent(); + writeCompilerOptions(); + if (fileNames && fileNames.length > 0) { + write(","); + writeLine(); + writeFileNames(); + } + if (excludes) { + write(","); + writeLine(); + writeExcludeOptions(); + } + writeLine(); + decreaseIndent(); + write("}"); + } + + function writeCompilerOptions() { + write(`"compilerOptions": {`); + writeLine(); + increaseIndent(); + + let length = 0; + for (var option in compilerOptions) { + length++; + } + + let i = 0; + for (var option in compilerOptions) { + switch (option) { + case "init": + case "watch": + case "help": + case "version": + i++; + continue; + + case "module": + case "target": + case "newLine": + writeComplexCompilerOption(option, i < length - 1); + break; + + default: + writeSimpleCompilerOption(option, i < length - 1); + + } + i++; + } + + decreaseIndent(); + write("}"); + } + + function writeOptionalOptionDescription(option: string) { + option = option.toLowerCase(); + if (optionNameMap[option].description && + optionNameMap[option].description.key) { + + write(`// ${optionNameMap[option].description.key}`); + writeLine(); + } + } + + /** + * Write simple compiler option. A simple compiler option is an option + * with boolean or non string set value. + */ + function writeSimpleCompilerOption(option: string, writeComma: boolean) { + writeOptionalOptionDescription(option); + + write(`"${option}": `); + if (typeof compilerOptions[option] === "string") { + write(`"${compilerOptions[option]}"`); + } + else { + if (compilerOptions[option]) { + write("true"); + } + else { + write("false"); + } + } + + if (writeComma) { + write(","); + } + writeLine(); + } + + /** + * Write complex compiler option. A complex compiler option is an option + * which maps to a TypeScript enum type. + */ + function writeComplexCompilerOption(option: string, writeComma: boolean) { + writeOptionalOptionDescription(option); + + outer: switch (option) { + case "module": + var moduleValue: string; + switch (compilerOptions.module) { + case ModuleKind.None: + break outer; + case ModuleKind.CommonJS: + moduleValue = "commonjs"; + break; + case ModuleKind.System: + moduleValue = "system"; + break; + case ModuleKind.UMD: + moduleValue = "umd"; + break; + default: + moduleValue = "amd"; + break; + } + write(`"module": "${moduleValue}"`); + if (writeComma) { + write(","); + } + writeLine(); + break; + + case "target": + var targetValue: string; + switch (compilerOptions.target) { + case ScriptTarget.ES5: + targetValue = "es5"; + break; + case ScriptTarget.ES6: + targetValue = "es6"; + break; + default: + targetValue = "es3"; + break; + } + write(`"target": "${targetValue}"`); + if (writeComma) { + write(","); + } + writeLine(); + break; + + case "newLine": + var newlineValue: string; + switch (compilerOptions.newLine) { + case NewLineKind.CarriageReturnLineFeed: + newlineValue = "CRLF"; + break; + default: + newlineValue = "LF"; + break; + } + write(`"newLine": "${newlineValue}"`); + if (writeComma) { + write(","); + } + writeLine(); + break; + } + } + + function writeFileNames() { + write(`"files": [`); + writeLine(); + increaseIndent(); + + forEach(fileNames, (fileName, index) => { + write(`"${fileName}"`); + if (index < fileNames.length - 1) { + write(","); + } + writeLine(); + }); + + decreaseIndent(); + write("]"); + } + + function writeExcludeOptions() { + write(`"exclude": [`); + writeLine(); + increaseIndent(); + + forEach(excludes, (exclude, index) => { + write(`"${exclude}"`); + if (index < excludes.length - 1) { + write(","); + } + writeLine(); + }); + + decreaseIndent(); + write("]"); + } } export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 676538a6859..37f7c29097d 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -150,7 +150,9 @@ namespace ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.You_already_have_a_tsconfig_json_file_defined)); } else { - writeConfigFile(file, commandLine.options, commandLine.fileNames); + let writer = createTextWriter("\n"); + buildConfigFile(writer, compilerOptions, commandLine.fileNames, ["node_modules"]); + sys.writeFile(file, writer.getText()); } return sys.exit(ExitStatus.Success); } diff --git a/tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts b/tests/cases/unittests/jsonWithComments.ts similarity index 65% rename from tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts rename to tests/cases/unittests/jsonWithComments.ts index 2a3304e9bab..cf29e22ffcf 100644 --- a/tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts +++ b/tests/cases/unittests/jsonWithComments.ts @@ -32,30 +32,6 @@ module ts { }); }); - it("should parse JSON with trailing commas in an object @jsonWithCommentsAndTrailingCommas", () => { - let json = -`{ - "a": { - "b": true, - } -}`; - expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ - a: { b: true } - }); - }); - - it("should parse JSON with trailing commas in an array @jsonWithCommentsAndTrailingCommas", () => { - let json = -`{ - "a": [ - "b", - ] -}`; - expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ - a: [ "b" ] - }); - }); - it("should parse JSON with escape characters @jsonWithCommentsAndTrailingCommas", () => { let json = `{ diff --git a/tests/cases/unittests/projectInit.ts b/tests/cases/unittests/projectInit.ts index a0334c7ff16..ba3c80c03cd 100644 --- a/tests/cases/unittests/projectInit.ts +++ b/tests/cases/unittests/projectInit.ts @@ -1,6 +1,5 @@ /// -/// -/// +/// module ts { describe('Project initializer', () => { @@ -38,23 +37,36 @@ module ts { expectedOutput += expectedCompilerOptionOutput[option].toString() + ",\n"; } } + expectedOutput = expectedOutput.slice(0, expectedOutput.lastIndexOf(',')) + "\n"; expectedOutput += " }"; if (expectedFileNames) { expectedOutput += ",\n"; expectedOutput += ` "files": [\n`; - for (let fileName of expectedFileNames) { - expectedOutput += ` "${fileName}",\n`; - } + + forEach(expectedFileNames, (fileName, index) => { + expectedOutput += ` "${fileName}"`; + if (index < expectedFileNames.length - 1) { + expectedOutput += ","; + } + expectedOutput += "\n"; + }); + expectedOutput += " ]"; } if (excludes) { expectedOutput += ",\n"; expectedOutput += ` "exclude": [\n`; - for (let exclude of excludes) { - expectedOutput += ` "${exclude}",\n`; - } + + forEach(excludes, (exclude, index) => { + expectedOutput += ` "${exclude}"`; + if (index < excludes.length - 1) { + expectedOutput += ","; + } + expectedOutput += "\n"; + }); + expectedOutput += " ]"; } expectedOutput += "\n}"; @@ -70,7 +82,7 @@ module ts { { module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false, @@ -90,7 +102,7 @@ module ts { { module: "amd", // overrides commonjs target: "es5", // overrides es3 - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false, @@ -110,7 +122,7 @@ module ts { newLine: "CRLF", module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false, @@ -128,7 +140,7 @@ module ts { newLine: "LF", module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false, @@ -145,7 +157,7 @@ module ts { { module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false @@ -162,7 +174,7 @@ module ts { { module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false @@ -184,7 +196,7 @@ module ts { { module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", sourceMap: false @@ -206,10 +218,10 @@ module ts { { module: "commonjs", target: "es3", - noImplicitAny: true, + noImplicitAny: false, outDir: "built", rootDir: ".", - sourceMap: false + sourceMap: false, }, null, null);