From 684acffd19dba9d70fd063408e62da01dcdd562d Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 27 Jul 2015 19:52:25 +0800 Subject: [PATCH 01/74] Adds JSON with comments and trailing comma tests --- .../jsonWithCommentsAndTrailingCommas.ts | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts diff --git a/tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts b/tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts new file mode 100644 index 00000000000..2a3304e9bab --- /dev/null +++ b/tests/cases/unittests/jsonWithCommentsAndTrailingCommas.ts @@ -0,0 +1,72 @@ +/// +/// + +module ts { + describe("JSON with comments and trailing commas", () => { + it("should parse JSON with single line comments @jsonWithCommentsAndTrailingCommas", () => { + let json = +`{ + "a": { + // comment + "b": true + } +}`; + expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ + a: { b: true } + }); + }); + + + it("should parse JSON with multiline line comments @jsonWithCommentsAndTrailingCommas", () => { + let json = +`{ + "a": { + /* + * comment + */ + "b": true + } +}`; + expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ + a: { b: true } + }); + }); + + 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 = +`{ + "a": [ + "b\\\"\\\\", + ] +}`; + expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ + a: [ "b\"\\" ] + }); + }); + }); +} + From e3d3cc920fbf478d53e36806ffb4b87d2d32c5c0 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 27 Jul 2015 19:52:39 +0800 Subject: [PATCH 02/74] Adds project init tests --- tests/cases/unittests/projectInit.ts | 180 +++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 tests/cases/unittests/projectInit.ts diff --git a/tests/cases/unittests/projectInit.ts b/tests/cases/unittests/projectInit.ts new file mode 100644 index 00000000000..77ca3492819 --- /dev/null +++ b/tests/cases/unittests/projectInit.ts @@ -0,0 +1,180 @@ +/// +/// +/// + +module ts { + describe('Project initializer', () => { + interface ExpectedCompilerOptionsOutput { + [option: string]: string | boolean; + } + + function assertConfigFile( + compilerOptions: CompilerOptions, + fileNames: string[], + excludes: string[], + expectedCompilerOptionOutput: ExpectedCompilerOptionsOutput): void { + + let writer = createTextWriter("\n"); + let optionNameMap = getOptionNameMap().optionNameMap; + + buildConfigFile(writer, compilerOptions, fileNames, excludes); + + let expectedOutput = `{\n "compilerOptions": {\n`; + for (let option in expectedCompilerOptionOutput) { + let lowerCaseOption = option.toLowerCase() + if (optionNameMap[lowerCaseOption].description && + optionNameMap[lowerCaseOption].description.key) { + + expectedOutput += ` // ${optionNameMap[lowerCaseOption].description.key}\n`; + } + + expectedOutput += ` "${option}": `; + if (typeof expectedCompilerOptionOutput[option] === "string") { + expectedOutput += `"${expectedCompilerOptionOutput[option]}",\n`; + } + else { + expectedOutput += expectedCompilerOptionOutput[option].toString() + ",\n"; + } + } + expectedOutput += " }"; + + if (fileNames) { + expectedOutput += ",\n"; + expectedOutput += ` "files": [\n`; + for (let fileName of fileNames) { + expectedOutput += ` "${fileName}",\n`; + } + expectedOutput += " ]"; + } + + if (excludes) { + expectedOutput += ",\n"; + expectedOutput += ` "exclude": [\n`; + for (let exclude of excludes) { + expectedOutput += ` "${exclude}",\n`; + } + expectedOutput += " ]"; + } + expectedOutput += "\n}"; + + expect(writer.getText()).to.equal(expectedOutput); + } + + it("should generate default compiler options @projectInit", () => { + assertConfigFile( + {}, + null, + null, + { + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false, + }); + }); + + it("should override default compiler options @projectInit", () => { + assertConfigFile( + { + module: ModuleKind.AMD, + target: ScriptTarget.ES5, + }, + null, + null, + { + module: "amd", // overrides commonjs + target: "es5", // overrides es3 + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false, + }); + }); + + it("should be able to generate newline option @projectInit", () => { + assertConfigFile( + { + newLine: NewLineKind.CarriageReturnLineFeed + }, + null, + null, + { + newLine: "CRLF", + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false, + }); + + assertConfigFile( + { + newLine: NewLineKind.LineFeed + }, + null, + null, + { + newLine: "LF", + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false, + }); + }); + + it("should generate a `files` property @projectInit", () => { + assertConfigFile( + {}, + ["file1.ts", "file2.ts"], + null, + { + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false + }); + }); + + it("should generete exclude options @projectInit", () => { + assertConfigFile( + {}, + null, + ["node_modules"], + { + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false + }); + }); + + it("should not genereate compiler options for `version`, `watch`, `init` and `help` @projectInit", () => { + assertConfigFile( + { + version: true, + watch: true, + init: true, + help: true, + }, + null, + null, + { + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false + }); + }); + }); +} \ No newline at end of file From 38f4c2dc8dd3244859a135bbe92c32fa4ac723b7 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 27 Jul 2015 19:52:57 +0800 Subject: [PATCH 03/74] Adds project init --- Jakefile.js | 20 +- src/compiler/commandLineParser.ts | 138 +++++++- .../diagnosticInformationMap.generated.ts | 2 + src/compiler/diagnosticMessages.json | 10 +- src/compiler/emitter.ts | 312 ++++++++++++++---- src/compiler/program.ts | 6 + src/compiler/tsc.ts | 11 + src/compiler/types.ts | 12 +- 8 files changed, 422 insertions(+), 89 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 8fbefe1b2cc..e3f2e8c22c7 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -141,7 +141,9 @@ var harnessSources = harnessCoreSources.concat([ "session.ts", "versionCache.ts", "convertToBase64.ts", - "transpile.ts" + "transpile.ts", + "projectInit.ts", + "jsonWithCommentsAndTrailingCommas.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ @@ -339,10 +341,10 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], complete(); }); ex.run(); -}, {async: true}); +}, {async: true}); desc("Generates a diagnostic file in TypeScript based on an input JSON file"); -task("generate-diagnostics", [diagnosticInfoMapTs]); +task("generate-diagnostics", [diagnosticInfoMapTs]); // Publish nightly @@ -479,11 +481,11 @@ file(specMd, [word2mdJs, specWord], function () { child_process.exec(cmd, function () { complete(); }); -}, {async: true}); +}, {async: true}); desc("Generates a Markdown version of the Language Specification"); -task("generate-spec", [specMd]); +task("generate-spec", [specMd]); // Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory @@ -615,7 +617,7 @@ task("runtests", ["tests", builtLocalDirectory], function() { exec(cmd, deleteTemporaryProjectOutput); }, {async: true}); -desc("Generates code coverage data via instanbul"); +desc("Generates code coverage data via instanbul"); task("generate-code-coverage", ["tests", builtLocalDirectory], function () { var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; console.log(cmd); @@ -658,7 +660,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function( function getDiffTool() { var program = process.env['DIFF'] if (!program) { - fail("Add the 'DIFF' environment variable to the path of the program you want to use."); + fail("Add the 'DIFF' environment variable to the path of the program you want to use."); } return program; } @@ -667,14 +669,14 @@ function getDiffTool() { desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff', function () { var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline; - console.log(cmd); + console.log(cmd); exec(cmd); }, {async: true}); desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff-rwc', function () { var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline; - console.log(cmd); + console.log(cmd); exec(cmd); }, {async: true}); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ba7d8ca9ce3..6ba05473b7c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -30,6 +30,11 @@ namespace ts { type: "boolean", description: Diagnostics.Print_this_message, }, + { + name: "init", + type: "boolean", + description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, + }, { name: "inlineSourceMap", type: "boolean", @@ -221,19 +226,36 @@ namespace ts { } ]; - export function parseCommandLine(commandLine: string[]): ParsedCommandLine { - let options: CompilerOptions = {}; - let fileNames: string[] = []; - let errors: Diagnostic[] = []; - let shortOptionNames: Map = {}; - let optionNameMap: Map = {}; + export interface OptionNameMap { + optionNameMap: Map; + shortOptionNames: Map; + } + let optionNameMapCache: OptionNameMap; + export function getOptionNameMap(): OptionNameMap { + if (optionNameMapCache) { + return optionNameMapCache; + } + + let optionNameMap: Map = {}; + let shortOptionNames: Map = {}; forEach(optionDeclarations, option => { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { shortOptionNames[option.shortName] = option.name; } }); + + optionNameMapCache = { optionNameMap, shortOptionNames }; + return optionNameMapCache; + } + + export function parseCommandLine(commandLine: string[]): ParsedCommandLine { + let options: CompilerOptions = {}; + let fileNames: string[] = []; + let errors: Diagnostic[] = []; + let { optionNameMap, shortOptionNames } = getOptionNameMap(); + parseStrings(commandLine); return { options, @@ -345,6 +367,107 @@ namespace ts { return parseConfigFileText(fileName, text); } + /** + * Remove whitespace, comments and trailing commas from JSON text. + * @param text JSON text string. + */ + function stripJsonTrivia(text: string): string { + let ch: number; + let pos = 0; + let end = text.length - 1; + let result = ''; + let pendingCommaInsertion = false; + + while (pos <= end) { + ch = text.charCodeAt(pos); + + if(isWhiteSpace(ch) || isLineBreak(ch)) { + pos++; + 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.doubleQuote: + result += text[pos]; + pos++; + + while (pos <= end) { + ch = text.charCodeAt(pos); + if (ch === CharacterCodes.backslash) { + switch (text.charCodeAt(pos + 1)) { + case CharacterCodes.doubleQuote: + result += "\\\""; + pos += 2; + continue; + case CharacterCodes.backslash: + result += "\\\\"; + pos += 2; + continue; + } + pos++; + } + result += text[pos]; + + if (ch === CharacterCodes.doubleQuote) { + break; + } + + pos++; + } + break; + + default: + result += text[pos]; + } + + pos++; + } + return result; + } + /** * Parse the text of the tsconfig.json file * @param fileName The path to the config file @@ -352,6 +475,7 @@ namespace ts { */ export function parseConfigFileText(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } { try { + jsonText = stripJsonTrivia(jsonText); return { config: /\S/.test(jsonText) ? JSON.parse(jsonText) : {} }; } catch (e) { @@ -425,7 +549,7 @@ namespace ts { } else { let exclude = json["exclude"] instanceof Array ? map(json["exclude"], normalizeSlashes) : undefined; - let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude)); + let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude)); for (let i = 0; i < sysFiles.length; i++) { let name = sysFiles[i]; if (fileExtensionIs(name, ".d.ts")) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index ecea3a76673..c2fe4c57b21 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -517,6 +517,7 @@ namespace ts { Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, + You_already_have_a_tsconfig_json_file_defined: { code: 5052, category: DiagnosticCategory.Error, key: "You already have a tsconfig.json file defined." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -572,6 +573,7 @@ namespace ts { Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6069, category: DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2765d04f400..b59fb231374 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -161,7 +161,7 @@ }, "Type '{0}' is not a valid async function return type.": { "category": "Error", - "code": 1055 + "code": 1055 }, "Accessors are only available when targeting ECMAScript 5 and higher.": { "category": "Error", @@ -2057,6 +2057,10 @@ "category": "Error", "code": 5051 }, + "You already have a tsconfig.json file defined.": { + "category": "Error", + "code": 5052 + }, "Concatenate and emit output to single file.": { "category": "Message", @@ -2278,6 +2282,10 @@ "category": "Message", "code": 6068 }, + "Initializes a TypeScript project and creates a tsconfig.json file.": { + "category": "Message", + "code": 6069 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e97ece5bf00..8f1d39379dd 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3,6 +3,190 @@ /* @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) { + 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); } @@ -124,11 +308,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function emitJavaScript(jsFilePath: string, root?: SourceFile) { let writer = createTextWriter(newLine); - let write = writer.write; - let writeTextOfNode = writer.writeTextOfNode; - let writeLine = writer.writeLine; - let increaseIndent = writer.increaseIndent; - let decreaseIndent = writer.decreaseIndent; + let { write, writeTextOfNode, writeLine, increaseIndent, decreaseIndent } = writer; let currentSourceFile: SourceFile; // name of an exporter function if file is a System external module @@ -2070,7 +2250,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi emit(node.name); decreaseIndentIf(indentedBeforeDot, indentedAfterDot); } - + function emitQualifiedName(node: QualifiedName) { emit(node.left); write("."); @@ -2093,12 +2273,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi else { emitEntityNameAsExpression(node.left, /*useFallback*/ false); } - + write("."); emitNodeWithoutSourceMap(node.right); } - - function emitEntityNameAsExpression(node: EntityName, useFallback: boolean) { + + function emitEntityNameAsExpression(node: EntityName, useFallback: boolean) { switch (node.kind) { case SyntaxKind.Identifier: if (useFallback) { @@ -2106,10 +2286,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi emitExpressionIdentifier(node); write(" !== 'undefined' && "); } - + emitExpressionIdentifier(node); break; - + case SyntaxKind.QualifiedName: emitQualifiedNameAsExpression(node, useFallback); break; @@ -3020,7 +3200,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (compilerOptions.module === ModuleKind.CommonJS || compilerOptions.module === ModuleKind.AMD || compilerOptions.module === ModuleKind.UMD) { if (!currentSourceFile.symbol.exports["___esModule"]) { if (languageVersion === ScriptTarget.ES5) { - // default value of configurable, enumerable, writable are `false`. + // default value of configurable, enumerable, writable are `false`. write("Object.defineProperty(exports, \"__esModule\", { value: true });"); writeLine(); } @@ -4250,7 +4430,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (ctor) { // Emit all the directive prologues (like "use strict"). These have to come before // any other preamble code we write (like parameter initializers). - startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true); + startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true); emitDetachedComments(ctor.body.statements); } emitCaptureThisForNodeIfNecessary(node); @@ -4821,7 +5001,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } return false; } - + /** Serializes the type of a declaration to an appropriate JS constructor value. Used by the __metadata decorator for a class member. */ function emitSerializedTypeOfNode(node: Node) { // serialization of the type of a declaration uses the following rules: @@ -4832,39 +5012,39 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // * The serialized type of an AccessorDeclaration is the serialized type of the return type annotation of its getter or parameter type annotation of its setter. // * The serialized type of any other FunctionLikeDeclaration is "Function". // * The serialized type of any other node is "void 0". - // + // // For rules on serializing type annotations, see `serializeTypeNode`. switch (node.kind) { case SyntaxKind.ClassDeclaration: write("Function"); return; - - case SyntaxKind.PropertyDeclaration: + + case SyntaxKind.PropertyDeclaration: emitSerializedTypeNode((node).type); return; - - case SyntaxKind.Parameter: + + case SyntaxKind.Parameter: emitSerializedTypeNode((node).type); return; - - case SyntaxKind.GetAccessor: + + case SyntaxKind.GetAccessor: emitSerializedTypeNode((node).type); return; - - case SyntaxKind.SetAccessor: + + case SyntaxKind.SetAccessor: emitSerializedTypeNode(getSetAccessorTypeAnnotationNode(node)); return; - + } - + if (isFunctionLike(node)) { write("Function"); return; } - + write("void 0"); } - + function emitSerializedTypeNode(node: TypeNode) { switch (node.kind) { case SyntaxKind.VoidKeyword: @@ -4874,17 +5054,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi case SyntaxKind.ParenthesizedType: emitSerializedTypeNode((node).type); return; - + case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: write("Function"); return; - + case SyntaxKind.ArrayType: case SyntaxKind.TupleType: write("Array"); return; - + case SyntaxKind.TypePredicate: case SyntaxKind.BooleanKeyword: write("Boolean"); @@ -4894,11 +5074,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi case SyntaxKind.StringLiteral: write("String"); return; - + case SyntaxKind.NumberKeyword: write("Number"); return; - + case SyntaxKind.SymbolKeyword: write("Symbol"); return; @@ -4906,22 +5086,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi case SyntaxKind.TypeReference: emitSerializedTypeReferenceNode(node); return; - + case SyntaxKind.TypeQuery: case SyntaxKind.TypeLiteral: case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: case SyntaxKind.AnyKeyword: break; - + default: Debug.fail("Cannot serialize unexpected type node."); break; } - + write("Object"); } - + /** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */ function emitSerializedTypeReferenceNode(node: TypeReferenceNode) { let typeName = node.typeName; @@ -4941,27 +5121,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue: emitEntityNameAsExpression(typeName, /*useFallback*/ false); break; - + case TypeReferenceSerializationKind.VoidType: write("void 0"); break; - + case TypeReferenceSerializationKind.BooleanType: write("Boolean"); break; - + case TypeReferenceSerializationKind.NumberLikeType: write("Number"); break; - + case TypeReferenceSerializationKind.StringLikeType: write("String"); break; - + case TypeReferenceSerializationKind.ArrayLikeType: write("Array"); break; - + case TypeReferenceSerializationKind.ESSymbolType: if (languageVersion < ScriptTarget.ES6) { write("typeof Symbol === 'function' ? Symbol : Object"); @@ -4970,24 +5150,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi write("Symbol"); } break; - + case TypeReferenceSerializationKind.TypeWithCallSignature: write("Function"); break; - + case TypeReferenceSerializationKind.ObjectType: write("Object"); break; } } - + /** Serializes the parameter types of a function or the constructor of a class. Used by the __metadata decorator for a method or set accessor. */ function emitSerializedParameterTypesOfNode(node: Node) { // serialization of parameter types uses the following rules: // // * If the declaration is a class, the parameters of the first constructor with a body are used. // * If the declaration is function-like and has a body, the parameters of the function are used. - // + // // For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`. if (node) { var valueDeclaration: FunctionLikeDeclaration; @@ -4997,7 +5177,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi else if (isFunctionLike(node) && nodeIsPresent((node).body)) { valueDeclaration = node; } - + if (valueDeclaration) { var parameters = valueDeclaration.parameters; var parameterCount = parameters.length; @@ -5006,7 +5186,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (i > 0) { write(", "); } - + if (parameters[i].dotDotDotToken) { var parameterType = parameters[i].type; if (parameterType.kind === SyntaxKind.ArrayType) { @@ -5018,7 +5198,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi else { parameterType = undefined; } - + emitSerializedTypeNode(parameterType); } else { @@ -5029,18 +5209,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } } - + /** Serializes the return type of function. Used by the __metadata decorator for a method. */ function emitSerializedReturnTypeOfNode(node: Node): string | string[] { if (node && isFunctionLike(node)) { emitSerializedTypeNode((node).type); return; } - + write("void 0"); } - - + + function emitSerializedTypeMetadata(node: Declaration, writeComma: boolean): number { // This method emits the serialized type metadata for a decorator target. // The caller should have already tested whether the node has decorators. @@ -5070,7 +5250,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (writeComma || argumentsWritten) { write(", "); } - + writeLine(); write("__metadata('design:returntype', "); emitSerializedReturnTypeOfNode(node); @@ -5078,10 +5258,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi argumentsWritten++; } } - + return argumentsWritten; } - + function emitInterfaceDeclaration(node: InterfaceDeclaration) { emitOnlyPinnedOrTripleSlashComments(node); } @@ -5430,18 +5610,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi (!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) { emitLeadingComments(node); emitStart(node); - + // variable declaration for import-equals declaration can be hoisted in system modules // in this case 'var' should be omitted and emit should contain only initialization let variableDeclarationIsHoisted = shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true); - + // is it top level export import v = a.b.c in system module? // if yes - it needs to be rewritten as exporter('v', v = a.b.c) let isExported = isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ true); - + if (!variableDeclarationIsHoisted) { Debug.assert(!isExported); - + if (isES6ExportedDeclaration(node)) { write("export "); write("var "); @@ -5450,8 +5630,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi write("var "); } } - - + + if (isExported) { write(`${exportFunctionForFile}("`); emitNodeWithoutSourceMap(node.name); @@ -5465,8 +5645,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (isExported) { write(")"); } - - write(";"); + + write(";"); emitEnd(node); emitExportImportAssignments(node); emitTrailingComments(node); @@ -5992,12 +6172,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } return; } - + if (isInternalModuleImportEqualsDeclaration(node)) { if (!hoistedVars) { hoistedVars = []; } - + hoistedVars.push(node.name); return; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 4b1f10eb649..ce6dac19f91 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -26,6 +26,12 @@ 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 function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { let currentDirectory: string; let existingDirectories: Map = {}; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index a657cc8c314..676538a6859 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -144,6 +144,17 @@ namespace ts { let hostGetSourceFile: typeof compilerHost.getSourceFile; // getSourceFile method from default host let timerHandle: number; // Handle for 0.25s wait timer + if (commandLine.options.init) { + let file = `${sys.getCurrentDirectory()}/tsconfig.json`; + if (sys.fileExists(file)) { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.You_already_have_a_tsconfig_json_file_defined)); + } + else { + writeConfigFile(file, commandLine.options, commandLine.fileNames); + } + return sys.exit(ExitStatus.Success); + } + if (commandLine.options.locale) { if (!isJSONSupported()) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale")); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 21eed30c244..7735f84c74d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1529,8 +1529,8 @@ namespace ts { export interface SymbolAccessiblityResult extends SymbolVisibilityResult { errorModuleName?: string; // If the symbol is not visible from module, module's name } - - /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator + + /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator * metadata */ /* @internal */ export enum TypeReferenceSerializationKind { @@ -1574,7 +1574,7 @@ namespace ts { getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; getBlockScopedVariableId(node: Identifier): number; getReferencedValueDeclaration(reference: Identifier): Declaration; - getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind; + getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind; } export const enum SymbolFlags { @@ -1777,10 +1777,10 @@ namespace ts { StringLike = String | StringLiteral, NumberLike = Number | Enum, ObjectType = Class | Interface | Reference | Tuple | Anonymous, - UnionOrIntersection = Union | Intersection, + UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral } // Properties common to all types @@ -1989,6 +1989,7 @@ namespace ts { diagnostics?: boolean; emitBOM?: boolean; help?: boolean; + init?: boolean; inlineSourceMap?: boolean; inlineSources?: boolean; jsx?: JsxEmit; @@ -2073,7 +2074,6 @@ namespace ts { errors: Diagnostic[]; } - /* @internal */ export interface CommandLineOption { name: string; type: string | Map; // "string", "number", "boolean", or an object literal mapping named values to actual values From 5daf3f11018c239c2e479818d7cdc9085d43de81 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 27 Jul 2015 20:18:21 +0800 Subject: [PATCH 04/74] Defaults to no files property --- src/compiler/emitter.ts | 2 +- tests/cases/unittests/projectInit.ts | 62 ++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8f1d39379dd..46a44d7b268 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -23,7 +23,7 @@ namespace ts { writeLine(); increaseIndent(); writeCompilerOptions(); - if (fileNames) { + if (fileNames && fileNames.length > 0) { write(","); writeLine(); writeFileNames(); diff --git a/tests/cases/unittests/projectInit.ts b/tests/cases/unittests/projectInit.ts index 77ca3492819..a0334c7ff16 100644 --- a/tests/cases/unittests/projectInit.ts +++ b/tests/cases/unittests/projectInit.ts @@ -12,7 +12,9 @@ module ts { compilerOptions: CompilerOptions, fileNames: string[], excludes: string[], - expectedCompilerOptionOutput: ExpectedCompilerOptionsOutput): void { + expectedCompilerOptionOutput: ExpectedCompilerOptionsOutput, + expectedFileNames: string[], + expectedExcludes: string[]): void { let writer = createTextWriter("\n"); let optionNameMap = getOptionNameMap().optionNameMap; @@ -38,10 +40,10 @@ module ts { } expectedOutput += " }"; - if (fileNames) { + if (expectedFileNames) { expectedOutput += ",\n"; expectedOutput += ` "files": [\n`; - for (let fileName of fileNames) { + for (let fileName of expectedFileNames) { expectedOutput += ` "${fileName}",\n`; } expectedOutput += " ]"; @@ -72,7 +74,9 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false, - }); + }, + null, + null); }); it("should override default compiler options @projectInit", () => { @@ -90,7 +94,9 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false, - }); + }, + null, + null); }); it("should be able to generate newline option @projectInit", () => { @@ -108,7 +114,9 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false, - }); + }, + null, + null); assertConfigFile( { @@ -124,7 +132,9 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false, - }); + }, + null, + null); }); it("should generate a `files` property @projectInit", () => { @@ -139,10 +149,12 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false - }); + }, + ["file1.ts", "file2.ts"], + null); }); - it("should generete exclude options @projectInit", () => { + it("should generate exclude options @projectInit", () => { assertConfigFile( {}, null, @@ -154,10 +166,12 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false - }); + }, + null, + ["node_modules"]); }); - it("should not genereate compiler options for `version`, `watch`, `init` and `help` @projectInit", () => { + it("should not generate compiler options for `version`, `watch`, `init` and `help` @projectInit", () => { assertConfigFile( { version: true, @@ -174,7 +188,31 @@ module ts { outDir: "built", rootDir: ".", sourceMap: false - }); + }, + null, + null); + }); + + it("should not generate a files property if the files length is zero @projectInit", () => { + assertConfigFile( + { + version: true, + watch: true, + init: true, + help: true, + }, + [], + null, + { + module: "commonjs", + target: "es3", + noImplicitAny: true, + outDir: "built", + rootDir: ".", + sourceMap: false + }, + null, + null); }); }); } \ No newline at end of file From db6e46df120bbec4fa9325315e5887e1d256143a Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Wed, 29 Jul 2015 10:26:18 +0800 Subject: [PATCH 05/74] 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); From 07fb139326c2040f72587f736ddcbf14bf024462 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Wed, 29 Jul 2015 10:32:33 +0800 Subject: [PATCH 06/74] Adds success message for tsconfig.json init --- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/tsc.ts | 1 + 3 files changed, 6 insertions(+) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index c2fe4c57b21..49ca79b0f1e 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -574,6 +574,7 @@ namespace ts { Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6069, category: DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, + Successfully_created_a_tsconfig_json_file: { code: 6070, category: DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b59fb231374..78ffb2da1c8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2286,6 +2286,10 @@ "category": "Message", "code": 6069 }, + "Successfully created a tsconfig.json file.": { + "category": "Message", + "code": 6070 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 37f7c29097d..e026732bc2c 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -153,6 +153,7 @@ namespace ts { let writer = createTextWriter("\n"); buildConfigFile(writer, compilerOptions, commandLine.fileNames, ["node_modules"]); sys.writeFile(file, writer.getText()); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); } return sys.exit(ExitStatus.Success); } From c57adeda1f32b9bd95f44316113e5bc99460baac Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 15 Aug 2015 17:02:08 -0700 Subject: [PATCH 07/74] Fix null reference in type parametr of type alias --- src/services/services.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index bfee19b3a6a..78aeb4bfeea 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4076,16 +4076,19 @@ namespace ts { } else { // Method/function type parameter - let signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; - let signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) { - displayParts.push(keywordPart(SyntaxKind.NewKeyword)); - displayParts.push(spacePart()); + let container = getContainingFunction(location); + if (container) { + let signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; + let signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) { + displayParts.push(keywordPart(SyntaxKind.NewKeyword)); + displayParts.push(spacePart()); + } + else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } - else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } } if (symbolFlags & SymbolFlags.EnumMember) { From abc96936b52ad35a086348873fc76eb24e984e39 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 10:48:36 -0700 Subject: [PATCH 08/74] Do not show completions in type parameter of type alias --- src/services/services.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/services.ts b/src/services/services.ts index 78aeb4bfeea..878d81fe195 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3492,6 +3492,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< | + containingNodeKind === SyntaxKind.TypeAliasDeclaration || isFunction(containingNodeKind); case SyntaxKind.StaticKeyword: From ab20cf9f141c9d5bdc28eb3bb0ddf7ff9add07de Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 22:02:05 -0700 Subject: [PATCH 09/74] Add test for completion in type parater of type alias --- ...mpletionListInTypeParameterOfTypeAlias1.ts | 18 ++++++++++++++++ ...mpletionListInTypeParameterOfTypeAlias2.ts | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts new file mode 100644 index 00000000000..ec20cdb409f --- /dev/null +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts @@ -0,0 +1,18 @@ +/// + +////type List1 = T[]; +////type List4 = /*2*/T[]; +////type List3 = /*3*/; + +/*goTo.marker("0"); +verify.completionListIsEmpty(); +goTo.marker("1"); +verify.not.completionListIsEmpty(); +goTo.marker("2"); +verify.completionListContains("T"); +*/ +goTo.marker("3"); +verify.not.completionListIsEmpty(); +verify.not.completionListContains("T"); +verify.completionListContains("T1"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts new file mode 100644 index 00000000000..e804fb8946a --- /dev/null +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts @@ -0,0 +1,21 @@ +/// + +////type Map1 = []; +////type Map1 = /*2*/[]; +////type Map1 = Date: Mon, 17 Aug 2015 22:02:45 -0700 Subject: [PATCH 10/74] Add comment and prevent completion in type paramter of class expression --- src/services/services.ts | 7 +++++-- ...letionListInTypeParameterOfClassExpression1.ts | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts diff --git a/src/services/services.ts b/src/services/services.ts index 878d81fe195..9c00b92a063 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3460,9 +3460,11 @@ namespace ts { containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, | isFunction(containingNodeKind) || containingNodeKind === SyntaxKind.ClassDeclaration || // class A + +////var C0 = class D {} +////var C3 = class D{} + +goTo.marker("0"); +verify.completionListIsEmpty(); +goTo.marker("1"); +verify.completionListIsEmpty(); +goTo.marker("2"); +verify.completionListIsEmpty(); +goTo.marker("3"); +verify.completionListIsEmpty(); \ No newline at end of file From bef4e8d58e8ce09bd6629d6e302edcb0f0cf7db0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 22:04:54 -0700 Subject: [PATCH 11/74] remove commented test --- .../fourslash/completionListInTypeParameterOfTypeAlias1.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts index ec20cdb409f..e6017eedbfc 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts @@ -5,13 +5,12 @@ ////type List4 = /*2*/T[]; ////type List3 = /*3*/; -/*goTo.marker("0"); +goTo.marker("0"); verify.completionListIsEmpty(); goTo.marker("1"); verify.not.completionListIsEmpty(); goTo.marker("2"); verify.completionListContains("T"); -*/ goTo.marker("3"); verify.not.completionListIsEmpty(); verify.not.completionListContains("T"); From ed1383842c49ad5f917b3cef61fcd5863cd27df8 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:38:08 -0700 Subject: [PATCH 12/74] Fix space --- src/compiler/utilities.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 70d17e4290b..e1f5d31b26c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -385,7 +385,10 @@ namespace ts { } export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) { - let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ? concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos), getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) : getLeadingCommentRangesOfNode(node, sourceFileOfNode); + let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ? + concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos), + getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) : + getLeadingCommentRangesOfNode(node, sourceFileOfNode); return filter(commentRanges, isJsDocComment); function isJsDocComment(comment: CommentRange) { From 4c44de6c5f438e5c84b792e71f2ac98941818cd0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:38:36 -0700 Subject: [PATCH 13/74] Write out type parameter in type alias in quick-info --- src/compiler/checker.ts | 2 +- src/services/services.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b5b4eb9e748..ba43bc585f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1902,7 +1902,7 @@ namespace ts { function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags) { let targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface) { + if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface || targetSymbol.flags & SymbolFlags.TypeAlias) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } diff --git a/src/services/services.ts b/src/services/services.ts index 9c00b92a063..14374e58192 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4040,6 +4040,7 @@ namespace ts { displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); displayParts.push(spacePart()); @@ -4093,6 +4094,16 @@ namespace ts { } addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + let declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; + displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); + displayParts.push(spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); + } } } if (symbolFlags & SymbolFlags.EnumMember) { From dddc76b15675621d6996a45549f386a5a8630831 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:39:36 -0700 Subject: [PATCH 14/74] Add quick info test for type parameter in type alias --- ...nfoDisplayPartsTypeParameterInTypeAlias.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts diff --git a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts new file mode 100644 index 00000000000..1bec6868e95 --- /dev/null +++ b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts @@ -0,0 +1,22 @@ +/// + +////type /*0*/List = /*2*/T[] + +type L = T[] +let typeAliashDisplayParts = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List", kind: "aliasName" }, + { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: ">", kind: "punctuation" }]; +let typeParameterDisplayParts = [{ text: "(", kind: "punctuation" }, { text: "type parameter", kind: "text" }, { text: ")", kind: "punctuation" }, { text: " ", kind: "space" }, + { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "in", kind: "keyword" }, { text: " ", kind: "space" } ] + +goTo.marker('0'); +verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("0").position, length: "List".length }, + typeAliashDisplayParts.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, + { text: "[", kind: "punctuation" }, { text: "]", kind: "punctuation" }]), []); + +goTo.marker('1'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("1").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts), []); + +goTo.marker('2'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("2").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts), []); From bb7a132b0e6669e362bc069ce37fdbaf383624e9 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 20 Aug 2015 09:25:02 -0700 Subject: [PATCH 15/74] Address code review --- src/services/services.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 14374e58192..ea667936146 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3493,7 +3493,6 @@ namespace ts { case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | containingNodeKind === SyntaxKind.ClassExpression || // var C = class D< | - containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< | containingNodeKind === SyntaxKind.TypeAliasDeclaration || // type List< | isFunction(containingNodeKind); From 963ba1918e49e5469a3915832e2de57149bf47c6 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 25 Aug 2015 15:05:02 +0800 Subject: [PATCH 16/74] Addresses CR feedback --- src/compiler/commandLineParser.ts | 88 --------- src/compiler/core.ts | 10 +- src/compiler/program.ts | 227 +++------------------- src/compiler/tsc.ts | 59 ++++-- tests/cases/unittests/jsonWithComments.ts | 48 ----- 5 files changed, 78 insertions(+), 354 deletions(-) delete mode 100644 tests/cases/unittests/jsonWithComments.ts diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 38faf0a43fb..d5ab9022b3e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -367,93 +367,6 @@ namespace ts { return parseConfigFileText(fileName, text); } - /** - * Remove whitespace, comments and trailing commas from JSON text. - * @param text JSON text string. - */ - function stripJsonTrivia(text: string): string { - let ch: number; - let pos = 0; - let end = text.length - 1; - let result = ''; - let pendingCommaInsertion = false; - - while (pos <= end) { - ch = text.charCodeAt(pos); - - if(isWhiteSpace(ch) || isLineBreak(ch)) { - pos++; - continue; - } - - switch (ch) { - 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]; - pos++; - - while (pos <= end) { - ch = text.charCodeAt(pos); - if (ch === CharacterCodes.backslash) { - switch (text.charCodeAt(pos + 1)) { - case CharacterCodes.doubleQuote: - result += "\\\""; - pos += 2; - continue; - case CharacterCodes.backslash: - result += "\\\\"; - pos += 2; - continue; - } - pos++; - } - result += text[pos]; - - if (ch === CharacterCodes.doubleQuote) { - break; - } - - pos++; - } - break; - - default: - result += text[pos]; - } - - pos++; - } - return result; - } - /** * Parse the text of the tsconfig.json file * @param fileName The path to the config file @@ -461,7 +374,6 @@ namespace ts { */ export function parseConfigFileText(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } { try { - jsonText = stripJsonTrivia(jsonText); return { config: /\S/.test(jsonText) ? JSON.parse(jsonText) : {} }; } catch (e) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ec171d4aee2..61232696697 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -275,14 +275,14 @@ namespace ts { return result; } - export function extend(first: Map, second: Map): Map { - let result: Map = {}; + export function extend(first: Map, second: Map): Map { + let result: Map = {}; for (let id in first) { - result[id] = first[id]; + (result as any)[id] = first[id]; } for (let id in second) { if (!hasProperty(result, id)) { - result[id] = second[id]; + (result as any)[id] = second[id]; } } return result; @@ -805,4 +805,4 @@ namespace ts { Debug.assert(false, message); } } -} +} diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 70b89db4eaf..a749e0e4ad6 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -36,209 +36,38 @@ namespace ts { 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("}"); + export function scriptTargetToString(target: ScriptTarget): string { + switch (target) { + case ScriptTarget.ES5: + return "es5"; + case ScriptTarget.ES6: + return "es6"; + default: + return "es3"; } + } - 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("}"); + export function moduleKindToString(kind: ModuleKind): string { + switch (kind) { + case ModuleKind.None: + return undefined; + case ModuleKind.CommonJS: + return "commonjs"; + case ModuleKind.System: + return "system"; + case ModuleKind.UMD: + return "umd"; + default: + return "amd"; } + } - 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 newLineKindToString(kind: NewLineKind): string { + switch (kind) { + case NewLineKind.CarriageReturnLineFeed: + return "CRLF"; + default: + return "LF"; } } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index e026732bc2c..bc7aa67b939 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -144,20 +144,6 @@ namespace ts { let hostGetSourceFile: typeof compilerHost.getSourceFile; // getSourceFile method from default host let timerHandle: number; // Handle for 0.25s wait timer - if (commandLine.options.init) { - let file = `${sys.getCurrentDirectory()}/tsconfig.json`; - if (sys.fileExists(file)) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.You_already_have_a_tsconfig_json_file_defined)); - } - else { - let writer = createTextWriter("\n"); - buildConfigFile(writer, compilerOptions, commandLine.fileNames, ["node_modules"]); - sys.writeFile(file, writer.getText()); - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); - } - return sys.exit(ExitStatus.Success); - } - if (commandLine.options.locale) { if (!isJSONSupported()) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale")); @@ -173,6 +159,51 @@ namespace ts { return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped); } + if (commandLine.options.init) { + let file = combinePaths(sys.getCurrentDirectory(), 'tsconfig.json'); + if (sys.fileExists(file)) { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.You_already_have_a_tsconfig_json_file_defined)); + } + else { + let compilerOptions = extend(commandLine.options, defaultInitCompilerOptions); + let configs = { + compilerOptions, + files: commandLine.fileNames, + exclude: ["node_modules"] + }; + sys.writeFile(file, JSON.stringify(configs, (k, v) => { + if (k === "compilerOptions") { + let options: CompilerOptions = v; + for (let o in options) { + switch (o) { + case "target": + options[o] = scriptTargetToString(options[o] as ScriptTarget); + continue; + case "module": + options[o] = moduleKindToString(options[o] as ModuleKind); + continue; + case "newLine": + options[o] = newLineKindToString(options[o] as NewLineKind); + continue; + case "init": + case "watch": + case "version": + case "help": + delete options[o]; + continue; + } + } + + return options; + } + + return v; + }, 4)); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); + } + return sys.exit(ExitStatus.Success); + } + if (commandLine.options.version) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.Version_0, ts.version)); return sys.exit(ExitStatus.Success); diff --git a/tests/cases/unittests/jsonWithComments.ts b/tests/cases/unittests/jsonWithComments.ts deleted file mode 100644 index cf29e22ffcf..00000000000 --- a/tests/cases/unittests/jsonWithComments.ts +++ /dev/null @@ -1,48 +0,0 @@ -/// -/// - -module ts { - describe("JSON with comments and trailing commas", () => { - it("should parse JSON with single line comments @jsonWithCommentsAndTrailingCommas", () => { - let json = -`{ - "a": { - // comment - "b": true - } -}`; - expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ - a: { b: true } - }); - }); - - - it("should parse JSON with multiline line comments @jsonWithCommentsAndTrailingCommas", () => { - let json = -`{ - "a": { - /* - * comment - */ - "b": true - } -}`; - expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ - a: { b: true } - }); - }); - - it("should parse JSON with escape characters @jsonWithCommentsAndTrailingCommas", () => { - let json = -`{ - "a": [ - "b\\\"\\\\", - ] -}`; - expect(parseConfigFileText("file.ts", json).config).to.be.deep.equal({ - a: [ "b\"\\" ] - }); - }); - }); -} - From 075cd1249fbe55339e72379e90634782a79b74e0 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 25 Aug 2015 15:31:14 +0800 Subject: [PATCH 17/74] Removes jsonWithComments --- Jakefile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 4f922dd3ab8..c67277405f8 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -142,8 +142,7 @@ var harnessSources = harnessCoreSources.concat([ "versionCache.ts", "convertToBase64.ts", "transpile.ts", - "projectInit.ts", - "jsonWithComments.ts" + "projectInit.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ From 1670ce9664ed914ba2cd7c172caf8fe905261a81 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 25 Aug 2015 15:43:10 +0800 Subject: [PATCH 18/74] Removes project init test --- Jakefile.js | 3 +- tests/cases/unittests/projectInit.ts | 230 --------------------------- 2 files changed, 1 insertion(+), 232 deletions(-) delete mode 100644 tests/cases/unittests/projectInit.ts diff --git a/Jakefile.js b/Jakefile.js index c67277405f8..c4a8121d037 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -141,8 +141,7 @@ var harnessSources = harnessCoreSources.concat([ "session.ts", "versionCache.ts", "convertToBase64.ts", - "transpile.ts", - "projectInit.ts" + "transpile.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/tests/cases/unittests/projectInit.ts b/tests/cases/unittests/projectInit.ts deleted file mode 100644 index ba3c80c03cd..00000000000 --- a/tests/cases/unittests/projectInit.ts +++ /dev/null @@ -1,230 +0,0 @@ -/// -/// - -module ts { - describe('Project initializer', () => { - interface ExpectedCompilerOptionsOutput { - [option: string]: string | boolean; - } - - function assertConfigFile( - compilerOptions: CompilerOptions, - fileNames: string[], - excludes: string[], - expectedCompilerOptionOutput: ExpectedCompilerOptionsOutput, - expectedFileNames: string[], - expectedExcludes: string[]): void { - - let writer = createTextWriter("\n"); - let optionNameMap = getOptionNameMap().optionNameMap; - - buildConfigFile(writer, compilerOptions, fileNames, excludes); - - let expectedOutput = `{\n "compilerOptions": {\n`; - for (let option in expectedCompilerOptionOutput) { - let lowerCaseOption = option.toLowerCase() - if (optionNameMap[lowerCaseOption].description && - optionNameMap[lowerCaseOption].description.key) { - - expectedOutput += ` // ${optionNameMap[lowerCaseOption].description.key}\n`; - } - - expectedOutput += ` "${option}": `; - if (typeof expectedCompilerOptionOutput[option] === "string") { - expectedOutput += `"${expectedCompilerOptionOutput[option]}",\n`; - } - else { - expectedOutput += expectedCompilerOptionOutput[option].toString() + ",\n"; - } - } - expectedOutput = expectedOutput.slice(0, expectedOutput.lastIndexOf(',')) + "\n"; - expectedOutput += " }"; - - if (expectedFileNames) { - expectedOutput += ",\n"; - expectedOutput += ` "files": [\n`; - - forEach(expectedFileNames, (fileName, index) => { - expectedOutput += ` "${fileName}"`; - if (index < expectedFileNames.length - 1) { - expectedOutput += ","; - } - expectedOutput += "\n"; - }); - - expectedOutput += " ]"; - } - - if (excludes) { - expectedOutput += ",\n"; - expectedOutput += ` "exclude": [\n`; - - forEach(excludes, (exclude, index) => { - expectedOutput += ` "${exclude}"`; - if (index < excludes.length - 1) { - expectedOutput += ","; - } - expectedOutput += "\n"; - }); - - expectedOutput += " ]"; - } - expectedOutput += "\n}"; - - expect(writer.getText()).to.equal(expectedOutput); - } - - it("should generate default compiler options @projectInit", () => { - assertConfigFile( - {}, - null, - null, - { - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false, - }, - null, - null); - }); - - it("should override default compiler options @projectInit", () => { - assertConfigFile( - { - module: ModuleKind.AMD, - target: ScriptTarget.ES5, - }, - null, - null, - { - module: "amd", // overrides commonjs - target: "es5", // overrides es3 - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false, - }, - null, - null); - }); - - it("should be able to generate newline option @projectInit", () => { - assertConfigFile( - { - newLine: NewLineKind.CarriageReturnLineFeed - }, - null, - null, - { - newLine: "CRLF", - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false, - }, - null, - null); - - assertConfigFile( - { - newLine: NewLineKind.LineFeed - }, - null, - null, - { - newLine: "LF", - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false, - }, - null, - null); - }); - - it("should generate a `files` property @projectInit", () => { - assertConfigFile( - {}, - ["file1.ts", "file2.ts"], - null, - { - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false - }, - ["file1.ts", "file2.ts"], - null); - }); - - it("should generate exclude options @projectInit", () => { - assertConfigFile( - {}, - null, - ["node_modules"], - { - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false - }, - null, - ["node_modules"]); - }); - - it("should not generate compiler options for `version`, `watch`, `init` and `help` @projectInit", () => { - assertConfigFile( - { - version: true, - watch: true, - init: true, - help: true, - }, - null, - null, - { - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false - }, - null, - null); - }); - - it("should not generate a files property if the files length is zero @projectInit", () => { - assertConfigFile( - { - version: true, - watch: true, - init: true, - help: true, - }, - [], - null, - { - module: "commonjs", - target: "es3", - noImplicitAny: false, - outDir: "built", - rootDir: ".", - sourceMap: false, - }, - null, - null); - }); - }); -} \ No newline at end of file From c0a87e9947e48399d38ea5b0184299a0526ad99d Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Wed, 26 Aug 2015 02:01:33 +0900 Subject: [PATCH 19/74] fixing function type formatting --- src/services/formatting/smartIndenter.ts | 1 + tests/cases/fourslash/formattingFunctionType.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/cases/fourslash/formattingFunctionType.ts diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index c7f762fea64..30da55b8f37 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -429,6 +429,7 @@ namespace ts.formatting { case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxElement: + case SyntaxKind.FunctionType: return true; } return false; diff --git a/tests/cases/fourslash/formattingFunctionType.ts b/tests/cases/fourslash/formattingFunctionType.ts new file mode 100644 index 00000000000..0e63292b5ed --- /dev/null +++ b/tests/cases/fourslash/formattingFunctionType.ts @@ -0,0 +1,17 @@ +/// + +////function renderElement( +//// element: Element, +//// renderNode: ( +//// node: Node/*paramInFuntionType*/ +/////*paramIndent*/ +//// ) => void +////): void { +////} + +format.document(); + +goTo.marker("paramInFuntionType"); +verify.currentLineContentIs(" node: Node"); +goTo.marker("paramIndent"); +verify.indentationIs(8); \ No newline at end of file From 9ed51c6399135b4d6746678d202170171632efaa Mon Sep 17 00:00:00 2001 From: zhengbli Date: Tue, 25 Aug 2015 12:16:31 -0700 Subject: [PATCH 20/74] Fix inconsistent line endings in lib.d.ts --- src/lib/dom.generated.d.ts | 2 +- src/lib/webworker.generated.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 19907d2edf9..9f857276d1a 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -12961,4 +12961,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any, declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 900c7e538ec..eef668d7745 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -967,4 +967,4 @@ declare function postMessage(data: any): void; declare var console: Console; declare function addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; declare function addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file From 13815442fe2027191dc816963ddbbc5b7eda8291 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Aug 2015 14:07:49 -0700 Subject: [PATCH 21/74] Update version to 1.7 in 'master'. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 166b73b4a9c..9ec67593c90 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "1.6.0", + "version": "1.7.0", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ From b85665cd38d437d842188fb2042e63c1c8bdc93b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 14:34:34 -0700 Subject: [PATCH 22/74] Make new exported functions internal --- src/compiler/commandLineParser.ts | 2 ++ src/compiler/program.ts | 4 ++++ src/compiler/types.ts | 1 + 3 files changed, 7 insertions(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index fa2826598ad..1f57c142113 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -242,12 +242,14 @@ namespace ts { } ]; + /* @internal */ export interface OptionNameMap { optionNameMap: Map; shortOptionNames: Map; } let optionNameMapCache: OptionNameMap; + /* @internal */ export function getOptionNameMap(): OptionNameMap { if (optionNameMapCache) { return optionNameMapCache; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 596a2b7170a..36700e0fbf5 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -225,6 +225,7 @@ namespace ts { return { resolvedFileName: referencedSourceFile, failedLookupLocations }; } + /* @internal */ export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, target: ScriptTarget.ES3, @@ -234,6 +235,7 @@ namespace ts { sourceMap: false, } + /* @internal */ export function scriptTargetToString(target: ScriptTarget): string { switch (target) { case ScriptTarget.ES5: @@ -245,6 +247,7 @@ namespace ts { } } + /* @internal */ export function moduleKindToString(kind: ModuleKind): string { switch (kind) { case ModuleKind.None: @@ -260,6 +263,7 @@ namespace ts { } } + /* @internal */ export function newLineKindToString(kind: NewLineKind): string { switch (kind) { case NewLineKind.CarriageReturnLineFeed: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 72b948b96d0..dfa44859266 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2109,6 +2109,7 @@ namespace ts { errors: Diagnostic[]; } + /* @internal */ export interface CommandLineOption { name: string; type: string | Map; // "string", "number", "boolean", or an object literal mapping named values to actual values From 16a6de281c18c765fd9ce42f8265ba71a842e50e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 14:41:43 -0700 Subject: [PATCH 23/74] Update error message --- .../diagnosticInformationMap.generated.ts | 3 +-- src/compiler/diagnosticMessages.json | 19 ++++++------------- src/compiler/tsc.ts | 2 +- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 811f7162b36..799adac319c 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -511,7 +511,7 @@ namespace ts { Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." }, Option_0_cannot_be_specified_with_option_1: { code: 5053, category: DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." }, - You_already_have_a_tsconfig_json_file_defined: { code: 5054, category: DiagnosticCategory.Error, key: "You already have a tsconfig.json file defined." }, + A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -569,7 +569,6 @@ namespace ts { Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, - Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f8a87acd153..132ce78a563 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2033,15 +2033,11 @@ "category": "Error", "code": 5053 }, -<<<<<<< HEAD - -======= - "You already have a tsconfig.json file defined.": { + "A 'tsconfig.json' file is already defined at: '{0}'.": { "category": "Error", - "code": 5052 + "code": 5053 }, ->>>>>>> 1670ce9664ed914ba2cd7c172caf8fe905261a81 "Concatenate and emit output to single file.": { "category": "Message", "code": 6001 @@ -2258,21 +2254,18 @@ "category": "Message", "code": 6068 }, -<<<<<<< HEAD "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) .": { "category": "Message", "code": 6069 }, -======= "Initializes a TypeScript project and creates a tsconfig.json file.": { - "category": "Message", - "code": 6069 - }, - "Successfully created a tsconfig.json file.": { "category": "Message", "code": 6070 }, ->>>>>>> 1670ce9664ed914ba2cd7c172caf8fe905261a81 + "Successfully created a tsconfig.json file.": { + "category": "Message", + "code": 6071 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 536b184589d..df193f4129b 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -162,7 +162,7 @@ namespace ts { if (commandLine.options.init) { let file = combinePaths(sys.getCurrentDirectory(), 'tsconfig.json'); if (sys.fileExists(file)) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.You_already_have_a_tsconfig_json_file_defined)); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file)); } else { let compilerOptions = extend(commandLine.options, defaultInitCompilerOptions); From 9b04405e201b61134aaa820e34b83de869296923 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 25 Aug 2015 16:53:12 -0700 Subject: [PATCH 24/74] Add test and address PR --- ...onListInTypeParameterOfClassExpression1.ts | 5 ++++- ...mpletionListInTypeParameterOfTypeAlias2.ts | 2 -- ...nfoDisplayPartsTypeParameterInTypeAlias.ts | 22 +++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts b/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts index 1398b05e701..f8afcdc418c 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts @@ -4,6 +4,7 @@ ////var C1 = class D {} ////var C3 = class D{} +////var C5 = class D{} goTo.marker("0"); verify.completionListIsEmpty(); @@ -12,4 +13,6 @@ verify.completionListIsEmpty(); goTo.marker("2"); verify.completionListIsEmpty(); goTo.marker("3"); -verify.completionListIsEmpty(); \ No newline at end of file +verify.completionListIsEmpty(); +goTo.marker("4"); +verify.not.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts index e804fb8946a..80a910da798 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts @@ -10,11 +10,9 @@ verify.completionListIsEmpty(); goTo.marker("1"); verify.completionListContains("V"); goTo.marker("2"); -verify.not.completionListIsEmpty(); verify.completionListContains("K"); verify.completionListContains("V"); goTo.marker("3"); -verify.not.completionListIsEmpty(); verify.not.completionListContains("K"); verify.not.completionListContains("V"); verify.completionListContains("K1"); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts index 1bec6868e95..b6a10e086c2 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts @@ -1,13 +1,22 @@ /// ////type /*0*/List = /*2*/T[] +////type /*3*/List2 = /*5*/T[]; + +type List2 = T[]; type L = T[] let typeAliashDisplayParts = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List", kind: "aliasName" }, { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: ">", kind: "punctuation" }]; + +let typeAliashDisplayParts2 = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List2", kind: "aliasName" }, + { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "extends", kind: "keyword" }, + { text: " ", kind: "space" }, { text: "string", kind: "keyword" }, { text: ">", kind: "punctuation" }]; + let typeParameterDisplayParts = [{ text: "(", kind: "punctuation" }, { text: "type parameter", kind: "text" }, { text: ")", kind: "punctuation" }, { text: " ", kind: "space" }, { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "in", kind: "keyword" }, { text: " ", kind: "space" } ] + goTo.marker('0'); verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("0").position, length: "List".length }, typeAliashDisplayParts.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, @@ -20,3 +29,16 @@ verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByN goTo.marker('2'); verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("2").position, length: "T".length }, typeParameterDisplayParts.concat(typeAliashDisplayParts), []); + +goTo.marker('3'); +verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("3").position, length: "List2".length }, + typeAliashDisplayParts2.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, + { text: "[", kind: "punctuation" }, { text: "]", kind: "punctuation" }]), []); + +goTo.marker('4'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("4").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts2), []); + +goTo.marker('5'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("5").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts2), []); \ No newline at end of file From 509232f47738f33bacc4b197034eca03af856506 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 17:42:39 -0700 Subject: [PATCH 25/74] Move handeling to a diffrent function, and remove specialized serialization --- src/compiler/program.ts | 40 +--------------- src/compiler/tsc.ts | 101 ++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 80 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 36700e0fbf5..a1861f6b462 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -233,45 +233,7 @@ namespace ts { outDir: "built", rootDir: ".", sourceMap: false, - } - - /* @internal */ - export function scriptTargetToString(target: ScriptTarget): string { - switch (target) { - case ScriptTarget.ES5: - return "es5"; - case ScriptTarget.ES6: - return "es6"; - default: - return "es3"; - } - } - - /* @internal */ - export function moduleKindToString(kind: ModuleKind): string { - switch (kind) { - case ModuleKind.None: - return undefined; - case ModuleKind.CommonJS: - return "commonjs"; - case ModuleKind.System: - return "system"; - case ModuleKind.UMD: - return "umd"; - default: - return "amd"; - } - } - - /* @internal */ - export function newLineKindToString(kind: NewLineKind): string { - switch (kind) { - case NewLineKind.CarriageReturnLineFeed: - return "CRLF"; - default: - return "LF"; - } - } + }; export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { let currentDirectory: string; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index df193f4129b..6c0b80595dc 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -160,47 +160,7 @@ namespace ts { } if (commandLine.options.init) { - let file = combinePaths(sys.getCurrentDirectory(), 'tsconfig.json'); - if (sys.fileExists(file)) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file)); - } - else { - let compilerOptions = extend(commandLine.options, defaultInitCompilerOptions); - let configs = { - compilerOptions, - files: commandLine.fileNames, - exclude: ["node_modules"] - }; - sys.writeFile(file, JSON.stringify(configs, (k, v) => { - if (k === "compilerOptions") { - let options: CompilerOptions = v; - for (let o in options) { - switch (o) { - case "target": - options[o] = scriptTargetToString(options[o] as ScriptTarget); - continue; - case "module": - options[o] = moduleKindToString(options[o] as ModuleKind); - continue; - case "newLine": - options[o] = newLineKindToString(options[o] as NewLineKind); - continue; - case "init": - case "watch": - case "version": - case "help": - delete options[o]; - continue; - } - } - - return options; - } - - return v; - }, 4)); - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); - } + writeConfigFile(commandLine.options, commandLine.fileNames); return sys.exit(ExitStatus.Success); } @@ -534,6 +494,65 @@ namespace ts { return Array(paddingLength + 1).join(" "); } } + + function writeConfigFile(options: CompilerOptions, fileNames: string[]) { + let currentDirectory = sys.getCurrentDirectory(); + let file = combinePaths(currentDirectory, 'tsconfig.json'); + if (sys.fileExists(file)) { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file)); + } + else { + let compilerOptions = extend(options, defaultInitCompilerOptions); + let configs = { + compilerOptions: serializeCompilerOptions(compilerOptions, currentDirectory), + files: fileNames, + exclude: ["node_modules"] + }; + sys.writeFile(file, JSON.stringify(configs, undefined, 4)); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); + } + + return; + + function serializeCompilerOptions(options: CompilerOptions, currentDirectory: string): Map { + let result: Map = {}; + let optionsNameMap = getOptionNameMap().optionNameMap; + + for (let name in options) { + if (hasProperty(options, name)) { + let value = options[name]; + switch (name) { + case "init": + case "watch": + case "version": + case "help": + case "project": + break; + default: + let optionDefinition = optionsNameMap[name]; + if (optionDefinition) { + if (typeof optionDefinition.type === "string") { + // string, number or boolean + result[name] = value; + } + else { + // Enum + let typeMap = >optionDefinition.type; + for (let key in typeMap) { + if (hasProperty(typeMap, key)) { + if (typeMap[key] === value) + result[name] = key; + } + } + } + } + break; + } + } + } + return result; + } + } } ts.executeCommandLine(ts.sys.args); From d3d4a00691d9d470a42222febcdba656588cc6bd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 17:43:46 -0700 Subject: [PATCH 26/74] use toLowerCase and remove unused property --- src/compiler/tsc.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 6c0b80595dc..e2bf12a832b 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -504,17 +504,18 @@ namespace ts { else { let compilerOptions = extend(options, defaultInitCompilerOptions); let configs = { - compilerOptions: serializeCompilerOptions(compilerOptions, currentDirectory), + compilerOptions: serializeCompilerOptions(compilerOptions), files: fileNames, - exclude: ["node_modules"] + exclude: ["node_modules"], }; + sys.writeFile(file, JSON.stringify(configs, undefined, 4)); reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); } return; - function serializeCompilerOptions(options: CompilerOptions, currentDirectory: string): Map { + function serializeCompilerOptions(options: CompilerOptions): Map { let result: Map = {}; let optionsNameMap = getOptionNameMap().optionNameMap; @@ -529,7 +530,7 @@ namespace ts { case "project": break; default: - let optionDefinition = optionsNameMap[name]; + let optionDefinition = optionsNameMap[name.toLowerCase()]; if (optionDefinition) { if (typeof optionDefinition.type === "string") { // string, number or boolean From 01dda944337c13c7ed5dc8ba42785874c06b5dff Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 17:44:16 -0700 Subject: [PATCH 27/74] Only set files if we have one --- src/compiler/tsc.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index e2bf12a832b..31a22a5dd68 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -503,12 +503,16 @@ namespace ts { } else { let compilerOptions = extend(options, defaultInitCompilerOptions); - let configs = { + let configs: any = { compilerOptions: serializeCompilerOptions(compilerOptions), - files: fileNames, - exclude: ["node_modules"], + exclude: ["node_modules"] }; + if (fileNames && fileNames.length) { + // only set the files property if we have at least one file + configs.files = fileNames; + } + sys.writeFile(file, JSON.stringify(configs, undefined, 4)); reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); } From ea35f07c0e33865594119ba210aeea2cd9e6d342 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 25 Aug 2015 17:45:21 -0700 Subject: [PATCH 28/74] change variable name --- src/compiler/tsc.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 31a22a5dd68..8c0a6d4e8c4 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -503,17 +503,17 @@ namespace ts { } else { let compilerOptions = extend(options, defaultInitCompilerOptions); - let configs: any = { + let configurations: any = { compilerOptions: serializeCompilerOptions(compilerOptions), exclude: ["node_modules"] }; if (fileNames && fileNames.length) { // only set the files property if we have at least one file - configs.files = fileNames; + configurations.files = fileNames; } - sys.writeFile(file, JSON.stringify(configs, undefined, 4)); + sys.writeFile(file, JSON.stringify(configurations, undefined, 4)); reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); } From d615d21e6d3f3280895b68261764a64f439d22d9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 06:41:41 -0700 Subject: [PATCH 29/74] Add cache of anonymous object type instantiations to TypeMapper --- src/compiler/checker.ts | 10 ++++++++++ src/compiler/types.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cff964361a6..ff8cf4e365e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4487,6 +4487,15 @@ namespace ts { } function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType { + if (mapper.instantiations) { + let cachedType = mapper.instantiations[type.id]; + if (cachedType) { + return cachedType; + } + } + else { + mapper.instantiations = []; + } // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it let result = createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); @@ -4497,6 +4506,7 @@ namespace ts { let numberIndexType = getIndexTypeOfType(type, IndexKind.Number); if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.instantiations[type.id] = result; return result; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dfa44859266..80d82547f88 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1953,6 +1953,7 @@ namespace ts { /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; + instantiations?: Type[]; // Cache of instantiations created using this type mapper. context?: InferenceContext; // The inference context this mapper was created from. // Only inference mappers have this set (in createInferenceMapper). // The identity mapper and regular instantiation mappers do not need it. From e364ef3c7c8b9401ad576c008286642b4166e350 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 06:58:53 -0700 Subject: [PATCH 30/74] Adding tests --- ...hRecursivelyReferencedTypeAliasToTypeLiteral01.ts | 7 +++++++ ...hRecursivelyReferencedTypeAliasToTypeLiteral02.ts | 12 ++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts create mode 100644 tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts diff --git a/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts b/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts new file mode 100644 index 00000000000..cffb7654834 --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts @@ -0,0 +1,7 @@ +type TreeNode = { + name: string; + parent: TreeNode; +} + +var nodes: TreeNode[]; +nodes.map(n => n.name); diff --git a/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts b/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts new file mode 100644 index 00000000000..4ca5c9fc663 --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts @@ -0,0 +1,12 @@ +type TreeNode = { + name: string; + parent: TreeNode; +} + +type TreeNodeMiddleman = { + name: string; + parent: TreeNode; +} + +var nodes: TreeNodeMiddleman[]; +nodes.map(n => n.name); From 32f37bb8e0e946d7aece0fa0c7cf52ccce962bbd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 06:59:58 -0700 Subject: [PATCH 31/74] Accepting new baselines --- ...ivelyReferencedTypeAliasToTypeLiteral01.js | 13 +++++++ ...ReferencedTypeAliasToTypeLiteral01.symbols | 25 ++++++++++++ ...lyReferencedTypeAliasToTypeLiteral01.types | 27 +++++++++++++ ...ivelyReferencedTypeAliasToTypeLiteral02.js | 18 +++++++++ ...ReferencedTypeAliasToTypeLiteral02.symbols | 36 ++++++++++++++++++ ...lyReferencedTypeAliasToTypeLiteral02.types | 38 +++++++++++++++++++ 6 files changed, 157 insertions(+) create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.types create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.types diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js new file mode 100644 index 00000000000..e23af7afab6 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js @@ -0,0 +1,13 @@ +//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts] +type TreeNode = { + name: string; + parent: TreeNode; +} + +var nodes: TreeNode[]; +nodes.map(n => n.name); + + +//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js] +var nodes; +nodes.map(function (n) { return n.name; }); diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.symbols b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.symbols new file mode 100644 index 00000000000..08b61492a54 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts === +type TreeNode = { +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0)) + + name: string; +>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17)) + + parent: TreeNode; +>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 1, 17)) +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0)) +} + +var nodes: TreeNode[]; +>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3)) +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0)) + +nodes.map(n => n.name); +>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92)) +>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3)) +>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92)) +>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10)) +>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17)) +>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10)) +>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17)) + diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.types b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.types new file mode 100644 index 00000000000..ea821607211 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts === +type TreeNode = { +>TreeNode : { name: string; parent: TreeNode; } + + name: string; +>name : string + + parent: TreeNode; +>parent : { name: string; parent: TreeNode; } +>TreeNode : { name: string; parent: TreeNode; } +} + +var nodes: TreeNode[]; +>nodes : { name: string; parent: TreeNode; }[] +>TreeNode : { name: string; parent: TreeNode; } + +nodes.map(n => n.name); +>nodes.map(n => n.name) : string[] +>nodes.map : (callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[] +>nodes : { name: string; parent: TreeNode; }[] +>map : (callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[] +>n => n.name : (n: { name: string; parent: TreeNode; }) => string +>n : { name: string; parent: TreeNode; } +>n.name : string +>n : { name: string; parent: TreeNode; } +>name : string + diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js new file mode 100644 index 00000000000..d8e32e12b55 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js @@ -0,0 +1,18 @@ +//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts] +type TreeNode = { + name: string; + parent: TreeNode; +} + +type TreeNodeMiddleman = { + name: string; + parent: TreeNode; +} + +var nodes: TreeNodeMiddleman[]; +nodes.map(n => n.name); + + +//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js] +var nodes; +nodes.map(function (n) { return n.name; }); diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.symbols b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.symbols new file mode 100644 index 00000000000..cb2e8e94656 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts === +type TreeNode = { +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0)) + + name: string; +>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 17)) + + parent: TreeNode; +>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 1, 17)) +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0)) +} + +type TreeNodeMiddleman = { +>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1)) + + name: string; +>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26)) + + parent: TreeNode; +>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 6, 17)) +>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0)) +} + +var nodes: TreeNodeMiddleman[]; +>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3)) +>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1)) + +nodes.map(n => n.name); +>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92)) +>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3)) +>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92)) +>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10)) +>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26)) +>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10)) +>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26)) + diff --git a/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.types b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.types new file mode 100644 index 00000000000..d18cf3a2b1d --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts === +type TreeNode = { +>TreeNode : { name: string; parent: TreeNode; } + + name: string; +>name : string + + parent: TreeNode; +>parent : { name: string; parent: TreeNode; } +>TreeNode : { name: string; parent: TreeNode; } +} + +type TreeNodeMiddleman = { +>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; } + + name: string; +>name : string + + parent: TreeNode; +>parent : { name: string; parent: TreeNode; } +>TreeNode : { name: string; parent: TreeNode; } +} + +var nodes: TreeNodeMiddleman[]; +>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[] +>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; } + +nodes.map(n => n.name); +>nodes.map(n => n.name) : string[] +>nodes.map : (callbackfn: (value: { name: string; parent: { name: string; parent: TreeNode; }; }, index: number, array: { name: string; parent: { name: string; parent: TreeNode; }; }[]) => U, thisArg?: any) => U[] +>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[] +>map : (callbackfn: (value: { name: string; parent: { name: string; parent: TreeNode; }; }, index: number, array: { name: string; parent: { name: string; parent: TreeNode; }; }[]) => U, thisArg?: any) => U[] +>n => n.name : (n: { name: string; parent: { name: string; parent: TreeNode; }; }) => string +>n : { name: string; parent: { name: string; parent: TreeNode; }; } +>n.name : string +>n : { name: string; parent: { name: string; parent: TreeNode; }; } +>name : string + From a74ca1801e6814ed3bd3b7c5e90fe3b7d24b8115 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Thu, 27 Aug 2015 03:33:36 +0900 Subject: [PATCH 32/74] adding rules, ParenthesizedType not yet --- src/services/formatting/rules.ts | 27 +++++++++++++++++++ src/services/formatting/smartIndenter.ts | 9 +++++-- ...rtIndentOnUnclosedFunctionDeclaration04.ts | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index d4e096974b7..6995287fbfd 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -213,6 +213,16 @@ namespace ts.formatting { public NoSpaceBetweenYieldKeywordAndStar: Rule; public SpaceBetweenYieldOrYieldStarAndOperand: Rule; + // Await-async + public SpaceAfterAwaitKeyword: Rule; + public NoSpaceAfterAwaitKeyword: Rule; + public SpaceBetweenAsyncAndFunctionKeyword: Rule; + public NoSpaceBetweenAsyncAndFunctionKeyword: Rule; + + // Tagged template string + public SpaceBetweenTagAndTemplateString: Rule; + public NoSpaceBetweenTagAndTemplateString: Rule; + constructor() { /// /// Common Rules @@ -360,6 +370,17 @@ namespace ts.formatting { this.NoSpaceBetweenYieldKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Delete)); this.SpaceBetweenYieldOrYieldStarAndOperand = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Space)); + // Await-async + this.SpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + + // template string + this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + + // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -386,6 +407,12 @@ namespace ts.formatting { this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, + this.SpaceAfterAwaitKeyword, + this.NoSpaceAfterAwaitKeyword, + this.SpaceBetweenAsyncAndFunctionKeyword, + this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceBetweenTagAndTemplateString, + this.NoSpaceBetweenTagAndTemplateString, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 30da55b8f37..012c73205f9 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -429,7 +429,14 @@ namespace ts.formatting { case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxElement: + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: case SyntaxKind.FunctionType: + case SyntaxKind.UnionType: + case SyntaxKind.Parameter: + case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.AwaitExpression: return true; } return false; @@ -449,8 +456,6 @@ namespace ts.formatting { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: case SyntaxKind.ArrowFunction: case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: diff --git a/tests/cases/fourslash/smartIndentOnUnclosedFunctionDeclaration04.ts b/tests/cases/fourslash/smartIndentOnUnclosedFunctionDeclaration04.ts index 3931433e51f..2cfd27f2e3b 100644 --- a/tests/cases/fourslash/smartIndentOnUnclosedFunctionDeclaration04.ts +++ b/tests/cases/fourslash/smartIndentOnUnclosedFunctionDeclaration04.ts @@ -12,6 +12,6 @@ function verifyIndentationAfterNewLine(marker: string, indentation: number): voi verifyIndentationAfterNewLine("1", 4); verifyIndentationAfterNewLine("2", 4); verifyIndentationAfterNewLine("3", 4); -verifyIndentationAfterNewLine("4", 4); +verifyIndentationAfterNewLine("4", 8); verifyIndentationAfterNewLine("5", 4); verifyIndentationAfterNewLine("6", 4); \ No newline at end of file From c7ea94be754731428b606e382cfc95070b4c2234 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Tue, 25 Aug 2015 14:33:09 -0700 Subject: [PATCH 33/74] fix MessageEvent and ProgressEvent constructors --- src/lib/dom.generated.d.ts | 20 +++++++++++++++++--- src/lib/webworker.generated.d.ts | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 9f857276d1a..09ab70f23b3 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -7706,7 +7706,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -8448,7 +8448,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -12615,7 +12615,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -12632,6 +12631,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: Array; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index eef668d7745..eff2035c627 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -587,7 +587,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -640,7 +640,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface WebSocket extends EventTarget { @@ -911,6 +911,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: Array; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } From 748231f45d9f08a9ff1c06da3a05475f6b646d14 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Wed, 26 Aug 2015 12:24:40 -0700 Subject: [PATCH 34/74] CR feedback --- src/lib/dom.generated.d.ts | 2 +- src/lib/webworker.generated.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 09ab70f23b3..90075a290a4 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -12637,7 +12637,7 @@ interface MessageEventInit extends EventInit { lastEventId?: string; channel?: string; source?: any; - ports?: Array; + ports?: MessagePort[]; } interface ProgressEventInit extends EventInit { diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index eff2035c627..9353047e9c6 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -917,7 +917,7 @@ interface MessageEventInit extends EventInit { lastEventId?: string; channel?: string; source?: any; - ports?: Array; + ports?: MessagePort[]; } interface ProgressEventInit extends EventInit { From 735efee7ce8a5cd594c6b2e647aaf11ae2ddbc51 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 25 Aug 2015 16:47:02 -0700 Subject: [PATCH 35/74] Read default lib from the local file system instead of log-array when do Not use custom library file --- src/harness/harness.ts | 3 --- src/harness/rwcRunner.ts | 12 +++++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index de675948851..097340082e3 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1424,9 +1424,6 @@ module Harness { return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; }); - // Verify we didn't miss any errors in total - assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); - return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index d8b52ec2e39..ea6f7b7ebb1 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -65,6 +65,15 @@ module RWC { opts.options.noEmitOnError = false; }); + if (!useCustomLibraryFile) { + let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); + let defaultLib = { + unitName: ts.normalizePath(defaultLibPath), + content: Harness.IO.readFile(defaultLibPath) + }; + inputFiles.push(defaultLib); + } + runWithIOLog(ioLog, () => { harnessCompiler.reset(); @@ -96,9 +105,6 @@ module RWC { if (useCustomLibraryFile) { inputFiles.push(getHarnessCompilerInputUnit(fileRead.path)); } - else { - inputFiles.push(Harness.getDefaultLibraryFile()); - } } } } From 8a4c56bb761256906ec7b2af4f342d7eb8c2a094 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 26 Aug 2015 12:50:00 -0700 Subject: [PATCH 36/74] Address CR --- src/harness/harness.ts | 10 +--------- src/harness/rwcRunner.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 097340082e3..5cde3ad3647 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1415,15 +1415,7 @@ module Harness { assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName); }); - let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { - return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName)); - }); - - let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { - // Count an error generated from tests262-harness folder.This should only apply for test262 - return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; - }); - + assert.equal(totalErrorsReported, diagnostics.length, "total number of errors"); return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index ea6f7b7ebb1..cf748c3070b 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -19,6 +19,12 @@ module RWC { } } + let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); + let defaultLib = { + unitName: ts.normalizePath(defaultLibPath), + content: Harness.IO.readFile(defaultLibPath) + }; + export function runRWCTest(jsonPath: string) { describe("Testing a RWC project: " + jsonPath, () => { let inputFiles: { unitName: string; content: string; }[] = []; @@ -66,11 +72,6 @@ module RWC { }); if (!useCustomLibraryFile) { - let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); - let defaultLib = { - unitName: ts.normalizePath(defaultLibPath), - content: Harness.IO.readFile(defaultLibPath) - }; inputFiles.push(defaultLib); } From a38c32f4955f9a354715f2b7a0b2cd34950dda47 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 26 Aug 2015 13:12:29 -0700 Subject: [PATCH 37/74] fix error message for forward references in enums --- src/compiler/checker.ts | 2 +- .../diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../reference/constEnumErrors.errors.txt | 4 +-- .../reference/forwardRefInEnum.errors.txt | 29 +++++++++++++++++ tests/baselines/reference/forwardRefInEnum.js | 31 +++++++++++++++++++ tests/cases/compiler/forwardRefInEnum.ts | 13 ++++++++ 7 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/forwardRefInEnum.errors.txt create mode 100644 tests/baselines/reference/forwardRefInEnum.js create mode 100644 tests/cases/compiler/forwardRefInEnum.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ae388c5b832..33761e2b2e6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13053,7 +13053,7 @@ namespace ts { // illegal case: forward reference if (!isDefinedBefore(propertyDecl, member)) { reportError = false; - error(e, Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); + error(e, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return undefined; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 76c68b4c3b4..5c4400b4fe4 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -425,7 +425,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." }, Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8113722ff3c..6c1fe01f724 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1689,7 +1689,7 @@ "category": "Error", "code": 2650 }, - "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums.": { + "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": { "category": "Error", "code": 2651 }, diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 4236544defa..586652d41eb 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/constEnumErrors.ts(1,12): error TS2300: Duplicate identifier 'E'. tests/cases/compiler/constEnumErrors.ts(5,8): error TS2300: Duplicate identifier 'E'. -tests/cases/compiler/constEnumErrors.ts(12,9): error TS2651: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. +tests/cases/compiler/constEnumErrors.ts(12,9): error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. @@ -31,7 +31,7 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member // forward reference to the element of the same enum X = Y, ~ -!!! error TS2651: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. +!!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. // forward reference to the element of the same enum Y = E1.Z, ~~~~ diff --git a/tests/baselines/reference/forwardRefInEnum.errors.txt b/tests/baselines/reference/forwardRefInEnum.errors.txt new file mode 100644 index 00000000000..0f2c359402f --- /dev/null +++ b/tests/baselines/reference/forwardRefInEnum.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/forwardRefInEnum.ts(4,9): error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. +tests/cases/compiler/forwardRefInEnum.ts(5,10): error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. +tests/cases/compiler/forwardRefInEnum.ts(7,9): error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. +tests/cases/compiler/forwardRefInEnum.ts(8,10): error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. + + +==== tests/cases/compiler/forwardRefInEnum.ts (4 errors) ==== + enum E1 { + // illegal case + // forward reference to the element of the same enum + X = Y, + ~ +!!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. + X1 = E1["Y"], + ~~~~~~~ +!!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. + // forward reference to the element of the same enum + Y = E1.Z, + ~~~~ +!!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. + Y1 = E1["Z"] + ~~~~~~~ +!!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. + } + + enum E1 { + Z = 4 + } + \ No newline at end of file diff --git a/tests/baselines/reference/forwardRefInEnum.js b/tests/baselines/reference/forwardRefInEnum.js new file mode 100644 index 00000000000..76e2575ec8d --- /dev/null +++ b/tests/baselines/reference/forwardRefInEnum.js @@ -0,0 +1,31 @@ +//// [forwardRefInEnum.ts] +enum E1 { + // illegal case + // forward reference to the element of the same enum + X = Y, + X1 = E1["Y"], + // forward reference to the element of the same enum + Y = E1.Z, + Y1 = E1["Z"] +} + +enum E1 { + Z = 4 +} + + +//// [forwardRefInEnum.js] +var E1; +(function (E1) { + // illegal case + // forward reference to the element of the same enum + E1[E1["X"] = E1.Y] = "X"; + E1[E1["X1"] = E1["Y"]] = "X1"; + // forward reference to the element of the same enum + E1[E1["Y"] = E1.Z] = "Y"; + E1[E1["Y1"] = E1["Z"]] = "Y1"; +})(E1 || (E1 = {})); +var E1; +(function (E1) { + E1[E1["Z"] = 4] = "Z"; +})(E1 || (E1 = {})); diff --git a/tests/cases/compiler/forwardRefInEnum.ts b/tests/cases/compiler/forwardRefInEnum.ts new file mode 100644 index 00000000000..97bc1819d7b --- /dev/null +++ b/tests/cases/compiler/forwardRefInEnum.ts @@ -0,0 +1,13 @@ +enum E1 { + // illegal case + // forward reference to the element of the same enum + X = Y, + X1 = E1["Y"], + // forward reference to the element of the same enum + Y = E1.Z, + Y1 = E1["Z"] +} + +enum E1 { + Z = 4 +} From c68fc53e37439a6c981241f08f1c30d6b27e6186 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 26 Aug 2015 13:26:51 -0700 Subject: [PATCH 38/74] Correctly emit imported 'React' references in JSX. Fixes bug #4422 --- src/compiler/checker.ts | 6 +++- src/compiler/emitter.ts | 16 ++++++++-- src/compiler/types.ts | 2 ++ tests/baselines/reference/tsxReactEmit5.js | 24 +++++++++++++++ .../baselines/reference/tsxReactEmit5.symbols | 29 ++++++++++++++++++ tests/baselines/reference/tsxReactEmit5.types | 30 +++++++++++++++++++ tests/cases/conformance/jsx/tsxReactEmit5.tsx | 18 +++++++++++ 7 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/tsxReactEmit5.js create mode 100644 tests/baselines/reference/tsxReactEmit5.symbols create mode 100644 tests/baselines/reference/tsxReactEmit5.types create mode 100644 tests/cases/conformance/jsx/tsxReactEmit5.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cff964361a6..48697bc548e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7629,8 +7629,12 @@ namespace ts { // is no 'React' symbol in scope, we should issue an error. if (compilerOptions.jsx === JsxEmit.React) { let reactSym = resolveName(node.tagName, "React", SymbolFlags.Value, Diagnostics.Cannot_find_name_0, "React"); - if (reactSym) { + if (reactSym && reactSym !== unknownSymbol) { getSymbolLinks(reactSym).referenced = true; + let reactNode = createSynthesizedNode(SyntaxKind.Identifier, false); + reactNode.text = 'React'; + getNodeLinks(reactNode).resolvedSymbol = reactSym; + node.reactNode = reactNode; } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index cdaa57aa981..8525e2addee 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1179,7 +1179,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function emitJsxElement(openingNode: JsxOpeningLikeElement, children?: JsxChild[]) { // Call React.createElement(tag, ... emitLeadingComments(openingNode); - write("React.createElement("); + if (openingNode.reactNode) { + emitExpressionIdentifier(openingNode.reactNode); + } + else { + write('React'); + } + write(".createElement("); emitTagName(openingNode.tagName); write(", "); @@ -1193,7 +1199,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // a call to React.__spread let attrs = openingNode.attributes; if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) { - write("React.__spread("); + if (openingNode.reactNode) { + emitExpressionIdentifier(openingNode.reactNode); + } + else { + write('React'); + } + write(".__spread("); let haveOpenedObjectLiteral = false; for (let i = 0; i < attrs.length; i++) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dfa44859266..0c9225aa43e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -869,11 +869,13 @@ namespace ts { _openingElementBrand?: any; tagName: EntityName; attributes: NodeArray; + reactNode?: Identifier; } /// A JSX expression of the form export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { _selfClosingElementBrand?: any; + reactNode?: Identifier; } /// Either the opening tag in a ... pair, or the lone in a self-closing form diff --git a/tests/baselines/reference/tsxReactEmit5.js b/tests/baselines/reference/tsxReactEmit5.js new file mode 100644 index 00000000000..d86fb4147ef --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit5.js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/jsx/tsxReactEmit5.tsx] //// + +//// [file.tsx] + +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//// [test.d.ts] +export var React; + +//// [react-consumer.tsx] +import {React} from "./test"; +// Should emit test_1.React.createElement +var spread1 =
; + +//// [file.js] +//// [react-consumer.js] +var test_1 = require("./test"); +// Should emit test_1.React.createElement +var spread1 = test_1.React.createElement("div", null); diff --git a/tests/baselines/reference/tsxReactEmit5.symbols b/tests/baselines/reference/tsxReactEmit5.symbols new file mode 100644 index 00000000000..66997574b97 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit5.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : Symbol(JSX, Decl(file.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(file.tsx, 1, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(file.tsx, 4, 3)) + } +} + +=== tests/cases/conformance/jsx/test.d.ts === +export var React; +>React : Symbol(React, Decl(test.d.ts, 0, 10)) + +=== tests/cases/conformance/jsx/react-consumer.tsx === +import {React} from "./test"; +>React : Symbol(React, Decl(react-consumer.tsx, 0, 8)) + +// Should emit test_1.React.createElement +var spread1 =
; +>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 2, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) + diff --git a/tests/baselines/reference/tsxReactEmit5.types b/tests/baselines/reference/tsxReactEmit5.types new file mode 100644 index 00000000000..eaaeaeda46f --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit5.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +=== tests/cases/conformance/jsx/test.d.ts === +export var React; +>React : any + +=== tests/cases/conformance/jsx/react-consumer.tsx === +import {React} from "./test"; +>React : any + +// Should emit test_1.React.createElement +var spread1 =
; +>spread1 : JSX.Element +>
: JSX.Element +>div : any + diff --git a/tests/cases/conformance/jsx/tsxReactEmit5.tsx b/tests/cases/conformance/jsx/tsxReactEmit5.tsx new file mode 100644 index 00000000000..c1890d1391a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit5.tsx @@ -0,0 +1,18 @@ +//@jsx: react +//@module: commonjs + +//@filename: file.tsx +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//@filename: test.d.ts +export var React; + +//@filename: react-consumer.tsx +import {React} from "./test"; +// Should emit test_1.React.createElement +var spread1 =
; \ No newline at end of file From 6b5a14a353c0d1b918886994ac29d027c5d80641 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 26 Aug 2015 15:28:21 -0700 Subject: [PATCH 39/74] CR feedback --- src/compiler/types.ts | 1 - tests/baselines/reference/tsxReactEmit5.js | 9 +++++++-- tests/baselines/reference/tsxReactEmit5.symbols | 10 ++++++++-- tests/baselines/reference/tsxReactEmit5.types | 11 +++++++++-- tests/cases/conformance/jsx/tsxReactEmit5.tsx | 4 +++- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0c9225aa43e..a63a0790e57 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -875,7 +875,6 @@ namespace ts { /// A JSX expression of the form export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { _selfClosingElementBrand?: any; - reactNode?: Identifier; } /// Either the opening tag in a ... pair, or the lone in a self-closing form diff --git a/tests/baselines/reference/tsxReactEmit5.js b/tests/baselines/reference/tsxReactEmit5.js index d86fb4147ef..f6a7eeb72a1 100644 --- a/tests/baselines/reference/tsxReactEmit5.js +++ b/tests/baselines/reference/tsxReactEmit5.js @@ -15,10 +15,15 @@ export var React; //// [react-consumer.tsx] import {React} from "./test"; // Should emit test_1.React.createElement -var spread1 =
; +// and React.__spread +var foo; +var spread1 =
; + //// [file.js] //// [react-consumer.js] var test_1 = require("./test"); // Should emit test_1.React.createElement -var spread1 = test_1.React.createElement("div", null); +// and React.__spread +var foo; +var spread1 = test_1.React.createElement("div", test_1.React.__spread({x: ''}, foo, {y: ''})); diff --git a/tests/baselines/reference/tsxReactEmit5.symbols b/tests/baselines/reference/tsxReactEmit5.symbols index 66997574b97..388e717957f 100644 --- a/tests/baselines/reference/tsxReactEmit5.symbols +++ b/tests/baselines/reference/tsxReactEmit5.symbols @@ -23,7 +23,13 @@ import {React} from "./test"; >React : Symbol(React, Decl(react-consumer.tsx, 0, 8)) // Should emit test_1.React.createElement -var spread1 =
; ->spread1 : Symbol(spread1, Decl(react-consumer.tsx, 2, 3)) +// and React.__spread +var foo; +>foo : Symbol(foo, Decl(react-consumer.tsx, 3, 3)) + +var spread1 =
; +>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 4, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) diff --git a/tests/baselines/reference/tsxReactEmit5.types b/tests/baselines/reference/tsxReactEmit5.types index eaaeaeda46f..fb1c6594f30 100644 --- a/tests/baselines/reference/tsxReactEmit5.types +++ b/tests/baselines/reference/tsxReactEmit5.types @@ -23,8 +23,15 @@ import {React} from "./test"; >React : any // Should emit test_1.React.createElement -var spread1 =
; +// and React.__spread +var foo; +>foo : any + +var spread1 =
; >spread1 : JSX.Element ->
: JSX.Element +>
: JSX.Element >div : any +>x : any +>foo : any +>y : any diff --git a/tests/cases/conformance/jsx/tsxReactEmit5.tsx b/tests/cases/conformance/jsx/tsxReactEmit5.tsx index c1890d1391a..c961a23ecfc 100644 --- a/tests/cases/conformance/jsx/tsxReactEmit5.tsx +++ b/tests/cases/conformance/jsx/tsxReactEmit5.tsx @@ -15,4 +15,6 @@ export var React; //@filename: react-consumer.tsx import {React} from "./test"; // Should emit test_1.React.createElement -var spread1 =
; \ No newline at end of file +// and React.__spread +var foo; +var spread1 =
; From 9eef4b8f4777196e49402d060a065c32168f08a9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Aug 2015 15:48:49 -0700 Subject: [PATCH 40/74] Added tests. --- ...ToDefinitionConstructorOfClassExpression01.ts | 11 +++++++++++ ...torOfClassWhenClassIsPrecededByNamespace01.ts | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts create mode 100644 tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts new file mode 100644 index 00000000000..aa96400a397 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts @@ -0,0 +1,11 @@ +/// + +////var x = class C { +//// /*definition*/constructor() { +//// var other = new /*usage*/C; +//// } +////} + +goTo.marker("usage"); +goTo.definition(); +verify.caretAtMarker("definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts new file mode 100644 index 00000000000..dc5c362772c --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts @@ -0,0 +1,16 @@ +/// + +////namespace Foo { +//// export var x; +////} +//// +////class Foo { +//// /*definition*/constructor() { +//// } +////} +//// +////var x = new /*usage*/Foo(); + +goTo.marker("usage"); +goTo.definition(); +verify.caretAtMarker("definition"); \ No newline at end of file From 0e4fdf8373de39200ddc41ca6fea68fe2875a66e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 26 Aug 2015 16:12:50 -0700 Subject: [PATCH 41/74] Use synthetic identifier during emit instead --- src/compiler/checker.ts | 6 +-- src/compiler/emitter.ts | 18 +++----- tests/baselines/reference/tsxReactEmit6.js | 36 ++++++++++++++++ .../baselines/reference/tsxReactEmit6.symbols | 39 ++++++++++++++++++ tests/baselines/reference/tsxReactEmit6.types | 41 +++++++++++++++++++ tests/cases/conformance/jsx/tsxReactEmit6.tsx | 22 ++++++++++ 6 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 tests/baselines/reference/tsxReactEmit6.js create mode 100644 tests/baselines/reference/tsxReactEmit6.symbols create mode 100644 tests/baselines/reference/tsxReactEmit6.types create mode 100644 tests/cases/conformance/jsx/tsxReactEmit6.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 48697bc548e..cff964361a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7629,12 +7629,8 @@ namespace ts { // is no 'React' symbol in scope, we should issue an error. if (compilerOptions.jsx === JsxEmit.React) { let reactSym = resolveName(node.tagName, "React", SymbolFlags.Value, Diagnostics.Cannot_find_name_0, "React"); - if (reactSym && reactSym !== unknownSymbol) { + if (reactSym) { getSymbolLinks(reactSym).referenced = true; - let reactNode = createSynthesizedNode(SyntaxKind.Identifier, false); - reactNode.text = 'React'; - getNodeLinks(reactNode).resolvedSymbol = reactSym; - node.reactNode = reactNode; } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8525e2addee..eeaab6d2123 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1177,14 +1177,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitJsxElement(openingNode: JsxOpeningLikeElement, children?: JsxChild[]) { + let syntheticReactRef = createSynthesizedNode(SyntaxKind.Identifier); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; + // Call React.createElement(tag, ... emitLeadingComments(openingNode); - if (openingNode.reactNode) { - emitExpressionIdentifier(openingNode.reactNode); - } - else { - write('React'); - } + emitExpressionIdentifier(syntheticReactRef); write(".createElement("); emitTagName(openingNode.tagName); write(", "); @@ -1199,12 +1198,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // a call to React.__spread let attrs = openingNode.attributes; if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) { - if (openingNode.reactNode) { - emitExpressionIdentifier(openingNode.reactNode); - } - else { - write('React'); - } + emitExpressionIdentifier(syntheticReactRef); write(".__spread("); let haveOpenedObjectLiteral = false; diff --git a/tests/baselines/reference/tsxReactEmit6.js b/tests/baselines/reference/tsxReactEmit6.js new file mode 100644 index 00000000000..d20ef7051e0 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.js @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/jsx/tsxReactEmit6.tsx] //// + +//// [file.tsx] + +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//// [react-consumer.tsx] +namespace M { + export var React: any; +} + +namespace M { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 =
; +} + + +//// [file.js] +//// [react-consumer.js] +var M; +(function (M) { +})(M || (M = {})); +var M; +(function (M) { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 = M.React.createElement("div", M.React.__spread({x: ''}, foo, {y: ''})); +})(M || (M = {})); diff --git a/tests/baselines/reference/tsxReactEmit6.symbols b/tests/baselines/reference/tsxReactEmit6.symbols new file mode 100644 index 00000000000..0302cef3e8d --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : Symbol(JSX, Decl(file.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(file.tsx, 1, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(file.tsx, 4, 3)) + } +} + +=== tests/cases/conformance/jsx/react-consumer.tsx === +namespace M { +>M : Symbol(M, Decl(react-consumer.tsx, 0, 0), Decl(react-consumer.tsx, 2, 1)) + + export var React: any; +>React : Symbol(React, Decl(react-consumer.tsx, 1, 11)) +} + +namespace M { +>M : Symbol(M, Decl(react-consumer.tsx, 0, 0), Decl(react-consumer.tsx, 2, 1)) + + // Should emit M.React.createElement + // and M.React.__spread + var foo; +>foo : Symbol(foo, Decl(react-consumer.tsx, 7, 4)) + + var spread1 =
; +>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 8, 4)) +>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) +} + diff --git a/tests/baselines/reference/tsxReactEmit6.types b/tests/baselines/reference/tsxReactEmit6.types new file mode 100644 index 00000000000..1b16b84fcc7 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.types @@ -0,0 +1,41 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +=== tests/cases/conformance/jsx/react-consumer.tsx === +namespace M { +>M : typeof M + + export var React: any; +>React : any +} + +namespace M { +>M : typeof M + + // Should emit M.React.createElement + // and M.React.__spread + var foo; +>foo : any + + var spread1 =
; +>spread1 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>foo : any +>y : any +} + diff --git a/tests/cases/conformance/jsx/tsxReactEmit6.tsx b/tests/cases/conformance/jsx/tsxReactEmit6.tsx new file mode 100644 index 00000000000..2782f90e503 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit6.tsx @@ -0,0 +1,22 @@ +//@jsx: react +//@module: commonjs + +//@filename: file.tsx +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//@filename: react-consumer.tsx +namespace M { + export var React: any; +} + +namespace M { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 =
; +} From 09120e3a4090366aca579c5807d14421e4919f72 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 26 Aug 2015 16:13:35 -0700 Subject: [PATCH 42/74] Remove unused field --- src/compiler/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a63a0790e57..dfa44859266 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -869,7 +869,6 @@ namespace ts { _openingElementBrand?: any; tagName: EntityName; attributes: NodeArray; - reactNode?: Identifier; } /// A JSX expression of the form From 9f3c99e392fde4cfbf19bdd70fe6fdfc45016a1c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Aug 2015 16:19:55 -0700 Subject: [PATCH 43/74] Don't assume the class declaration will occur first, and that it is *only* a class declaration. --- src/compiler/utilities.ts | 4 ++-- src/services/services.ts | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ac559645bb5..99ea06532a0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -611,11 +611,11 @@ namespace ts { return false; } - export function isAccessor(node: Node): boolean { + export function isAccessor(node: Node): node is AccessorDeclaration { return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor); } - export function isClassLike(node: Node): boolean { + export function isClassLike(node: Node): node is ClassLikeDeclaration { return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression); } diff --git a/src/services/services.ts b/src/services/services.ts index 92b62458f64..4358c9d58a9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4480,10 +4480,19 @@ namespace ts { // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { - let classDeclaration = symbol.getDeclarations()[0]; - Debug.assert(classDeclaration && classDeclaration.kind === SyntaxKind.ClassDeclaration); + // Find the first class-like declaration and try to get the construct signature. + for (let declaration of symbol.getDeclarations()) { + if (isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, + symbolKind, + symbolName, + containerName, + result); + } + } - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; From 50127a5adf0bbbc331dd49b7ea7a254c1cc58a99 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Aug 2015 15:48:49 -0700 Subject: [PATCH 44/74] Added tests. --- ...ToDefinitionConstructorOfClassExpression01.ts | 11 +++++++++++ ...torOfClassWhenClassIsPrecededByNamespace01.ts | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts create mode 100644 tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts new file mode 100644 index 00000000000..aa96400a397 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts @@ -0,0 +1,11 @@ +/// + +////var x = class C { +//// /*definition*/constructor() { +//// var other = new /*usage*/C; +//// } +////} + +goTo.marker("usage"); +goTo.definition(); +verify.caretAtMarker("definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts new file mode 100644 index 00000000000..dc5c362772c --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts @@ -0,0 +1,16 @@ +/// + +////namespace Foo { +//// export var x; +////} +//// +////class Foo { +//// /*definition*/constructor() { +//// } +////} +//// +////var x = new /*usage*/Foo(); + +goTo.marker("usage"); +goTo.definition(); +verify.caretAtMarker("definition"); \ No newline at end of file From d4a45227ec4f5bbc3e5dae251e0c23b40e1c154a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Aug 2015 16:19:55 -0700 Subject: [PATCH 45/74] Don't assume the class declaration will occur first, and that it is *only* a class declaration. --- src/compiler/utilities.ts | 4 ++-- src/services/services.ts | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ac559645bb5..99ea06532a0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -611,11 +611,11 @@ namespace ts { return false; } - export function isAccessor(node: Node): boolean { + export function isAccessor(node: Node): node is AccessorDeclaration { return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor); } - export function isClassLike(node: Node): boolean { + export function isClassLike(node: Node): node is ClassLikeDeclaration { return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression); } diff --git a/src/services/services.ts b/src/services/services.ts index 92b62458f64..4358c9d58a9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4480,10 +4480,19 @@ namespace ts { // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { - let classDeclaration = symbol.getDeclarations()[0]; - Debug.assert(classDeclaration && classDeclaration.kind === SyntaxKind.ClassDeclaration); + // Find the first class-like declaration and try to get the construct signature. + for (let declaration of symbol.getDeclarations()) { + if (isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, + symbolKind, + symbolName, + containerName, + result); + } + } - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; From bbdd340de93073f8305d097df52596249cb4e077 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 17:13:53 -0700 Subject: [PATCH 46/74] Adding -suppressExcessPropertyErrors compiler option --- src/compiler/checker.ts | 5 +++-- src/compiler/commandLineParser.ts | 6 ++++++ src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/types.ts | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 73fa64ed499..fb410d207cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7161,7 +7161,7 @@ namespace ts { let propertiesTable: SymbolTable = {}; let propertiesArray: Symbol[] = []; let contextualType = getContextualType(node); - let typeFlags: TypeFlags; + let typeFlags: TypeFlags = 0; for (let memberDecl of node.properties) { let member = memberDecl.symbol; @@ -7210,7 +7210,8 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.PropagatingFlags); + let freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral; + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags); return result; function getIndexType(kind: IndexKind) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 1f57c142113..df94ce33631 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -184,6 +184,12 @@ namespace ts { description: Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: Diagnostics.LOCATION, }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: Diagnostics.Suppress_excess_property_checks_for_object_literals, + experimental: true + }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 799adac319c..355d1e6dda1 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -569,6 +569,7 @@ namespace ts { Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, + Suppress_excess_property_checks_for_object_literals: { code: 6072, category: DiagnosticCategory.Message, key: "Suppress excess property checks for object literals." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 132ce78a563..57badca8c4e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2266,6 +2266,10 @@ "category": "Message", "code": 6071 }, + "Suppress excess property checks for object literals.": { + "category": "Message", + "code": 6072 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 80d82547f88..47182e39527 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2048,6 +2048,7 @@ namespace ts { rootDir?: string; sourceMap?: boolean; sourceRoot?: string; + suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; version?: boolean; From 72b347478c1372a3ccb0ef3aff36b5cab9055b48 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 17:14:13 -0700 Subject: [PATCH 47/74] Adding test harness support --- src/harness/harness.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index de675948851..780a6ca1408 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1203,6 +1203,10 @@ module Harness { options.isolatedModules = setting.value === "true"; break; + case "suppressexcesspropertyerrors": + options.suppressExcessPropertyErrors = setting.value === "true"; + break; + case "suppressimplicitanyindexerrors": options.suppressImplicitAnyIndexErrors = setting.value === "true"; break; @@ -1569,7 +1573,7 @@ module Harness { "nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror", "noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums", - "includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal", + "includebuiltfile", "suppressexcesspropertyerrors", "suppressimplicitanyindexerrors", "stripinternal", "isolatedmodules", "inlinesourcemap", "maproot", "sourceroot", "inlinesources", "emitdecoratormetadata", "experimentaldecorators", "skipdefaultlibcheck", "jsx"]; From f5b85acd74fabb5ff67f1257fd724f5d069ec7be Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 17:14:33 -0700 Subject: [PATCH 48/74] Adding test --- tests/cases/compiler/excessPropertyErrorsSuppressed.ts | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/cases/compiler/excessPropertyErrorsSuppressed.ts diff --git a/tests/cases/compiler/excessPropertyErrorsSuppressed.ts b/tests/cases/compiler/excessPropertyErrorsSuppressed.ts new file mode 100644 index 00000000000..21bfee420c1 --- /dev/null +++ b/tests/cases/compiler/excessPropertyErrorsSuppressed.ts @@ -0,0 +1,3 @@ +//@suppressExcessPropertyErrors: true + +var x: { a: string } = { a: "hello", b: 42 }; // No error From 806c549c84e694eebde71640131d953e736b1e4c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Aug 2015 17:15:21 -0700 Subject: [PATCH 49/74] Accepting new baselines --- .../reference/excessPropertyErrorsSuppressed.js | 7 +++++++ .../reference/excessPropertyErrorsSuppressed.symbols | 8 ++++++++ .../reference/excessPropertyErrorsSuppressed.types | 11 +++++++++++ 3 files changed, 26 insertions(+) create mode 100644 tests/baselines/reference/excessPropertyErrorsSuppressed.js create mode 100644 tests/baselines/reference/excessPropertyErrorsSuppressed.symbols create mode 100644 tests/baselines/reference/excessPropertyErrorsSuppressed.types diff --git a/tests/baselines/reference/excessPropertyErrorsSuppressed.js b/tests/baselines/reference/excessPropertyErrorsSuppressed.js new file mode 100644 index 00000000000..1673674c5f3 --- /dev/null +++ b/tests/baselines/reference/excessPropertyErrorsSuppressed.js @@ -0,0 +1,7 @@ +//// [excessPropertyErrorsSuppressed.ts] + +var x: { a: string } = { a: "hello", b: 42 }; // No error + + +//// [excessPropertyErrorsSuppressed.js] +var x = { a: "hello", b: 42 }; // No error diff --git a/tests/baselines/reference/excessPropertyErrorsSuppressed.symbols b/tests/baselines/reference/excessPropertyErrorsSuppressed.symbols new file mode 100644 index 00000000000..01c2846d3e1 --- /dev/null +++ b/tests/baselines/reference/excessPropertyErrorsSuppressed.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/excessPropertyErrorsSuppressed.ts === + +var x: { a: string } = { a: "hello", b: 42 }; // No error +>x : Symbol(x, Decl(excessPropertyErrorsSuppressed.ts, 1, 3)) +>a : Symbol(a, Decl(excessPropertyErrorsSuppressed.ts, 1, 8)) +>a : Symbol(a, Decl(excessPropertyErrorsSuppressed.ts, 1, 24)) +>b : Symbol(b, Decl(excessPropertyErrorsSuppressed.ts, 1, 36)) + diff --git a/tests/baselines/reference/excessPropertyErrorsSuppressed.types b/tests/baselines/reference/excessPropertyErrorsSuppressed.types new file mode 100644 index 00000000000..47a4dbf92a9 --- /dev/null +++ b/tests/baselines/reference/excessPropertyErrorsSuppressed.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/excessPropertyErrorsSuppressed.ts === + +var x: { a: string } = { a: "hello", b: 42 }; // No error +>x : { a: string; } +>a : string +>{ a: "hello", b: 42 } : { a: string; b: number; } +>a : string +>"hello" : string +>b : number +>42 : number + From be97d03af0d0888100b80ffb5d58ed12505248a2 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Thu, 27 Aug 2015 18:26:00 +0900 Subject: [PATCH 50/74] union type rules --- src/services/formatting/rules.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 6995287fbfd..92c27266818 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -223,6 +223,12 @@ namespace ts.formatting { public SpaceBetweenTagAndTemplateString: Rule; public NoSpaceBetweenTagAndTemplateString: Rule; + // Union type + public SpaceBeforeBar: Rule; + public NoSpaceBeforeBar: Rule; + public SpaceAfterBar: Rule; + public NoSpaceAfterBar: Rule; + constructor() { /// /// Common Rules @@ -380,6 +386,12 @@ namespace ts.formatting { this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + // union type + this.SpaceBeforeBar = new Rule(RuleDescriptor.create3(SyntaxKind.BarToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceBeforeBar = new Rule(RuleDescriptor.create3(SyntaxKind.BarToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + this.SpaceAfterBar = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.BarToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceAfterBar = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.BarToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = @@ -407,12 +419,10 @@ namespace ts.formatting { this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, - this.SpaceAfterAwaitKeyword, - this.NoSpaceAfterAwaitKeyword, - this.SpaceBetweenAsyncAndFunctionKeyword, - this.NoSpaceBetweenAsyncAndFunctionKeyword, - this.SpaceBetweenTagAndTemplateString, - this.NoSpaceBetweenTagAndTemplateString, + this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, + this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceBetweenTagAndTemplateString, this.NoSpaceBetweenTagAndTemplateString, + this.SpaceBeforeBar, this.NoSpaceBeforeBar, this.SpaceAfterBar, this.NoSpaceAfterBar, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, From b23215986cbd53d027c34801236b55848654a3f7 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Thu, 27 Aug 2015 19:03:35 +0900 Subject: [PATCH 51/74] adding constructor/parenthesized type --- src/services/formatting/smartIndenter.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 012c73205f9..692c27cc751 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -432,9 +432,11 @@ namespace ts.formatting { case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: - case SyntaxKind.FunctionType: - case SyntaxKind.UnionType: case SyntaxKind.Parameter: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.UnionType: + case SyntaxKind.ParenthesizedType: case SyntaxKind.TaggedTemplateExpression: case SyntaxKind.AwaitExpression: return true; From 96174ba1a75f0fbab827b942c6eaa7a639c68619 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Thu, 27 Aug 2015 22:59:10 +0900 Subject: [PATCH 52/74] adding tests --- src/services/formatting/rules.ts | 25 ++++++++++----- src/services/formatting/smartIndenter.ts | 1 + tests/cases/fourslash/formatAsyncAwait.ts | 19 +++++++++++ .../formatFunctionAndConstructorType.ts | 32 +++++++++++++++++++ tests/cases/fourslash/formatParameter.ts | 23 +++++++++++++ tests/cases/fourslash/formatSignatures.ts | 31 ++++++++++++++++++ .../cases/fourslash/formatTemplateLiteral.ts | 17 +++++++++- tests/cases/fourslash/formatTypeAlias.ts | 14 ++++++++ tests/cases/fourslash/formatTypeUnion.ts | 14 ++++++++ .../cases/fourslash/formattingFunctionType.ts | 17 ---------- 10 files changed, 167 insertions(+), 26 deletions(-) create mode 100644 tests/cases/fourslash/formatAsyncAwait.ts create mode 100644 tests/cases/fourslash/formatFunctionAndConstructorType.ts create mode 100644 tests/cases/fourslash/formatParameter.ts create mode 100644 tests/cases/fourslash/formatSignatures.ts create mode 100644 tests/cases/fourslash/formatTypeAlias.ts create mode 100644 tests/cases/fourslash/formatTypeUnion.ts delete mode 100644 tests/cases/fourslash/formattingFunctionType.ts diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 92c27266818..f609edb0501 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -213,11 +213,15 @@ namespace ts.formatting { public NoSpaceBetweenYieldKeywordAndStar: Rule; public SpaceBetweenYieldOrYieldStarAndOperand: Rule; - // Await-async - public SpaceAfterAwaitKeyword: Rule; - public NoSpaceAfterAwaitKeyword: Rule; + // Async-await public SpaceBetweenAsyncAndFunctionKeyword: Rule; public NoSpaceBetweenAsyncAndFunctionKeyword: Rule; + public SpaceAfterAwaitKeyword: Rule; + public NoSpaceAfterAwaitKeyword: Rule; + + // Type alias declaration + public SpaceAfterTypeKeyword: Rule; + public NoSpaceAfterTypeKeyword: Rule; // Tagged template string public SpaceBetweenTagAndTemplateString: Rule; @@ -376,12 +380,16 @@ namespace ts.formatting { this.NoSpaceBetweenYieldKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Delete)); this.SpaceBetweenYieldOrYieldStarAndOperand = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Space)); - // Await-async - this.SpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + // Async-await this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); this.NoSpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); - + this.SpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceAfterAwaitKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.AwaitKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + + // Type alias declaration + this.SpaceAfterTypeKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.TypeKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceAfterTypeKeyword = new Rule(RuleDescriptor.create3(SyntaxKind.TypeKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + // template string this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); @@ -419,8 +427,9 @@ namespace ts.formatting { this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, - this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, + this.SpaceAfterTypeKeyword, this.NoSpaceAfterTypeKeyword, this.SpaceBetweenTagAndTemplateString, this.NoSpaceBetweenTagAndTemplateString, this.SpaceBeforeBar, this.NoSpaceBeforeBar, this.SpaceAfterBar, this.NoSpaceAfterBar, diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 692c27cc751..ebbf09e9feb 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -408,6 +408,7 @@ namespace ts.formatting { case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: + case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.Block: case SyntaxKind.ModuleBlock: diff --git a/tests/cases/fourslash/formatAsyncAwait.ts b/tests/cases/fourslash/formatAsyncAwait.ts new file mode 100644 index 00000000000..0530f868f91 --- /dev/null +++ b/tests/cases/fourslash/formatAsyncAwait.ts @@ -0,0 +1,19 @@ +/// + +////async function asyncFunction() {/*asyncKeyword*/ +//// await +/////*awaitExpressionIndent*/ +//// Promise.resolve("await");/*awaitExpressionAutoformat*/ +//// return await Promise.resolve("completed");/*awaitKeyword*/ +////} + +format.document(); + +goTo.marker("asyncKeyword"); +verify.currentLineContentIs("async function asyncFunction() {"); +goTo.marker("awaitExpressionIndent"); +verify.indentationIs(8); +goTo.marker("awaitExpressionAutoformat"); +verify.currentLineContentIs(' Promise.resolve("await");'); +goTo.marker("awaitKeyword"); +verify.currentLineContentIs(' return await Promise.resolve("completed");'); \ No newline at end of file diff --git a/tests/cases/fourslash/formatFunctionAndConstructorType.ts b/tests/cases/fourslash/formatFunctionAndConstructorType.ts new file mode 100644 index 00000000000..1b9655143f9 --- /dev/null +++ b/tests/cases/fourslash/formatFunctionAndConstructorType.ts @@ -0,0 +1,32 @@ +/// + +////function renderElement( +//// element: Element, +//// renderNode: +////(/*funcAutoformat*/ +//// node: Node/*funcParamAutoformat*/ +/////*funcIndent*/ +//// ) => void, +////newNode: +////new(/*constrAutoformat*/ +//// name: string/*constrParamAutoformat*/ +/////*constrIndent*/ +////) => Node +////): void { +////} + +format.document(); + +goTo.marker("funcAutoformat"); +verify.currentLineContentIs(" ("); +goTo.marker("funcParamAutoformat"); +verify.currentLineContentIs(" node: Node"); +goTo.marker("funcIndent"); +verify.indentationIs(12); + +goTo.marker("constrAutoformat"); +verify.currentLineContentIs(" new ("); +goTo.marker("constrParamAutoformat"); +verify.currentLineContentIs(" name: string"); +goTo.marker("constrIndent"); +verify.indentationIs(12); \ No newline at end of file diff --git a/tests/cases/fourslash/formatParameter.ts b/tests/cases/fourslash/formatParameter.ts new file mode 100644 index 00000000000..827de0edf58 --- /dev/null +++ b/tests/cases/fourslash/formatParameter.ts @@ -0,0 +1,23 @@ +/// + +////function foo( +//// first: +//// number,/*first*/ +//// second: ( +//// string/*second*/ +//// ), +//// third: +//// ( +//// boolean/*third*/ +//// ) +////) { +////} + +format.document(); + +goTo.marker("first"); +verify.currentLineContentIs(" number,"); +goTo.marker("second"); +verify.currentLineContentIs(" string"); +goTo.marker("third"); +verify.currentLineContentIs(" boolean"); \ No newline at end of file diff --git a/tests/cases/fourslash/formatSignatures.ts b/tests/cases/fourslash/formatSignatures.ts new file mode 100644 index 00000000000..f850ab48ef9 --- /dev/null +++ b/tests/cases/fourslash/formatSignatures.ts @@ -0,0 +1,31 @@ +/// + +////type Foo = { +//// ( +//// call: any/*callAutoformat*/ +/////*callIndent*/ +//// ): void; +//// new ( +//// constr: any/*constrAutoformat*/ +/////*constrIndent*/ +//// ): void; +//// method( +//// whatever: any/*methodAutoformat*/ +/////*methodIndent*/ +//// ): void; +////}; + +format.document(); + +goTo.marker("callAutoformat"); +verify.currentLineContentIs(" call: any"); +goTo.marker("callIndent"); +verify.indentationIs(8); +goTo.marker("constrAutoformat"); +verify.currentLineContentIs(" constr: any"); +goTo.marker("constrIndent"); +verify.indentationIs(8); +goTo.marker("methodAutoformat"); +verify.currentLineContentIs(" whatever: any"); +goTo.marker("methodIndent"); +verify.indentationIs(8); \ No newline at end of file diff --git a/tests/cases/fourslash/formatTemplateLiteral.ts b/tests/cases/fourslash/formatTemplateLiteral.ts index a1f5ef963da..29e58160cc1 100644 --- a/tests/cases/fourslash/formatTemplateLiteral.ts +++ b/tests/cases/fourslash/formatTemplateLiteral.ts @@ -2,6 +2,10 @@ ////var x = `sadasdasdasdasfegsfd /////*1*/rasdesgeryt35t35y35 e4 ergt er 35t 3535 `; ////var y = `1${2}/*2*/3`; +////let z= `foo`/*3*/ +////let w= `bar${3}`/*4*/ +////String.raw +//// `template`/*5*/ goTo.marker("1"); @@ -10,4 +14,15 @@ edit.insert("\r\n"); // edit will trigger formatting - should succeeed goTo.marker("2"); edit.insert("\r\n"); verify.indentationIs(0); -verify.currentLineContentIs("3`;") \ No newline at end of file +verify.currentLineContentIs("3`;") + +goTo.marker("3"); +edit.insert(";"); +verify.currentLineContentIs("let z = `foo`;"); +goTo.marker("4"); +edit.insert(";"); +verify.currentLineContentIs("let w = `bar${3}`;"); + +goTo.marker("5"); +edit.insert(";"); +verify.currentLineContentIs(" `template`;"); \ No newline at end of file diff --git a/tests/cases/fourslash/formatTypeAlias.ts b/tests/cases/fourslash/formatTypeAlias.ts new file mode 100644 index 00000000000..c97a868c1f1 --- /dev/null +++ b/tests/cases/fourslash/formatTypeAlias.ts @@ -0,0 +1,14 @@ +/// + +////type Alias = /*typeKeyword*/ +/////*indent*/ +////number;/*autoformat*/ + +format.document(); + +goTo.marker("typeKeyword"); +verify.currentLineContentIs("type Alias ="); +goTo.marker("indent"); +verify.indentationIs(4); +goTo.marker("autoformat"); +verify.currentLineContentIs(" number;"); diff --git a/tests/cases/fourslash/formatTypeUnion.ts b/tests/cases/fourslash/formatTypeUnion.ts new file mode 100644 index 00000000000..267ba656612 --- /dev/null +++ b/tests/cases/fourslash/formatTypeUnion.ts @@ -0,0 +1,14 @@ +/// + +////type Union = number | {}/*formatOperator*/ +/////*indent*/ +////|string/*autoformat*/ + +format.document(); + +goTo.marker("formatOperator"); +verify.currentLineContentIs("type Union = number | {}"); +goTo.marker("indent"); +verify.indentationIs(4); +goTo.marker("autoformat"); +verify.currentLineContentIs(" | string"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingFunctionType.ts b/tests/cases/fourslash/formattingFunctionType.ts deleted file mode 100644 index 0e63292b5ed..00000000000 --- a/tests/cases/fourslash/formattingFunctionType.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// - -////function renderElement( -//// element: Element, -//// renderNode: ( -//// node: Node/*paramInFuntionType*/ -/////*paramIndent*/ -//// ) => void -////): void { -////} - -format.document(); - -goTo.marker("paramInFuntionType"); -verify.currentLineContentIs(" node: Node"); -goTo.marker("paramIndent"); -verify.indentationIs(8); \ No newline at end of file From 69249cbed726c60a1bc900f9ff72c9e2e44b8d5e Mon Sep 17 00:00:00 2001 From: Jason Killian Date: Thu, 27 Aug 2015 11:36:57 -0400 Subject: [PATCH 53/74] Propagate namespace flag to namespaces nested with dot syntax --- src/compiler/parser.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 25b38277991..3ece155a8c6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4941,12 +4941,13 @@ namespace ts { function parseModuleOrNamespaceDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { let node = createNode(SyntaxKind.ModuleDeclaration, fullStart); + let namespaceFlag = flags & NodeFlags.Namespace; node.decorators = decorators; setModifiers(node, modifiers); node.flags |= flags; node.name = parseIdentifier(); node.body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.Export) + ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.Export | namespaceFlag) : parseModuleBlock(); return finishNode(node); } From 4db535d9497d4edffbbe840473c704c71ba0fc50 Mon Sep 17 00:00:00 2001 From: Jason Killian Date: Thu, 27 Aug 2015 14:04:00 -0400 Subject: [PATCH 54/74] Add comment --- src/compiler/parser.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3ece155a8c6..350b9d450b8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4941,6 +4941,8 @@ namespace ts { function parseModuleOrNamespaceDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { let node = createNode(SyntaxKind.ModuleDeclaration, fullStart); + // If we are parsing a dotted namespace name, we want to + // propagate the 'Namespace' flag across the names if set. let namespaceFlag = flags & NodeFlags.Namespace; node.decorators = decorators; setModifiers(node, modifiers); From ff47fa124ae08278ce9e5a5997e373dfa22b1e80 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Aug 2015 12:52:34 -0700 Subject: [PATCH 55/74] Property check expressions in class extends clause --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 73fa64ed499..5d0c0cd7ffc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12613,6 +12613,7 @@ namespace ts { if (baseTypes.length && produceDiagnostics) { let baseType = baseTypes[0]; let staticBaseType = getBaseConstructorTypeOfClass(type); + checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { forEach(baseTypeNode.typeArguments, checkSourceElement); for (let constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments)) { @@ -13682,6 +13683,8 @@ namespace ts { case SyntaxKind.VariableDeclaration: case SyntaxKind.VariableDeclarationList: case SyntaxKind.ClassDeclaration: + case SyntaxKind.HeritageClause: + case SyntaxKind.ExpressionWithTypeArguments: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: case SyntaxKind.ExportAssignment: From 08f4f3774c26b7604fd7d0161179ba8800068560 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 12:53:17 -0700 Subject: [PATCH 56/74] Fixes declaration emit for a class that extends null --- src/compiler/declarationEmitter.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 85513e8719f..e5914d10060 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -896,6 +896,9 @@ namespace ts { if (isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; From bff8caa54cd9cc944eabbc213946a8a06e4f455b Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 27 Aug 2015 13:15:03 -0700 Subject: [PATCH 57/74] Add class expression if existed to classifiable-name map --- src/compiler/binder.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 340bf478209..16f2a59a58d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -973,6 +973,10 @@ namespace ts { else { let bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); + // Add name of class expression into the map for semantic classifier + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } let symbol = node.symbol; @@ -1062,4 +1066,4 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } -} +} From 4c516264694de09714482c64342f41f0fb1079d9 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 27 Aug 2015 13:16:10 -0700 Subject: [PATCH 58/74] Add tests --- .../semanticClassificationClassExpression.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/cases/fourslash/semanticClassificationClassExpression.ts diff --git a/tests/cases/fourslash/semanticClassificationClassExpression.ts b/tests/cases/fourslash/semanticClassificationClassExpression.ts new file mode 100644 index 00000000000..f067265df29 --- /dev/null +++ b/tests/cases/fourslash/semanticClassificationClassExpression.ts @@ -0,0 +1,12 @@ +/// + +//// var x = class /*0*/C {} +//// class /*1*/C {} +//// class /*2*/D extends class /*3*/B{} { } +var c = classification; +verify.semanticClassificationsAre( + c.className("C", test.marker("0").position), + c.className("C", test.marker("1").position), + c.className("D", test.marker("2").position), + c.className("B", test.marker("3").position) +); \ No newline at end of file From 67b00feadfcf35db86cf850efd959142d8b40f26 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 13:31:31 -0700 Subject: [PATCH 59/74] Added test --- .../reference/declFileClassExtendsNull.js | 23 +++++++++++++++++++ .../declFileClassExtendsNull.symbols | 5 ++++ .../reference/declFileClassExtendsNull.types | 6 +++++ .../compiler/declFileClassExtendsNull.ts | 5 ++++ 4 files changed, 39 insertions(+) create mode 100644 tests/baselines/reference/declFileClassExtendsNull.js create mode 100644 tests/baselines/reference/declFileClassExtendsNull.symbols create mode 100644 tests/baselines/reference/declFileClassExtendsNull.types create mode 100644 tests/cases/compiler/declFileClassExtendsNull.ts diff --git a/tests/baselines/reference/declFileClassExtendsNull.js b/tests/baselines/reference/declFileClassExtendsNull.js new file mode 100644 index 00000000000..0d50b320592 --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.js @@ -0,0 +1,23 @@ +//// [declFileClassExtendsNull.ts] + +class ExtendsNull extends null { +} + +//// [declFileClassExtendsNull.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ExtendsNull = (function (_super) { + __extends(ExtendsNull, _super); + function ExtendsNull() { + _super.apply(this, arguments); + } + return ExtendsNull; +})(null); + + +//// [declFileClassExtendsNull.d.ts] +declare class ExtendsNull extends null { +} diff --git a/tests/baselines/reference/declFileClassExtendsNull.symbols b/tests/baselines/reference/declFileClassExtendsNull.symbols new file mode 100644 index 00000000000..e86276faad8 --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/declFileClassExtendsNull.ts === + +class ExtendsNull extends null { +>ExtendsNull : Symbol(ExtendsNull, Decl(declFileClassExtendsNull.ts, 0, 0)) +} diff --git a/tests/baselines/reference/declFileClassExtendsNull.types b/tests/baselines/reference/declFileClassExtendsNull.types new file mode 100644 index 00000000000..bbd43d99c0d --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/declFileClassExtendsNull.ts === + +class ExtendsNull extends null { +>ExtendsNull : ExtendsNull +>null : null +} diff --git a/tests/cases/compiler/declFileClassExtendsNull.ts b/tests/cases/compiler/declFileClassExtendsNull.ts new file mode 100644 index 00000000000..d21fd5d3805 --- /dev/null +++ b/tests/cases/compiler/declFileClassExtendsNull.ts @@ -0,0 +1,5 @@ +// @target: ES5 +// @declaration: true + +class ExtendsNull extends null { +} \ No newline at end of file From 945eb1145d0a02e8bea13288733fdaef60979259 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 27 Aug 2015 13:48:25 -0700 Subject: [PATCH 60/74] Revert change to the harness that break the unittest --- src/harness/harness.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5cde3ad3647..ac392df513f 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1415,7 +1415,16 @@ module Harness { assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName); }); - assert.equal(totalErrorsReported, diagnostics.length, "total number of errors"); + let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { + return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName)); + }); + + let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { + // Count an error generated from tests262-harness folder.This should only apply for test262 + return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; + }); + + assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } From 5f3c7623aac953a22e913226796222a4968feea2 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 27 Aug 2015 13:15:03 -0700 Subject: [PATCH 61/74] Add class expression if existed to classifiable-name map --- src/compiler/binder.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 340bf478209..16f2a59a58d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -973,6 +973,10 @@ namespace ts { else { let bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); + // Add name of class expression into the map for semantic classifier + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } let symbol = node.symbol; @@ -1062,4 +1066,4 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } -} +} From 2ef73db4986b91be16448ed8ef47c5b71a0df4a2 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 27 Aug 2015 13:16:10 -0700 Subject: [PATCH 62/74] Add tests --- .../semanticClassificationClassExpression.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/cases/fourslash/semanticClassificationClassExpression.ts diff --git a/tests/cases/fourslash/semanticClassificationClassExpression.ts b/tests/cases/fourslash/semanticClassificationClassExpression.ts new file mode 100644 index 00000000000..f067265df29 --- /dev/null +++ b/tests/cases/fourslash/semanticClassificationClassExpression.ts @@ -0,0 +1,12 @@ +/// + +//// var x = class /*0*/C {} +//// class /*1*/C {} +//// class /*2*/D extends class /*3*/B{} { } +var c = classification; +verify.semanticClassificationsAre( + c.className("C", test.marker("0").position), + c.className("C", test.marker("1").position), + c.className("D", test.marker("2").position), + c.className("B", test.marker("3").position) +); \ No newline at end of file From e9dc96598cd635265881104b08b4a4120b43f845 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 14:03:19 -0700 Subject: [PATCH 63/74] Update LKG --- lib/lib.d.ts | 25 ++- lib/lib.dom.d.ts | 24 ++- lib/lib.es6.d.ts | 25 ++- lib/lib.webworker.d.ts | 21 ++- lib/tsc.js | 161 +++++++++++++++- lib/tsserver.js | 336 +++++++++++++++++++++++++++++---- lib/typescript.d.ts | 8 + lib/typescript.js | 357 ++++++++++++++++++++++++++++++++---- lib/typescriptServices.d.ts | 8 + lib/typescriptServices.js | 357 ++++++++++++++++++++++++++++++++---- 10 files changed, 1197 insertions(+), 125 deletions(-) diff --git a/lib/lib.d.ts b/lib/lib.d.ts index 7a411e002fa..c55970d9aca 100644 --- a/lib/lib.d.ts +++ b/lib/lib.d.ts @@ -6929,6 +6929,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -7916,7 +7917,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -11719,7 +11719,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -12461,7 +12461,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -16628,7 +16628,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -16645,6 +16644,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -16974,8 +16988,7 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any, declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; ///////////////////////////// /// WorkerGlobalScope APIs ///////////////////////////// diff --git a/lib/lib.dom.d.ts b/lib/lib.dom.d.ts index 896db2d55ef..54461afef40 100644 --- a/lib/lib.dom.d.ts +++ b/lib/lib.dom.d.ts @@ -3105,6 +3105,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -4092,7 +4093,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -7895,7 +7895,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -8637,7 +8637,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -12804,7 +12804,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -12821,6 +12820,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -13150,4 +13164,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any, declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index 02b89b3a2ba..de051a44edd 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -8217,6 +8217,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -9204,7 +9205,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -13007,7 +13007,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -13749,7 +13749,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -17916,7 +17916,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -17933,6 +17932,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -18262,8 +18276,7 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any, declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -interface DOMTokenList { +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;interface DOMTokenList { [Symbol.iterator](): IterableIterator; } diff --git a/lib/lib.webworker.d.ts b/lib/lib.webworker.d.ts index ed9f18e8dae..0f3e85da9f1 100644 --- a/lib/lib.webworker.d.ts +++ b/lib/lib.webworker.d.ts @@ -776,7 +776,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -829,7 +829,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface WebSocket extends EventTarget { @@ -1100,6 +1100,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -1156,4 +1171,4 @@ declare function postMessage(data: any): void; declare var console: Console; declare function addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; declare function addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file diff --git a/lib/tsc.js b/lib/tsc.js index eb2a963b828..f9ce3ad9023 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -1569,6 +1569,7 @@ var ts; Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -4482,6 +4483,7 @@ var ts; case 134: return node === parent_2.expression; case 137: + case 238: return true; case 186: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -9823,7 +9825,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -11681,7 +11682,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { + if (targetSymbol.flags & 32 || targetSymbol.flags & 64 || targetSymbol.flags & 524288) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -18860,9 +18861,13 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 149) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455, undefined, undefined); - if (rootSymbol && rootSymbol.flags & 8388608 && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 ? 793056 : 1536; + var rootSymbol = resolveName(root, root.text, meaning | 8388608, undefined, undefined); + if (rootSymbol && rootSymbol.flags & 8388608) { + var aliasTarget = resolveAlias(rootSymbol); + if (aliasTarget.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -21147,6 +21152,9 @@ var ts; return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } var typeSymbol = resolveEntityName(typeName, 793056, true); + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -23011,6 +23019,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; if (node.parent.parent.kind === 212) { @@ -24708,7 +24719,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2) { @@ -24733,6 +24749,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -28558,7 +28577,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; for (var i = 0; i < text.length; i++) { @@ -29362,10 +29381,124 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 ? 2 : 1; + switch (moduleResolution) { + case 2: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46); + } + function useBaseUrl(moduleName) { + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; } @@ -29398,6 +29531,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -30262,6 +30396,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2, + "classic": 1 + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { diff --git a/lib/tsserver.js b/lib/tsserver.js index 6fdd0b20f39..e01d4f0527e 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1569,6 +1569,7 @@ var ts; Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -3200,6 +3201,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2, + "classic": 1 + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -4203,6 +4213,7 @@ var ts; case 134: return node === parent_2.expression; case 137: + case 238: return true; case 186: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -9544,7 +9555,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -12113,7 +12123,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { + if (targetSymbol.flags & 32 || targetSymbol.flags & 64 || targetSymbol.flags & 524288) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -19292,9 +19302,13 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 149) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455, undefined, undefined); - if (rootSymbol && rootSymbol.flags & 8388608 && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 ? 793056 : 1536; + var rootSymbol = resolveName(root, root.text, meaning | 8388608, undefined, undefined); + if (rootSymbol && rootSymbol.flags & 8388608) { + var aliasTarget = resolveAlias(rootSymbol); + if (aliasTarget.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -21579,6 +21593,9 @@ var ts; return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } var typeSymbol = resolveEntityName(typeName, 793056, true); + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -23443,6 +23460,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; if (node.parent.parent.kind === 212) { @@ -25140,7 +25160,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2) { @@ -25165,6 +25190,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -28990,7 +29018,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; for (var i = 0; i < text.length; i++) { @@ -29794,10 +29822,124 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 ? 2 : 1; + switch (moduleResolution) { + case 2: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46); + } + function useBaseUrl(moduleName) { + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; } @@ -29830,6 +29972,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -32608,6 +32751,34 @@ var ts; } } ts.hasDocComment = hasDocComment; + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100: + case 106: + case 72: + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { return n.getWidth() !== 0; } @@ -35172,6 +35343,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2, true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -36883,6 +37093,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -36890,8 +37101,33 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64) { + isJsDocTagName = true; + } + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267: + case 265: + case 266: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -36954,7 +37190,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { isMemberCompletion = true; isNewIdentifierLocation = false; @@ -37247,9 +37483,10 @@ var ts; containingNodeKind === 215 || isFunction(containingNodeKind) || containingNodeKind === 212 || - containingNodeKind === 211 || + containingNodeKind === 184 || containingNodeKind === 213 || - containingNodeKind === 160; + containingNodeKind === 160 || + containingNodeKind === 214; case 21: return containingNodeKind === 160; case 53: @@ -37270,8 +37507,9 @@ var ts; contextToken.parent.parent.kind === 153); case 25: return containingNodeKind === 212 || - containingNodeKind === 211 || + containingNodeKind === 184 || containingNodeKind === 213 || + containingNodeKind === 214 || isFunction(containingNodeKind); case 111: return containingNodeKind === 139; @@ -37383,8 +37621,11 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -37395,7 +37636,7 @@ var ts; } entries = getCompletionEntriesFromSymbols(symbols); } - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -37424,6 +37665,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { var displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, true, location); if (!displayName) { @@ -37698,6 +37949,7 @@ var ts; displayParts.push(ts.keywordPart(130)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55)); displayParts.push(ts.spacePart()); @@ -37736,16 +37988,26 @@ var ts; writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration); } else { - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146) { - displayParts.push(ts.keywordPart(90)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146) { + displayParts.push(ts.keywordPart(90)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32)); + } + else { + var declaration = ts.getDeclarationOfKind(symbol, 135).parent; + displayParts.push(ts.keywordPart(130)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32)); } } if (symbolFlags & 8) { @@ -37951,9 +38213,13 @@ var ts; function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) { if (isNewExpressionTarget(location) || location.kind === 119) { if (symbol.flags & 32) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212); - return tryAddSignature(classDeclaration.members, true, symbolKind, symbolName, containerName, result); + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; @@ -42229,13 +42495,15 @@ var ts; info = this.openFile(fileName, false); } else { - if (this.openFileRoots.indexOf(info) >= 0) { - this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + if (info.isOpen) { + if (this.openFileRoots.indexOf(info) >= 0) { + this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + } + if (this.openFilesReferenced.indexOf(info) >= 0) { + this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); + } + this.openFileRootsConfigured.push(info); } - if (this.openFilesReferenced.indexOf(info) >= 0) { - this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); - } - this.openFileRootsConfigured.push(info); } project.addRoot(info); } diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index edeb166cf88..604bdbf373a 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1293,6 +1293,10 @@ declare module "typescript" { Error = 1, Message = 2, } + const enum ModuleResolutionKind { + Classic = 1, + NodeJs = 2, + } interface CompilerOptions { allowNonTsExtensions?: boolean; charset?: string; @@ -1332,6 +1336,7 @@ declare module "typescript" { experimentalDecorators?: boolean; experimentalAsyncFunctions?: boolean; emitDecoratorMetadata?: boolean; + moduleResolution?: ModuleResolutionKind; [option: string]: string | number | boolean; } const enum ModuleKind { @@ -1509,6 +1514,9 @@ declare module "typescript" { function findConfigFile(searchPath: string): string; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; + function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule; + function baseUrlModuleNameResolver(moduleName: string, containingFile: string, baseUrl: string, host: ModuleResolutionHost): ResolvedModule; + function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; diff --git a/lib/typescript.js b/lib/typescript.js index 9507f25db63..bcb172085b0 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -644,6 +644,11 @@ var ts; DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message"; })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {})); var DiagnosticCategory = ts.DiagnosticCategory; + (function (ModuleResolutionKind) { + ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic"; + ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs"; + })(ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {})); + var ModuleResolutionKind = ts.ModuleResolutionKind; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS"; @@ -2433,6 +2438,7 @@ var ts; Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -5832,6 +5838,7 @@ var ts; case 134 /* ComputedPropertyName */: return node === parent_2.expression; case 137 /* Decorator */: + case 238 /* JsxExpression */: return true; case 186 /* ExpressionWithTypeArguments */: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -12258,7 +12265,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -14561,7 +14567,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { + if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -23164,9 +23170,16 @@ var ts; // serialize the type metadata. if (node && node.kind === 149 /* TypeReference */) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); - if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */ && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */; + // Resolve type so we know which symbol is referenced + var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); + // Resolved symbol is alias + if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) { + var aliasTarget = resolveAlias(rootSymbol); + // If alias has value symbol - mark alias as referenced + if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -25835,6 +25848,10 @@ var ts; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. var typeSymbol = resolveEntityName(typeName, 793056 /* Type */, /*ignoreErrors*/ true); + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -27820,6 +27837,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91 /* NullKeyword */) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; // Heritage clause is written by user so it can always be named @@ -29775,7 +29795,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2 /* ES6 */) { @@ -29800,6 +29825,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -34261,7 +34289,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, /*includeTrivia*/ true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; // JSX trims whitespace at the end and beginning of lines, except that the @@ -34312,7 +34340,7 @@ var ts; } case 1 /* Preserve */: default: - return ts.getTextOfNode(node, true); + return ts.getTextOfNode(node, /*includeTrivia*/ true); } } function emitJsxText(node) { @@ -34324,7 +34352,7 @@ var ts; break; case 1 /* Preserve */: default: - writer.writeLiteral(ts.getTextOfNode(node, true)); + writer.writeLiteral(ts.getTextOfNode(node, /*includeTrivia*/ true)); break; } } @@ -35124,11 +35152,128 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - // TODO: use different resolution strategy based on compiler options - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 /* CommonJS */ ? 2 /* NodeJs */ : 1 /* Classic */; + switch (moduleResolution) { + case 2 /* NodeJs */: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1 /* Classic */: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + // gracefully handle if readFile fails or returns not JSON + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46 /* dot */); + } + function useBaseUrl(moduleName) { + // path is not rooted + // module name does not start with './' or '../' + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { // module names that contain '!' are used to reference resources and are not resolved to actual files on disk if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; @@ -35164,6 +35309,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36103,6 +36249,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2 /* NodeJs */, + "classic": 1 /* Classic */ + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -38656,6 +38811,38 @@ var ts; } } ts.hasDocComment = hasDocComment; + /** + * Get the corresponding JSDocTag node if the position is in a jsDoc comment + */ + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100 /* VarKeyword */: + case 106 /* LetKeyword */: + case 72 /* ConstKeyword */: + // if the current token is var, let or const, skip the VariableDeclarationList + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. @@ -41591,6 +41778,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -43614,6 +43840,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -43622,8 +43849,40 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64 /* at */) { + isJsDocTagName = true; + } + // Completion should work inside certain JsDoc tags. For example: + // /** @type {number | string} */ + // Completion should work in the brackets + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267 /* JSDocTypeTag */: + case 265 /* JSDocParameterTag */: + case 266 /* JSDocReturnTag */: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal + // comment or the plain text part of a jsDoc comment, so no completion should be available + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -43699,7 +43958,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { // Right of dot member completion list isMemberCompletion = true; @@ -44083,9 +44342,10 @@ var ts; containingNodeKind === 215 /* EnumDeclaration */ || isFunction(containingNodeKind) || containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || - containingNodeKind === 160 /* ArrayBindingPattern */; // var [x, y| + containingNodeKind === 160 /* ArrayBindingPattern */ || + containingNodeKind === 214 /* TypeAliasDeclaration */; // type Map, K, | case 21 /* DotToken */: return containingNodeKind === 160 /* ArrayBindingPattern */; // var [.| case 53 /* ColonToken */: @@ -44106,8 +44366,9 @@ var ts; contextToken.parent.parent.kind === 153 /* TypeLiteral */); // let x : { a; | case 25 /* LessThanToken */: return containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || + containingNodeKind === 214 /* TypeAliasDeclaration */ || isFunction(containingNodeKind); case 111 /* StaticKeyword */: return containingNodeKind === 139 /* PropertyDeclaration */; @@ -44248,8 +44509,12 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -44261,7 +44526,7 @@ var ts; entries = getCompletionEntriesFromSymbols(symbols); } // Add keywords if this is not a member completion list - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -44290,6 +44555,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can @@ -44601,6 +44876,7 @@ var ts; displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55 /* EqualsToken */)); displayParts.push(ts.spacePart()); @@ -44641,16 +44917,29 @@ var ts; } else { // Method/function type parameter - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146 /* ConstructSignature */) { - displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146 /* ConstructSignature */) { + displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); + } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + var declaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); } } if (symbolFlags & 8 /* EnumMember */) { @@ -44863,9 +45152,15 @@ var ts; // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === 119 /* ConstructorKeyword */) { if (symbol.flags & 32 /* Class */) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212 /* ClassDeclaration */); - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + // Find the first class-like declaration and try to get the construct signature. + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 890c77e5ae7..7ea3324afe0 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1293,6 +1293,10 @@ declare namespace ts { Error = 1, Message = 2, } + const enum ModuleResolutionKind { + Classic = 1, + NodeJs = 2, + } interface CompilerOptions { allowNonTsExtensions?: boolean; charset?: string; @@ -1332,6 +1336,7 @@ declare namespace ts { experimentalDecorators?: boolean; experimentalAsyncFunctions?: boolean; emitDecoratorMetadata?: boolean; + moduleResolution?: ModuleResolutionKind; [option: string]: string | number | boolean; } const enum ModuleKind { @@ -1509,6 +1514,9 @@ declare namespace ts { function findConfigFile(searchPath: string): string; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; + function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule; + function baseUrlModuleNameResolver(moduleName: string, containingFile: string, baseUrl: string, host: ModuleResolutionHost): ResolvedModule; + function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 9507f25db63..bcb172085b0 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -644,6 +644,11 @@ var ts; DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message"; })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {})); var DiagnosticCategory = ts.DiagnosticCategory; + (function (ModuleResolutionKind) { + ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic"; + ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs"; + })(ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {})); + var ModuleResolutionKind = ts.ModuleResolutionKind; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS"; @@ -2433,6 +2438,7 @@ var ts; Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -5832,6 +5838,7 @@ var ts; case 134 /* ComputedPropertyName */: return node === parent_2.expression; case 137 /* Decorator */: + case 238 /* JsxExpression */: return true; case 186 /* ExpressionWithTypeArguments */: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -12258,7 +12265,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -14561,7 +14567,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { + if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -23164,9 +23170,16 @@ var ts; // serialize the type metadata. if (node && node.kind === 149 /* TypeReference */) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); - if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */ && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */; + // Resolve type so we know which symbol is referenced + var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); + // Resolved symbol is alias + if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) { + var aliasTarget = resolveAlias(rootSymbol); + // If alias has value symbol - mark alias as referenced + if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -25835,6 +25848,10 @@ var ts; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. var typeSymbol = resolveEntityName(typeName, 793056 /* Type */, /*ignoreErrors*/ true); + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -27820,6 +27837,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91 /* NullKeyword */) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; // Heritage clause is written by user so it can always be named @@ -29775,7 +29795,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2 /* ES6 */) { @@ -29800,6 +29825,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -34261,7 +34289,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, /*includeTrivia*/ true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; // JSX trims whitespace at the end and beginning of lines, except that the @@ -34312,7 +34340,7 @@ var ts; } case 1 /* Preserve */: default: - return ts.getTextOfNode(node, true); + return ts.getTextOfNode(node, /*includeTrivia*/ true); } } function emitJsxText(node) { @@ -34324,7 +34352,7 @@ var ts; break; case 1 /* Preserve */: default: - writer.writeLiteral(ts.getTextOfNode(node, true)); + writer.writeLiteral(ts.getTextOfNode(node, /*includeTrivia*/ true)); break; } } @@ -35124,11 +35152,128 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - // TODO: use different resolution strategy based on compiler options - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 /* CommonJS */ ? 2 /* NodeJs */ : 1 /* Classic */; + switch (moduleResolution) { + case 2 /* NodeJs */: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1 /* Classic */: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + // gracefully handle if readFile fails or returns not JSON + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46 /* dot */); + } + function useBaseUrl(moduleName) { + // path is not rooted + // module name does not start with './' or '../' + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { // module names that contain '!' are used to reference resources and are not resolved to actual files on disk if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; @@ -35164,6 +35309,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36103,6 +36249,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2 /* NodeJs */, + "classic": 1 /* Classic */ + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -38656,6 +38811,38 @@ var ts; } } ts.hasDocComment = hasDocComment; + /** + * Get the corresponding JSDocTag node if the position is in a jsDoc comment + */ + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100 /* VarKeyword */: + case 106 /* LetKeyword */: + case 72 /* ConstKeyword */: + // if the current token is var, let or const, skip the VariableDeclarationList + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. @@ -41591,6 +41778,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -43614,6 +43840,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -43622,8 +43849,40 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64 /* at */) { + isJsDocTagName = true; + } + // Completion should work inside certain JsDoc tags. For example: + // /** @type {number | string} */ + // Completion should work in the brackets + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267 /* JSDocTypeTag */: + case 265 /* JSDocParameterTag */: + case 266 /* JSDocReturnTag */: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal + // comment or the plain text part of a jsDoc comment, so no completion should be available + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -43699,7 +43958,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { // Right of dot member completion list isMemberCompletion = true; @@ -44083,9 +44342,10 @@ var ts; containingNodeKind === 215 /* EnumDeclaration */ || isFunction(containingNodeKind) || containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || - containingNodeKind === 160 /* ArrayBindingPattern */; // var [x, y| + containingNodeKind === 160 /* ArrayBindingPattern */ || + containingNodeKind === 214 /* TypeAliasDeclaration */; // type Map, K, | case 21 /* DotToken */: return containingNodeKind === 160 /* ArrayBindingPattern */; // var [.| case 53 /* ColonToken */: @@ -44106,8 +44366,9 @@ var ts; contextToken.parent.parent.kind === 153 /* TypeLiteral */); // let x : { a; | case 25 /* LessThanToken */: return containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || + containingNodeKind === 214 /* TypeAliasDeclaration */ || isFunction(containingNodeKind); case 111 /* StaticKeyword */: return containingNodeKind === 139 /* PropertyDeclaration */; @@ -44248,8 +44509,12 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -44261,7 +44526,7 @@ var ts; entries = getCompletionEntriesFromSymbols(symbols); } // Add keywords if this is not a member completion list - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -44290,6 +44555,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can @@ -44601,6 +44876,7 @@ var ts; displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55 /* EqualsToken */)); displayParts.push(ts.spacePart()); @@ -44641,16 +44917,29 @@ var ts; } else { // Method/function type parameter - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146 /* ConstructSignature */) { - displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146 /* ConstructSignature */) { + displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); + } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + var declaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); } } if (symbolFlags & 8 /* EnumMember */) { @@ -44863,9 +45152,15 @@ var ts; // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === 119 /* ConstructorKeyword */) { if (symbol.flags & 32 /* Class */) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212 /* ClassDeclaration */); - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + // Find the first class-like declaration and try to get the construct signature. + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; From 175b9bf96f0a14270d5d8185790056a869f075c9 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 14:06:06 -0700 Subject: [PATCH 64/74] Adds a "typings" property to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 166b73b4a9c..abd81e12f47 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "url": "https://github.com/Microsoft/TypeScript.git" }, "main": "./lib/typescript.js", + "typings": "./lib/typescript.d.ts", "bin": { "tsc": "./bin/tsc", "tsserver": "./bin/tsserver" From c0267ec8e1ad2f4c07d50375a01cf869ff59dbf0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Aug 2015 14:22:42 -0700 Subject: [PATCH 65/74] Adding test --- ...singPropertiesOfClassExpression.errors.txt | 12 +++++++++ .../missingPropertiesOfClassExpression.js | 26 +++++++++++++++++++ .../missingPropertiesOfClassExpression.ts | 5 ++++ 3 files changed, 43 insertions(+) create mode 100644 tests/baselines/reference/missingPropertiesOfClassExpression.errors.txt create mode 100644 tests/baselines/reference/missingPropertiesOfClassExpression.js create mode 100644 tests/cases/compiler/missingPropertiesOfClassExpression.ts diff --git a/tests/baselines/reference/missingPropertiesOfClassExpression.errors.txt b/tests/baselines/reference/missingPropertiesOfClassExpression.errors.txt new file mode 100644 index 00000000000..b7331a68271 --- /dev/null +++ b/tests/baselines/reference/missingPropertiesOfClassExpression.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/missingPropertiesOfClassExpression.ts(1,52): error TS2339: Property 'y' does not exist on type '(Anonymous class)'. + + +==== tests/cases/compiler/missingPropertiesOfClassExpression.ts (1 errors) ==== + class George extends class { reset() { return this.y; } } { + ~ +!!! error TS2339: Property 'y' does not exist on type '(Anonymous class)'. + constructor() { + super(); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/missingPropertiesOfClassExpression.js b/tests/baselines/reference/missingPropertiesOfClassExpression.js new file mode 100644 index 00000000000..f427da20f0c --- /dev/null +++ b/tests/baselines/reference/missingPropertiesOfClassExpression.js @@ -0,0 +1,26 @@ +//// [missingPropertiesOfClassExpression.ts] +class George extends class { reset() { return this.y; } } { + constructor() { + super(); + } +} + + +//// [missingPropertiesOfClassExpression.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var George = (function (_super) { + __extends(George, _super); + function George() { + _super.call(this); + } + return George; +})((function () { + function class_1() { + } + class_1.prototype.reset = function () { return this.y; }; + return class_1; +})()); diff --git a/tests/cases/compiler/missingPropertiesOfClassExpression.ts b/tests/cases/compiler/missingPropertiesOfClassExpression.ts new file mode 100644 index 00000000000..a1d91355365 --- /dev/null +++ b/tests/cases/compiler/missingPropertiesOfClassExpression.ts @@ -0,0 +1,5 @@ +class George extends class { reset() { return this.y; } } { + constructor() { + super(); + } +} From 89ac1940ee002c85a1120118cadf9774d7f806e8 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 12:53:17 -0700 Subject: [PATCH 66/74] Fixes declaration emit for a class that extends null --- src/compiler/declarationEmitter.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 85513e8719f..e5914d10060 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -896,6 +896,9 @@ namespace ts { if (isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; From 481c18c8925f2db2eea41da5d187915d0110e4f7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 13:31:31 -0700 Subject: [PATCH 67/74] Added test --- .../reference/declFileClassExtendsNull.js | 23 +++++++++++++++++++ .../declFileClassExtendsNull.symbols | 5 ++++ .../reference/declFileClassExtendsNull.types | 6 +++++ .../compiler/declFileClassExtendsNull.ts | 5 ++++ 4 files changed, 39 insertions(+) create mode 100644 tests/baselines/reference/declFileClassExtendsNull.js create mode 100644 tests/baselines/reference/declFileClassExtendsNull.symbols create mode 100644 tests/baselines/reference/declFileClassExtendsNull.types create mode 100644 tests/cases/compiler/declFileClassExtendsNull.ts diff --git a/tests/baselines/reference/declFileClassExtendsNull.js b/tests/baselines/reference/declFileClassExtendsNull.js new file mode 100644 index 00000000000..0d50b320592 --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.js @@ -0,0 +1,23 @@ +//// [declFileClassExtendsNull.ts] + +class ExtendsNull extends null { +} + +//// [declFileClassExtendsNull.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ExtendsNull = (function (_super) { + __extends(ExtendsNull, _super); + function ExtendsNull() { + _super.apply(this, arguments); + } + return ExtendsNull; +})(null); + + +//// [declFileClassExtendsNull.d.ts] +declare class ExtendsNull extends null { +} diff --git a/tests/baselines/reference/declFileClassExtendsNull.symbols b/tests/baselines/reference/declFileClassExtendsNull.symbols new file mode 100644 index 00000000000..e86276faad8 --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/declFileClassExtendsNull.ts === + +class ExtendsNull extends null { +>ExtendsNull : Symbol(ExtendsNull, Decl(declFileClassExtendsNull.ts, 0, 0)) +} diff --git a/tests/baselines/reference/declFileClassExtendsNull.types b/tests/baselines/reference/declFileClassExtendsNull.types new file mode 100644 index 00000000000..bbd43d99c0d --- /dev/null +++ b/tests/baselines/reference/declFileClassExtendsNull.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/declFileClassExtendsNull.ts === + +class ExtendsNull extends null { +>ExtendsNull : ExtendsNull +>null : null +} diff --git a/tests/cases/compiler/declFileClassExtendsNull.ts b/tests/cases/compiler/declFileClassExtendsNull.ts new file mode 100644 index 00000000000..d21fd5d3805 --- /dev/null +++ b/tests/cases/compiler/declFileClassExtendsNull.ts @@ -0,0 +1,5 @@ +// @target: ES5 +// @declaration: true + +class ExtendsNull extends null { +} \ No newline at end of file From e0f9d3d04b57385a5095250b5fc2a705bce94ed2 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 14:06:06 -0700 Subject: [PATCH 68/74] Adds a "typings" property to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9ec67593c90..b743b04838d 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "url": "https://github.com/Microsoft/TypeScript.git" }, "main": "./lib/typescript.js", + "typings": "./lib/typescript.d.ts", "bin": { "tsc": "./bin/tsc", "tsserver": "./bin/tsserver" From 3d5f73b1f78b0ff4a92441b78ca921b88bce8a29 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 27 Aug 2015 15:26:29 -0700 Subject: [PATCH 69/74] Update LKG --- lib/tsc.js | 119 ++++++++++++++++++++++++++++++++---- lib/tsserver.js | 90 ++++++++++++++++++++++----- lib/typescript.d.ts | 1 + lib/typescript.js | 103 +++++++++++++++++++++++++------ lib/typescriptServices.d.ts | 1 + lib/typescriptServices.js | 103 +++++++++++++++++++++++++------ 6 files changed, 357 insertions(+), 60 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index f9ce3ad9023..0ccb839c2ef 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -1429,7 +1429,7 @@ var ts; JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: ts.DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: ts.DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: ts.DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." }, Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: ts.DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -1515,6 +1515,7 @@ var ts; Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: ts.DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." }, Option_0_cannot_be_specified_with_option_1: { code: 5053, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." }, + A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: ts.DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: ts.DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -1570,6 +1571,8 @@ var ts; Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, + Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, + Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -3630,6 +3633,9 @@ var ts; else { var bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, 32, bindingName); + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } var symbol = node.symbol; var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); @@ -13825,6 +13831,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.instantiations) { + var cachedType = mapper.instantiations[type.id]; + if (cachedType) { + return cachedType; + } + } + else { + mapper.instantiations = []; + } var result = createObjectType(65536 | 131072, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -13836,6 +13851,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.instantiations[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -20063,7 +20079,7 @@ var ts; } if (!isDefinedBefore(propertyDecl, member)) { reportError = false; - error(e, ts.Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); + error(e, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return undefined; } return getNodeLinks(propertyDecl).enumMemberValue; @@ -23679,11 +23695,7 @@ var ts; } function emitJavaScript(jsFilePath, root) { var writer = ts.createTextWriter(newLine); - var write = writer.write; - var writeTextOfNode = writer.writeTextOfNode; - var writeLine = writer.writeLine; - var increaseIndent = writer.increaseIndent; - var decreaseIndent = writer.decreaseIndent; + var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent; var currentSourceFile; var exportFunctionForFile; var generatedNameSet = {}; @@ -29350,6 +29362,7 @@ var ts; })(ts || (ts = {})); /// /// +/// var ts; (function (ts) { ts.programTime = 0; @@ -29532,6 +29545,14 @@ var ts; return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } ts.classicNameResolver = classicNameResolver; + ts.defaultInitCompilerOptions = { + module: 1, + target: 0, + noImplicitAny: false, + outDir: "built", + rootDir: ".", + sourceMap: false + }; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -30202,6 +30223,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "init", + type: "boolean", + description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file + }, { name: "inlineSourceMap", type: "boolean" @@ -30407,18 +30433,28 @@ var ts; description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; - function parseCommandLine(commandLine) { - var options = {}; - var fileNames = []; - var errors = []; - var shortOptionNames = {}; + var optionNameMapCache; + function getOptionNameMap() { + if (optionNameMapCache) { + return optionNameMapCache; + } var optionNameMap = {}; + var shortOptionNames = {}; ts.forEach(ts.optionDeclarations, function (option) { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { shortOptionNames[option.shortName] = option.name; } }); + optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames }; + return optionNameMapCache; + } + ts.getOptionNameMap = getOptionNameMap; + function parseCommandLine(commandLine) { + var options = {}; + var fileNames = []; + var errors = []; + var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames; parseStrings(commandLine); return { options: options, @@ -30734,6 +30770,10 @@ var ts; reportDiagnostics(commandLine.errors); return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } + if (commandLine.options.init) { + writeConfigFile(commandLine.options, commandLine.fileNames); + return ts.sys.exit(ts.ExitStatus.Success); + } if (commandLine.options.version) { reportDiagnostic(ts.createCompilerDiagnostic(ts.Diagnostics.Version_0, ts.version)); return ts.sys.exit(ts.ExitStatus.Success); @@ -30975,5 +31015,60 @@ var ts; return Array(paddingLength + 1).join(" "); } } + function writeConfigFile(options, fileNames) { + var currentDirectory = ts.sys.getCurrentDirectory(); + var file = ts.combinePaths(currentDirectory, 'tsconfig.json'); + if (ts.sys.fileExists(file)) { + reportDiagnostic(ts.createCompilerDiagnostic(ts.Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file)); + } + else { + var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions); + var configurations = { + compilerOptions: serializeCompilerOptions(compilerOptions), + exclude: ["node_modules"] + }; + if (fileNames && fileNames.length) { + configurations.files = fileNames; + } + ts.sys.writeFile(file, JSON.stringify(configurations, undefined, 4)); + reportDiagnostic(ts.createCompilerDiagnostic(ts.Diagnostics.Successfully_created_a_tsconfig_json_file)); + } + return; + function serializeCompilerOptions(options) { + var result = {}; + var optionsNameMap = ts.getOptionNameMap().optionNameMap; + for (var name_28 in options) { + if (ts.hasProperty(options, name_28)) { + var value = options[name_28]; + switch (name_28) { + case "init": + case "watch": + case "version": + case "help": + case "project": + break; + default: + var optionDefinition = optionsNameMap[name_28.toLowerCase()]; + if (optionDefinition) { + if (typeof optionDefinition.type === "string") { + result[name_28] = value; + } + else { + var typeMap = optionDefinition.type; + for (var key in typeMap) { + if (ts.hasProperty(typeMap, key)) { + if (typeMap[key] === value) + result[name_28] = key; + } + } + } + } + break; + } + } + } + return result; + } + } })(ts || (ts = {})); ts.executeCommandLine(ts.sys.args); diff --git a/lib/tsserver.js b/lib/tsserver.js index e01d4f0527e..3c339e6d661 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1429,7 +1429,7 @@ var ts; JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: ts.DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: ts.DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: ts.DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." }, Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: ts.DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -1515,6 +1515,7 @@ var ts; Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: ts.DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." }, Option_0_cannot_be_specified_with_option_1: { code: 5053, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." }, + A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: ts.DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: ts.DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -1570,6 +1571,8 @@ var ts; Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, + Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, + Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -3007,6 +3010,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "init", + type: "boolean", + description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file + }, { name: "inlineSourceMap", type: "boolean" @@ -3212,18 +3220,28 @@ var ts; description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; - function parseCommandLine(commandLine) { - var options = {}; - var fileNames = []; - var errors = []; - var shortOptionNames = {}; + var optionNameMapCache; + function getOptionNameMap() { + if (optionNameMapCache) { + return optionNameMapCache; + } var optionNameMap = {}; + var shortOptionNames = {}; ts.forEach(ts.optionDeclarations, function (option) { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { shortOptionNames[option.shortName] = option.name; } }); + optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames }; + return optionNameMapCache; + } + ts.getOptionNameMap = getOptionNameMap; + function parseCommandLine(commandLine) { + var options = {}; + var fileNames = []; + var errors = []; + var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames; parseStrings(commandLine); return { options: options, @@ -10585,6 +10603,9 @@ var ts; else { var bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, 32, bindingName); + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } var symbol = node.symbol; var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); @@ -14266,6 +14287,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.instantiations) { + var cachedType = mapper.instantiations[type.id]; + if (cachedType) { + return cachedType; + } + } + else { + mapper.instantiations = []; + } var result = createObjectType(65536 | 131072, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -14277,6 +14307,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.instantiations[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -20504,7 +20535,7 @@ var ts; } if (!isDefinedBefore(propertyDecl, member)) { reportError = false; - error(e, ts.Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); + error(e, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return undefined; } return getNodeLinks(propertyDecl).enumMemberValue; @@ -24120,11 +24151,7 @@ var ts; } function emitJavaScript(jsFilePath, root) { var writer = ts.createTextWriter(newLine); - var write = writer.write; - var writeTextOfNode = writer.writeTextOfNode; - var writeLine = writer.writeLine; - var increaseIndent = writer.increaseIndent; - var decreaseIndent = writer.decreaseIndent; + var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent; var currentSourceFile; var exportFunctionForFile; var generatedNameSet = {}; @@ -29791,6 +29818,7 @@ var ts; })(ts || (ts = {})); /// /// +/// var ts; (function (ts) { ts.programTime = 0; @@ -29973,6 +30001,14 @@ var ts; return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } ts.classicNameResolver = classicNameResolver; + ts.defaultInitCompilerOptions = { + module: 1, + target: 0, + noImplicitAny: false, + outDir: "built", + rootDir: ".", + sourceMap: false + }; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -33520,6 +33556,18 @@ var ts; this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(37, formatting.Shared.TokenRange.FromTokens([67, 17])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2)); this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(112, 37), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8)); this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([112, 37]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2)); + this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116, 85), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116, 85), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.SpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.SpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.SpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67, formatting.Shared.TokenRange.FromTokens([11, 12])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67, formatting.Shared.TokenRange.FromTokens([11, 12])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.SpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.SpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); + this.NoSpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); this.HighPriorityCommonRules = [ this.IgnoreBeforeComment, this.IgnoreAfterLineComment, @@ -33545,6 +33593,11 @@ var ts; this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, + this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, + this.SpaceAfterTypeKeyword, this.NoSpaceAfterTypeKeyword, + this.SpaceBetweenTagAndTemplateString, this.NoSpaceBetweenTagAndTemplateString, + this.SpaceBeforeBar, this.NoSpaceBeforeBar, this.SpaceAfterBar, this.NoSpaceAfterBar, this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, this.SpaceAfterModuleName, @@ -35247,6 +35300,7 @@ var ts; case 212: case 213: case 215: + case 214: case 162: case 190: case 217: @@ -35268,6 +35322,16 @@ var ts; case 160: case 159: case 231: + case 140: + case 145: + case 146: + case 136: + case 150: + case 151: + case 156: + case 158: + case 168: + case 176: return true; } return false; @@ -35286,8 +35350,6 @@ var ts; case 211: case 171: case 141: - case 140: - case 145: case 172: case 142: case 143: diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 604bdbf373a..f94d24269f1 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1304,6 +1304,7 @@ declare module "typescript" { diagnostics?: boolean; emitBOM?: boolean; help?: boolean; + init?: boolean; inlineSourceMap?: boolean; inlineSources?: boolean; jsx?: JsxEmit; diff --git a/lib/typescript.js b/lib/typescript.js index bcb172085b0..c1105bb262a 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -2298,7 +2298,7 @@ var ts; JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: ts.DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: ts.DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: ts.DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." }, Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: ts.DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -2384,6 +2384,7 @@ var ts; Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: ts.DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." }, Option_0_cannot_be_specified_with_option_1: { code: 5053, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." }, + A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: ts.DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: ts.DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -2439,6 +2440,8 @@ var ts; Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, + Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, + Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -4855,6 +4858,10 @@ var ts; else { var bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, 32 /* Class */, bindingName); + // Add name of class expression into the map for semantic classifier + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } var symbol = node.symbol; // TypeScript 1.0 spec (April 2014): 8.4 @@ -16963,6 +16970,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.instantiations) { + var cachedType = mapper.instantiations[type.id]; + if (cachedType) { + return cachedType; + } + } + else { + mapper.instantiations = []; + } // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it var result = createObjectType(65536 /* Anonymous */ | 131072 /* Instantiated */, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); @@ -16975,6 +16991,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.instantiations[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -24634,7 +24651,7 @@ var ts; // illegal case: forward reference if (!isDefinedBefore(propertyDecl, member)) { reportError = false; - error(e, ts.Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); + error(e, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return undefined; } return getNodeLinks(propertyDecl).enumMemberValue; @@ -28581,11 +28598,7 @@ var ts; } function emitJavaScript(jsFilePath, root) { var writer = ts.createTextWriter(newLine); - var write = writer.write; - var writeTextOfNode = writer.writeTextOfNode; - var writeLine = writer.writeLine; - var increaseIndent = writer.increaseIndent; - var decreaseIndent = writer.decreaseIndent; + var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent; var currentSourceFile; // name of an exporter function if file is a System external module // System.register([...], function () {...}) @@ -31169,7 +31182,7 @@ var ts; if (compilerOptions.module === 1 /* CommonJS */ || compilerOptions.module === 2 /* AMD */ || compilerOptions.module === 3 /* UMD */) { if (!currentSourceFile.symbol.exports["___esModule"]) { if (languageVersion === 1 /* ES5 */) { - // default value of configurable, enumerable, writable are `false`. + // default value of configurable, enumerable, writable are `false`. write("Object.defineProperty(exports, \"__esModule\", { value: true });"); writeLine(); } @@ -32840,7 +32853,7 @@ var ts; // * The serialized type of an AccessorDeclaration is the serialized type of the return type annotation of its getter or parameter type annotation of its setter. // * The serialized type of any other FunctionLikeDeclaration is "Function". // * The serialized type of any other node is "void 0". - // + // // For rules on serializing type annotations, see `serializeTypeNode`. switch (node.kind) { case 212 /* ClassDeclaration */: @@ -32974,7 +32987,7 @@ var ts; // // * If the declaration is a class, the parameters of the first constructor with a body are used. // * If the declaration is function-like and has a body, the parameters of the function are used. - // + // // For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`. if (node) { var valueDeclaration; @@ -35120,6 +35133,7 @@ var ts; })(ts || (ts = {})); /// /// +/// var ts; (function (ts) { /* @internal */ ts.programTime = 0; @@ -35310,6 +35324,15 @@ var ts; return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } ts.classicNameResolver = classicNameResolver; + /* @internal */ + ts.defaultInitCompilerOptions = { + module: 1 /* CommonJS */, + target: 0 /* ES3 */, + noImplicitAny: false, + outDir: "built", + rootDir: ".", + sourceMap: false + }; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36054,6 +36077,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "init", + type: "boolean", + description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file + }, { name: "inlineSourceMap", type: "boolean" @@ -36260,18 +36288,29 @@ var ts; description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; - function parseCommandLine(commandLine) { - var options = {}; - var fileNames = []; - var errors = []; - var shortOptionNames = {}; + var optionNameMapCache; + /* @internal */ + function getOptionNameMap() { + if (optionNameMapCache) { + return optionNameMapCache; + } var optionNameMap = {}; + var shortOptionNames = {}; ts.forEach(ts.optionDeclarations, function (option) { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { shortOptionNames[option.shortName] = option.name; } }); + optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames }; + return optionNameMapCache; + } + ts.getOptionNameMap = getOptionNameMap; + function parseCommandLine(commandLine) { + var options = {}; + var fileNames = []; + var errors = []; + var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames; parseStrings(commandLine); return { options: options, @@ -39710,6 +39749,22 @@ var ts; this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(37 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([67 /* Identifier */, 17 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */)); this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(112 /* YieldKeyword */, 37 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */)); this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([112 /* YieldKeyword */, 37 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */)); + // Async-await + this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* AsyncKeyword */, 85 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* AsyncKeyword */, 85 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.SpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117 /* AwaitKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117 /* AwaitKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // Type alias declaration + this.SpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130 /* TypeKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130 /* TypeKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // template string + this.SpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67 /* Identifier */, formatting.Shared.TokenRange.FromTokens([11 /* NoSubstitutionTemplateLiteral */, 12 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67 /* Identifier */, formatting.Shared.TokenRange.FromTokens([11 /* NoSubstitutionTemplateLiteral */, 12 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // union type + this.SpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46 /* BarToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46 /* BarToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.SpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46 /* BarToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46 /* BarToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -39736,6 +39791,11 @@ var ts; this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, + this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, + this.SpaceAfterTypeKeyword, this.NoSpaceAfterTypeKeyword, + this.SpaceBetweenTagAndTemplateString, this.NoSpaceBetweenTagAndTemplateString, + this.SpaceBeforeBar, this.NoSpaceBeforeBar, this.SpaceAfterBar, this.NoSpaceAfterBar, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, @@ -41679,6 +41739,7 @@ var ts; case 212 /* ClassDeclaration */: case 213 /* InterfaceDeclaration */: case 215 /* EnumDeclaration */: + case 214 /* TypeAliasDeclaration */: case 162 /* ArrayLiteralExpression */: case 190 /* Block */: case 217 /* ModuleBlock */: @@ -41700,6 +41761,16 @@ var ts; case 160 /* ArrayBindingPattern */: case 159 /* ObjectBindingPattern */: case 231 /* JsxElement */: + case 140 /* MethodSignature */: + case 145 /* CallSignature */: + case 146 /* ConstructSignature */: + case 136 /* Parameter */: + case 150 /* FunctionType */: + case 151 /* ConstructorType */: + case 156 /* UnionType */: + case 158 /* ParenthesizedType */: + case 168 /* TaggedTemplateExpression */: + case 176 /* AwaitExpression */: return true; } return false; @@ -41718,8 +41789,6 @@ var ts; case 211 /* FunctionDeclaration */: case 171 /* FunctionExpression */: case 141 /* MethodDeclaration */: - case 140 /* MethodSignature */: - case 145 /* CallSignature */: case 172 /* ArrowFunction */: case 142 /* Constructor */: case 143 /* GetAccessor */: diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 7ea3324afe0..812305c8a68 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1304,6 +1304,7 @@ declare namespace ts { diagnostics?: boolean; emitBOM?: boolean; help?: boolean; + init?: boolean; inlineSourceMap?: boolean; inlineSources?: boolean; jsx?: JsxEmit; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index bcb172085b0..c1105bb262a 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -2298,7 +2298,7 @@ var ts; JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: ts.DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: ts.DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: ts.DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." }, Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: ts.DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -2384,6 +2384,7 @@ var ts; Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: ts.DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." }, Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." }, Option_0_cannot_be_specified_with_option_1: { code: 5053, category: ts.DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." }, + A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: ts.DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: ts.DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, @@ -2439,6 +2440,8 @@ var ts; Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, + Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, + Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -4855,6 +4858,10 @@ var ts; else { var bindingName = node.name ? node.name.text : "__class"; bindAnonymousDeclaration(node, 32 /* Class */, bindingName); + // Add name of class expression into the map for semantic classifier + if (node.name) { + classifiableNames[node.name.text] = node.name.text; + } } var symbol = node.symbol; // TypeScript 1.0 spec (April 2014): 8.4 @@ -16963,6 +16970,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.instantiations) { + var cachedType = mapper.instantiations[type.id]; + if (cachedType) { + return cachedType; + } + } + else { + mapper.instantiations = []; + } // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it var result = createObjectType(65536 /* Anonymous */ | 131072 /* Instantiated */, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); @@ -16975,6 +16991,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.instantiations[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -24634,7 +24651,7 @@ var ts; // illegal case: forward reference if (!isDefinedBefore(propertyDecl, member)) { reportError = false; - error(e, ts.Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); + error(e, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return undefined; } return getNodeLinks(propertyDecl).enumMemberValue; @@ -28581,11 +28598,7 @@ var ts; } function emitJavaScript(jsFilePath, root) { var writer = ts.createTextWriter(newLine); - var write = writer.write; - var writeTextOfNode = writer.writeTextOfNode; - var writeLine = writer.writeLine; - var increaseIndent = writer.increaseIndent; - var decreaseIndent = writer.decreaseIndent; + var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent; var currentSourceFile; // name of an exporter function if file is a System external module // System.register([...], function () {...}) @@ -31169,7 +31182,7 @@ var ts; if (compilerOptions.module === 1 /* CommonJS */ || compilerOptions.module === 2 /* AMD */ || compilerOptions.module === 3 /* UMD */) { if (!currentSourceFile.symbol.exports["___esModule"]) { if (languageVersion === 1 /* ES5 */) { - // default value of configurable, enumerable, writable are `false`. + // default value of configurable, enumerable, writable are `false`. write("Object.defineProperty(exports, \"__esModule\", { value: true });"); writeLine(); } @@ -32840,7 +32853,7 @@ var ts; // * The serialized type of an AccessorDeclaration is the serialized type of the return type annotation of its getter or parameter type annotation of its setter. // * The serialized type of any other FunctionLikeDeclaration is "Function". // * The serialized type of any other node is "void 0". - // + // // For rules on serializing type annotations, see `serializeTypeNode`. switch (node.kind) { case 212 /* ClassDeclaration */: @@ -32974,7 +32987,7 @@ var ts; // // * If the declaration is a class, the parameters of the first constructor with a body are used. // * If the declaration is function-like and has a body, the parameters of the function are used. - // + // // For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`. if (node) { var valueDeclaration; @@ -35120,6 +35133,7 @@ var ts; })(ts || (ts = {})); /// /// +/// var ts; (function (ts) { /* @internal */ ts.programTime = 0; @@ -35310,6 +35324,15 @@ var ts; return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } ts.classicNameResolver = classicNameResolver; + /* @internal */ + ts.defaultInitCompilerOptions = { + module: 1 /* CommonJS */, + target: 0 /* ES3 */, + noImplicitAny: false, + outDir: "built", + rootDir: ".", + sourceMap: false + }; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36054,6 +36077,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "init", + type: "boolean", + description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file + }, { name: "inlineSourceMap", type: "boolean" @@ -36260,18 +36288,29 @@ var ts; description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; - function parseCommandLine(commandLine) { - var options = {}; - var fileNames = []; - var errors = []; - var shortOptionNames = {}; + var optionNameMapCache; + /* @internal */ + function getOptionNameMap() { + if (optionNameMapCache) { + return optionNameMapCache; + } var optionNameMap = {}; + var shortOptionNames = {}; ts.forEach(ts.optionDeclarations, function (option) { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { shortOptionNames[option.shortName] = option.name; } }); + optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames }; + return optionNameMapCache; + } + ts.getOptionNameMap = getOptionNameMap; + function parseCommandLine(commandLine) { + var options = {}; + var fileNames = []; + var errors = []; + var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames; parseStrings(commandLine); return { options: options, @@ -39710,6 +39749,22 @@ var ts; this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(37 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([67 /* Identifier */, 17 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */)); this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(112 /* YieldKeyword */, 37 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */)); this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([112 /* YieldKeyword */, 37 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */)); + // Async-await + this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* AsyncKeyword */, 85 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(116 /* AsyncKeyword */, 85 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.SpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117 /* AwaitKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterAwaitKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(117 /* AwaitKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // Type alias declaration + this.SpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130 /* TypeKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterTypeKeyword = new formatting.Rule(formatting.RuleDescriptor.create3(130 /* TypeKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // template string + this.SpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67 /* Identifier */, formatting.Shared.TokenRange.FromTokens([11 /* NoSubstitutionTemplateLiteral */, 12 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(67 /* Identifier */, formatting.Shared.TokenRange.FromTokens([11 /* NoSubstitutionTemplateLiteral */, 12 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + // union type + this.SpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46 /* BarToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceBeforeBar = new formatting.Rule(formatting.RuleDescriptor.create3(46 /* BarToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.SpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46 /* BarToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); + this.NoSpaceAfterBar = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 46 /* BarToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -39736,6 +39791,11 @@ var ts; this.NoSpaceBeforeOpenParenInFuncCall, this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, + this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenAsyncAndFunctionKeyword, + this.SpaceAfterAwaitKeyword, this.NoSpaceAfterAwaitKeyword, + this.SpaceAfterTypeKeyword, this.NoSpaceAfterTypeKeyword, + this.SpaceBetweenTagAndTemplateString, this.NoSpaceBetweenTagAndTemplateString, + this.SpaceBeforeBar, this.NoSpaceBeforeBar, this.SpaceAfterBar, this.NoSpaceAfterBar, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, @@ -41679,6 +41739,7 @@ var ts; case 212 /* ClassDeclaration */: case 213 /* InterfaceDeclaration */: case 215 /* EnumDeclaration */: + case 214 /* TypeAliasDeclaration */: case 162 /* ArrayLiteralExpression */: case 190 /* Block */: case 217 /* ModuleBlock */: @@ -41700,6 +41761,16 @@ var ts; case 160 /* ArrayBindingPattern */: case 159 /* ObjectBindingPattern */: case 231 /* JsxElement */: + case 140 /* MethodSignature */: + case 145 /* CallSignature */: + case 146 /* ConstructSignature */: + case 136 /* Parameter */: + case 150 /* FunctionType */: + case 151 /* ConstructorType */: + case 156 /* UnionType */: + case 158 /* ParenthesizedType */: + case 168 /* TaggedTemplateExpression */: + case 176 /* AwaitExpression */: return true; } return false; @@ -41718,8 +41789,6 @@ var ts; case 211 /* FunctionDeclaration */: case 171 /* FunctionExpression */: case 141 /* MethodDeclaration */: - case 140 /* MethodSignature */: - case 145 /* CallSignature */: case 172 /* ArrowFunction */: case 142 /* Constructor */: case 143 /* GetAccessor */: From 6fbf4494b532080889daabaea3f2e189bfa16d67 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 27 Aug 2015 15:46:25 -0700 Subject: [PATCH 70/74] Update version to 1.7 --- src/compiler/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index a1861f6b462..402b413dd9c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -12,7 +12,7 @@ namespace ts { let emptyArray: any[] = []; - export const version = "1.6.0"; + export const version = "1.7.0"; export function findConfigFile(searchPath: string): string { let fileName = "tsconfig.json"; From 98de9de2816295fec775d3bc0ef9f279d6356a17 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Aug 2015 15:59:00 -0700 Subject: [PATCH 71/74] No deduplication in union of tuple element types --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d9a36c34cdf..43856b535e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3119,7 +3119,7 @@ namespace ts { } function resolveTupleTypeMembers(type: TupleType) { - let arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes))); + let arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, /*noDeduplication*/ true))); let members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType); From 1b08f8adc9ae1fcccd6f6e6e7fadff715ed2e038 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Aug 2015 16:12:04 -0700 Subject: [PATCH 72/74] Adding tests --- tests/cases/compiler/recursiveTupleTypes1.ts | 12 ++++++++++++ tests/cases/compiler/recursiveTupleTypes2.ts | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/cases/compiler/recursiveTupleTypes1.ts create mode 100644 tests/cases/compiler/recursiveTupleTypes2.ts diff --git a/tests/cases/compiler/recursiveTupleTypes1.ts b/tests/cases/compiler/recursiveTupleTypes1.ts new file mode 100644 index 00000000000..82559eccfad --- /dev/null +++ b/tests/cases/compiler/recursiveTupleTypes1.ts @@ -0,0 +1,12 @@ +interface Tree1 { + children: [Tree1, Tree2]; +} + +interface Tree2 { + children: [Tree2, Tree1]; +} + +let tree1: Tree1; +let tree2: Tree2; +tree1 = tree2; +tree2 = tree1; diff --git a/tests/cases/compiler/recursiveTupleTypes2.ts b/tests/cases/compiler/recursiveTupleTypes2.ts new file mode 100644 index 00000000000..78c8efa82a4 --- /dev/null +++ b/tests/cases/compiler/recursiveTupleTypes2.ts @@ -0,0 +1,12 @@ +interface Tree1 { + children: [Tree1, Tree2]; +} + +interface Tree2 { + children: [Tree2, Tree2]; +} + +let tree1: Tree1; +let tree2: Tree2; +tree1 = tree2; +tree2 = tree1; From e6dc58efb9e00824c29c50c46bc6f80a01b1b1f6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Aug 2015 16:12:31 -0700 Subject: [PATCH 73/74] Accepting new baselines --- .../reference/recursiveTupleTypes1.js | 20 ++++++++++ .../reference/recursiveTupleTypes1.symbols | 35 ++++++++++++++++++ .../reference/recursiveTupleTypes1.types | 37 +++++++++++++++++++ .../reference/recursiveTupleTypes2.js | 20 ++++++++++ .../reference/recursiveTupleTypes2.symbols | 35 ++++++++++++++++++ .../reference/recursiveTupleTypes2.types | 37 +++++++++++++++++++ 6 files changed, 184 insertions(+) create mode 100644 tests/baselines/reference/recursiveTupleTypes1.js create mode 100644 tests/baselines/reference/recursiveTupleTypes1.symbols create mode 100644 tests/baselines/reference/recursiveTupleTypes1.types create mode 100644 tests/baselines/reference/recursiveTupleTypes2.js create mode 100644 tests/baselines/reference/recursiveTupleTypes2.symbols create mode 100644 tests/baselines/reference/recursiveTupleTypes2.types diff --git a/tests/baselines/reference/recursiveTupleTypes1.js b/tests/baselines/reference/recursiveTupleTypes1.js new file mode 100644 index 00000000000..f4fa8ef4816 --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes1.js @@ -0,0 +1,20 @@ +//// [recursiveTupleTypes1.ts] +interface Tree1 { + children: [Tree1, Tree2]; +} + +interface Tree2 { + children: [Tree2, Tree1]; +} + +let tree1: Tree1; +let tree2: Tree2; +tree1 = tree2; +tree2 = tree1; + + +//// [recursiveTupleTypes1.js] +var tree1; +var tree2; +tree1 = tree2; +tree2 = tree1; diff --git a/tests/baselines/reference/recursiveTupleTypes1.symbols b/tests/baselines/reference/recursiveTupleTypes1.symbols new file mode 100644 index 00000000000..8bd0797f3f6 --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes1.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/recursiveTupleTypes1.ts === +interface Tree1 { +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes1.ts, 0, 0)) + + children: [Tree1, Tree2]; +>children : Symbol(children, Decl(recursiveTupleTypes1.ts, 0, 17)) +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes1.ts, 0, 0)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes1.ts, 2, 1)) +} + +interface Tree2 { +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes1.ts, 2, 1)) + + children: [Tree2, Tree1]; +>children : Symbol(children, Decl(recursiveTupleTypes1.ts, 4, 17)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes1.ts, 2, 1)) +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes1.ts, 0, 0)) +} + +let tree1: Tree1; +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes1.ts, 8, 3)) +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes1.ts, 0, 0)) + +let tree2: Tree2; +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes1.ts, 9, 3)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes1.ts, 2, 1)) + +tree1 = tree2; +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes1.ts, 8, 3)) +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes1.ts, 9, 3)) + +tree2 = tree1; +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes1.ts, 9, 3)) +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes1.ts, 8, 3)) + diff --git a/tests/baselines/reference/recursiveTupleTypes1.types b/tests/baselines/reference/recursiveTupleTypes1.types new file mode 100644 index 00000000000..9dfdc768ddb --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes1.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/recursiveTupleTypes1.ts === +interface Tree1 { +>Tree1 : Tree1 + + children: [Tree1, Tree2]; +>children : [Tree1, Tree2] +>Tree1 : Tree1 +>Tree2 : Tree2 +} + +interface Tree2 { +>Tree2 : Tree2 + + children: [Tree2, Tree1]; +>children : [Tree2, Tree1] +>Tree2 : Tree2 +>Tree1 : Tree1 +} + +let tree1: Tree1; +>tree1 : Tree1 +>Tree1 : Tree1 + +let tree2: Tree2; +>tree2 : Tree2 +>Tree2 : Tree2 + +tree1 = tree2; +>tree1 = tree2 : Tree2 +>tree1 : Tree1 +>tree2 : Tree2 + +tree2 = tree1; +>tree2 = tree1 : Tree1 +>tree2 : Tree2 +>tree1 : Tree1 + diff --git a/tests/baselines/reference/recursiveTupleTypes2.js b/tests/baselines/reference/recursiveTupleTypes2.js new file mode 100644 index 00000000000..60dde8ef4d5 --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes2.js @@ -0,0 +1,20 @@ +//// [recursiveTupleTypes2.ts] +interface Tree1 { + children: [Tree1, Tree2]; +} + +interface Tree2 { + children: [Tree2, Tree2]; +} + +let tree1: Tree1; +let tree2: Tree2; +tree1 = tree2; +tree2 = tree1; + + +//// [recursiveTupleTypes2.js] +var tree1; +var tree2; +tree1 = tree2; +tree2 = tree1; diff --git a/tests/baselines/reference/recursiveTupleTypes2.symbols b/tests/baselines/reference/recursiveTupleTypes2.symbols new file mode 100644 index 00000000000..2895f1b5669 --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes2.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/recursiveTupleTypes2.ts === +interface Tree1 { +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes2.ts, 0, 0)) + + children: [Tree1, Tree2]; +>children : Symbol(children, Decl(recursiveTupleTypes2.ts, 0, 17)) +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes2.ts, 0, 0)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes2.ts, 2, 1)) +} + +interface Tree2 { +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes2.ts, 2, 1)) + + children: [Tree2, Tree2]; +>children : Symbol(children, Decl(recursiveTupleTypes2.ts, 4, 17)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes2.ts, 2, 1)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes2.ts, 2, 1)) +} + +let tree1: Tree1; +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes2.ts, 8, 3)) +>Tree1 : Symbol(Tree1, Decl(recursiveTupleTypes2.ts, 0, 0)) + +let tree2: Tree2; +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes2.ts, 9, 3)) +>Tree2 : Symbol(Tree2, Decl(recursiveTupleTypes2.ts, 2, 1)) + +tree1 = tree2; +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes2.ts, 8, 3)) +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes2.ts, 9, 3)) + +tree2 = tree1; +>tree2 : Symbol(tree2, Decl(recursiveTupleTypes2.ts, 9, 3)) +>tree1 : Symbol(tree1, Decl(recursiveTupleTypes2.ts, 8, 3)) + diff --git a/tests/baselines/reference/recursiveTupleTypes2.types b/tests/baselines/reference/recursiveTupleTypes2.types new file mode 100644 index 00000000000..9ce8e5daf79 --- /dev/null +++ b/tests/baselines/reference/recursiveTupleTypes2.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/recursiveTupleTypes2.ts === +interface Tree1 { +>Tree1 : Tree1 + + children: [Tree1, Tree2]; +>children : [Tree1, Tree2] +>Tree1 : Tree1 +>Tree2 : Tree2 +} + +interface Tree2 { +>Tree2 : Tree2 + + children: [Tree2, Tree2]; +>children : [Tree2, Tree2] +>Tree2 : Tree2 +>Tree2 : Tree2 +} + +let tree1: Tree1; +>tree1 : Tree1 +>Tree1 : Tree1 + +let tree2: Tree2; +>tree2 : Tree2 +>Tree2 : Tree2 + +tree1 = tree2; +>tree1 = tree2 : Tree2 +>tree1 : Tree1 +>tree2 : Tree2 + +tree2 = tree1; +>tree2 = tree1 : Tree1 +>tree2 : Tree2 +>tree1 : Tree1 + From be8f17c5d7352d5f6f2e8b6718867374a06a5a2d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 27 Aug 2015 18:16:22 -0700 Subject: [PATCH 74/74] Merge pull request #4488 from Microsoft/fixRWC Move RWC runner to use Harness.IO instead of sys --- src/compiler/commandLineParser.ts | 6 ++--- src/harness/harness.ts | 40 ++++++++++++++++++++------- src/harness/loggedIO.ts | 34 +++++++++++++---------- src/harness/rwcRunner.ts | 45 +++++++++++++------------------ 4 files changed, 73 insertions(+), 52 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index df94ce33631..1a0c971001e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -274,7 +274,7 @@ namespace ts { return optionNameMapCache; } - export function parseCommandLine(commandLine: string[]): ParsedCommandLine { + export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine { let options: CompilerOptions = {}; let fileNames: string[] = []; let errors: Diagnostic[] = []; @@ -343,7 +343,7 @@ namespace ts { } function parseResponseFile(fileName: string) { - let text = sys.readFile(fileName); + let text = readFile ? readFile(fileName) : sys.readFile(fileName); if (!text) { errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, fileName)); @@ -496,4 +496,4 @@ namespace ts { return fileNames; } } -} +} \ No newline at end of file diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 6c6d913b7a6..f65a4f88730 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -425,6 +425,9 @@ module Harness { listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[]; log(text: string): void; getMemoryUsage?(): number; + args(): string[]; + getExecutingFilePath(): string; + exit(exitCode?: number): void; } export var IO: IO; @@ -446,7 +449,10 @@ module Harness { } else { fso = {}; } - + + export const args = () => ts.sys.args; + export const getExecutingFilePath = () => ts.sys.getExecutingFilePath(); + export const exit = (exitCode: number) => ts.sys.exit(exitCode); export const resolvePath = (path: string) => ts.sys.resolvePath(path); export const getCurrentDirectory = () => ts.sys.getCurrentDirectory(); export const newLine = () => harnessNewLine; @@ -517,6 +523,9 @@ module Harness { export const getCurrentDirectory = () => ts.sys.getCurrentDirectory(); export const newLine = () => harnessNewLine; export const useCaseSensitiveFileNames = () => ts.sys.useCaseSensitiveFileNames; + export const args = () => ts.sys.args; + export const getExecutingFilePath = () => ts.sys.getExecutingFilePath(); + export const exit = (exitCode: number) => ts.sys.exit(exitCode); export const readFile: typeof IO.readFile = path => ts.sys.readFile(path); export const writeFile: typeof IO.writeFile = (path, content) => ts.sys.writeFile(path, content); @@ -589,6 +598,10 @@ module Harness { export const newLine = () => harnessNewLine; export const useCaseSensitiveFileNames = () => false; export const getCurrentDirectory = () => ""; + export const args = () => []; + export const getExecutingFilePath = () => ""; + export const exit = (exitCode: number) => {}; + let supportsCodePage = () => false; module Http { @@ -1331,8 +1344,8 @@ module Harness { export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) { diagnostics.sort(ts.compareDiagnostics); let outputLines: string[] = []; - // Count up all the errors we find so we don't miss any - let totalErrorsReported = 0; + // Count up all errors that were found in files other than lib.d.ts so we don't miss any + let totalErrorsReportedInNonLibraryFiles = 0; function outputErrorText(error: ts.Diagnostic) { let message = ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine()); @@ -1343,8 +1356,15 @@ module Harness { .filter(s => s.length > 0) .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); errLines.forEach(e => outputLines.push(e)); - - totalErrorsReported++; + + // do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics + // if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers) + // then they will be added twice thus triggering 'total errors' assertion with condition + // 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length + + if (!error.file || !isLibraryFile(error.file.fileName)) { + totalErrorsReportedInNonLibraryFiles++; + } } // Report global errors @@ -1428,7 +1448,9 @@ module Harness { return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; }); - assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); + // Verify we didn't miss any errors in total + assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); + return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } @@ -1805,11 +1827,11 @@ module Harness { return filePath.indexOf(Harness.libFolder) === 0; } - export function getDefaultLibraryFile(): { unitName: string, content: string } { - let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts"; + export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } { + let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts"; return { unitName: libFile, - content: IO.readFile(libFile) + content: io.readFile(libFile) }; } diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index db82a47d362..5a572e220b3 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -93,7 +93,7 @@ module Playback { return run; } - export interface PlaybackSystem extends ts.System, PlaybackControl { } + export interface PlaybackIO extends Harness.IO, PlaybackControl { } function createEmptyLog(): IOLog { return { @@ -223,8 +223,8 @@ module Playback { // console.log("Swallowed write operation during replay: " + name); } - export function wrapSystem(underlying: ts.System): PlaybackSystem { - let wrapper: PlaybackSystem = {}; + export function wrapIO(underlying: Harness.IO): PlaybackIO { + let wrapper: PlaybackIO = {}; initWrapper(wrapper, underlying); wrapper.startReplayFromFile = logFn => { @@ -239,18 +239,24 @@ module Playback { recordLog = undefined; } }; - - Object.defineProperty(wrapper, "args", { - get() { - if (replayLog !== undefined) { - return replayLog.arguments; - } else if (recordLog !== undefined) { - recordLog.arguments = underlying.args; - } - return underlying.args; + + wrapper.args = () => { + if (replayLog !== undefined) { + return replayLog.arguments; + } else if (recordLog !== undefined) { + recordLog.arguments = underlying.args(); } - }); - + return underlying.args(); + } + + wrapper.newLine = () => underlying.newLine(); + wrapper.useCaseSensitiveFileNames = () => underlying.useCaseSensitiveFileNames(); + wrapper.directoryName = (path): string => { throw new Error("NotSupported"); }; + wrapper.createDirectory = path => { throw new Error("NotSupported"); }; + wrapper.directoryExists = (path): boolean => { throw new Error("NotSupported"); }; + wrapper.deleteFile = path => { throw new Error("NotSupported"); }; + wrapper.listFiles = (path, filter, options): string[] => { throw new Error("NotSupported"); }; + wrapper.log = text => underlying.log(text); wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)( (path) => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path: path }), diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index cf748c3070b..a1aaeed3d55 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -4,27 +4,21 @@ /// module RWC { - function runWithIOLog(ioLog: IOLog, fn: () => void) { - let oldSys = ts.sys; + function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) { + let oldIO = Harness.IO; - let wrappedSys = Playback.wrapSystem(ts.sys); - wrappedSys.startReplayFromData(ioLog); - ts.sys = wrappedSys; + let wrappedIO = Playback.wrapIO(oldIO); + wrappedIO.startReplayFromData(ioLog); + Harness.IO = wrappedIO; try { - fn(); + fn(oldIO); } finally { - wrappedSys.endReplay(); - ts.sys = oldSys; + wrappedIO.endReplay(); + Harness.IO = oldIO; } } - let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); - let defaultLib = { - unitName: ts.normalizePath(defaultLibPath), - content: Harness.IO.readFile(defaultLibPath) - }; - export function runRWCTest(jsonPath: string) { describe("Testing a RWC project: " + jsonPath, () => { let inputFiles: { unitName: string; content: string; }[] = []; @@ -38,7 +32,6 @@ module RWC { let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; let currentDirectory: string; let useCustomLibraryFile: boolean; - after(() => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Therefore we have to clean out large objects after the test is done. @@ -63,7 +56,7 @@ module RWC { currentDirectory = ioLog.currentDirectory; useCustomLibraryFile = ioLog.useCustomLibraryFile; runWithIOLog(ioLog, () => { - opts = ts.parseCommandLine(ioLog.arguments); + opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName)); assert.equal(opts.errors.length, 0); // To provide test coverage of output javascript file, @@ -71,11 +64,7 @@ module RWC { opts.options.noEmitOnError = false; }); - if (!useCustomLibraryFile) { - inputFiles.push(defaultLib); - } - - runWithIOLog(ioLog, () => { + runWithIOLog(ioLog, oldIO => { harnessCompiler.reset(); // Load the files @@ -87,7 +76,7 @@ module RWC { let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath; for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. - const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); + const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path)); let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath)); if (!Harness.isLibraryFile(fileRead.path)) { @@ -106,6 +95,10 @@ module RWC { if (useCustomLibraryFile) { inputFiles.push(getHarnessCompilerInputUnit(fileRead.path)); } + else { + // set the flag to put default library to the beginning of the list + inputFiles.unshift(Harness.getDefaultLibraryFile(oldIO)); + } } } } @@ -125,13 +118,13 @@ module RWC { }); function getHarnessCompilerInputUnit(fileName: string) { - let unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName)); + let unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)); let content: string = null; try { - content = ts.sys.readFile(unitName); + content = Harness.IO.readFile(unitName); } catch (e) { - content = ts.sys.readFile(fileName); + content = Harness.IO.readFile(fileName); } return { unitName, content }; } @@ -194,7 +187,7 @@ module RWC { } return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) + - ts.sys.newLine + ts.sys.newLine + + Harness.IO.newLine() + Harness.IO.newLine() + Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors); }, false, baselineOpts); }