diff --git a/Jakefile.js b/Jakefile.js index 5b93462d855..dae99085bef 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -626,9 +626,7 @@ function deleteTemporaryProjectOutput() { } } -var testTimeout = 20000; -desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]', debug=true."); -task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { +function runConsoleTests(defaultReporter, defaultSubsets, postLint) { cleanTestDirs(); var debug = process.env.debug || process.env.d; tests = process.env.test || process.env.tests || process.env.t; @@ -638,7 +636,7 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { fs.unlinkSync(testConfigFile); } - if(tests || light) { + if (tests || light) { writeTestConfigFile(tests, light, testConfigFile); } @@ -648,20 +646,48 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { colors = process.env.colors || process.env.color colors = colors ? ' --no-colors ' : ' --colors '; - tests = tests ? ' -g ' + tests : ''; - reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; + reporter = process.env.reporter || process.env.r || defaultReporter; + // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; - console.log(cmd); - exec(cmd, function() { - deleteTemporaryProjectOutput(); - var lint = jake.Task['lint']; - lint.addListener('complete', function () { - complete(); + var subsetRegexes; + if(defaultSubsets.length === 0) { + subsetRegexes = [tests] + } + else { + var subsets = tests ? tests.split("|") : defaultSubsets; + subsetRegexes = subsets.map(function (sub) { return "^" + sub + ".*$"; }); + subsetRegexes.push("^(?!" + subsets.join("|") + ").*$"); + } + subsetRegexes.forEach(function (subsetRegex) { + tests = subsetRegex ? ' -g "' + subsetRegex + '"' : ''; + var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; + console.log(cmd); + exec(cmd, function () { + deleteTemporaryProjectOutput(); + if (postLint) { + var lint = jake.Task['lint']; + lint.addListener('complete', function () { + complete(); + }); + lint.invoke(); + } + else { + complete(); + } }); - lint.invoke(); }); +} + +var testTimeout = 20000; +desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true."); +task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() { + runConsoleTests('min', ['compiler', 'conformance', 'Projects', 'fourslash']); +}, {async: true}); + +desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); +task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { + runConsoleTests('mocha-fivemat-progress-reporter', [], /*postLint*/ true); }, {async: true}); desc("Generates code coverage data via instanbul"); @@ -820,7 +846,8 @@ var tslintRuleDir = "scripts/tslint"; var tslintRules = ([ "nextLineRule", "noNullRule", - "booleanTriviaRule" + "booleanTriviaRule", + "typeOperatorSpacingRule" ]); var tslintRulesFiles = tslintRules.map(function(p) { return path.join(tslintRuleDir, p + ".ts"); diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index 1eead82d9fe..26632ba6bab 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -18,6 +18,13 @@ function main(): void { return; } + function writeFile(fileName: string, contents: string) { + // TODO: Fix path joining + var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/")); + var fileOutputPath = inputDirectory + "/" + fileName; + sys.writeFile(fileOutputPath, contents); + } + var inputFilePath = sys.args[0].replace(/\\/g, "/"); var inputStr = sys.readFile(inputFilePath); @@ -28,11 +35,10 @@ function main(): void { var infoFileOutput = buildInfoFileOutput(diagnosticMessages, nameMap); checkForUniqueCodes(names, diagnosticMessages); + writeFile("diagnosticInformationMap.generated.ts", infoFileOutput); - // TODO: Fix path joining - var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/")); - var fileOutputPath = inputDirectory + "/diagnosticInformationMap.generated.ts"; - sys.writeFile(fileOutputPath, infoFileOutput); + var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages, nameMap); + writeFile("diagnosticMessages.generated.json", messageOutput); } function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) { @@ -85,12 +91,14 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: for (var i = 0; i < names.length; i++) { var name = names[i]; var diagnosticDetails = messageTable[name]; + var propName = convertPropertyName(nameMap[name]); result += - ' ' + convertPropertyName(nameMap[name]) + + ' ' + propName + ': { code: ' + diagnosticDetails.code + ', category: DiagnosticCategory.' + diagnosticDetails.category + - ', key: "' + name.replace(/[\"]/g, '\\"') + '"' + + ', key: "' + createKey(propName, diagnosticDetails.code) + '"' + + ', message: "' + name.replace(/[\"]/g, '\\"') + '"' + ' },\r\n'; } @@ -99,6 +107,30 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: return result; } +function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map): string { + var result = + '{'; + var names = Utilities.getObjectKeys(messageTable); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + var diagnosticDetails = messageTable[name]; + var propName = convertPropertyName(nameMap[name]); + + result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"'; + if (i !== names.length - 1) { + result += ','; + } + } + + result += '\r\n}'; + + return result; +} + +function createKey(name: string, code: number) : string { + return name.slice(0, 100) + '_' + code; +} + function convertPropertyName(origName: string): string { var result = origName.split("").map(char => { if (char === '*') { return "_Asterisk"; } diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts new file mode 100644 index 00000000000..23925493340 --- /dev/null +++ b/scripts/tslint/typeOperatorSpacingRule.ts @@ -0,0 +1,29 @@ +/// +/// + + +export class Rule extends Lint.Rules.AbstractRule { + public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces"; + + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithWalker(new TypeOperatorSpacingWalker(sourceFile, this.getOptions())); + } +} + +class TypeOperatorSpacingWalker extends Lint.RuleWalker { + public visitNode(node: ts.Node) { + if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) { + let types = (node).types; + let expectedStart = types[0].end + 2; // space, | or & + for (let i = 1; i < types.length; i++) { + let currentType = types[i]; + if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) { + const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING); + this.addFailure(failure); + } + expectedStart = currentType.end + 2; + } + } + super.visitNode(node); + } +} diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8e2fa3a89f9..51acf06e2d6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2847,23 +2847,29 @@ namespace ts { return type.resolvedBaseConstructorType; } + function hasClassBaseType(type: InterfaceType): boolean { + return !!forEach(getBaseTypes(type), t => !!(t.symbol.flags & SymbolFlags.Class)); + } + function getBaseTypes(type: InterfaceType): ObjectType[] { + let isClass = type.symbol.flags & SymbolFlags.Class; + let isInterface = type.symbol.flags & SymbolFlags.Interface; if (!type.resolvedBaseTypes) { - if (type.symbol.flags & SymbolFlags.Class) { + if (!isClass && !isInterface) { + Debug.fail("type must be class or interface"); + } + if (isClass) { resolveBaseTypesOfClass(type); } - else if (type.symbol.flags & SymbolFlags.Interface) { + if (isInterface) { resolveBaseTypesOfInterface(type); } - else { - Debug.fail("type must be class or interface"); - } } return type.resolvedBaseTypes; } function resolveBaseTypesOfClass(type: InterfaceType): void { - type.resolvedBaseTypes = emptyArray; + type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; let baseContructorType = getBaseConstructorTypeOfClass(type); if (!(baseContructorType.flags & TypeFlags.ObjectType)) { return; @@ -2899,11 +2905,16 @@ namespace ts { typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; } - type.resolvedBaseTypes = [baseType]; + if (type.resolvedBaseTypes === emptyArray) { + type.resolvedBaseTypes = [baseType]; + } + else { + type.resolvedBaseTypes.push(baseType); + } } function resolveBaseTypesOfInterface(type: InterfaceType): void { - type.resolvedBaseTypes = []; + type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; for (let declaration of type.symbol.declarations) { if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration)) { for (let node of getInterfaceBaseTypeNodes(declaration)) { @@ -2911,7 +2922,12 @@ namespace ts { if (baseType !== unknownType) { if (getTargetType(baseType).flags & (TypeFlags.Class | TypeFlags.Interface)) { if (type !== baseType && !hasBaseType(baseType, type)) { - type.resolvedBaseTypes.push(baseType); + if (type.resolvedBaseTypes === emptyArray) { + type.resolvedBaseTypes = [baseType]; + } + else { + type.resolvedBaseTypes.push(baseType); + } } else { error(declaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); @@ -3254,7 +3270,7 @@ namespace ts { } function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { - if (!getBaseTypes(classType).length) { + if (!hasClassBaseType(classType)) { return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)]; } let baseConstructorType = getBaseConstructorTypeOfClass(classType); @@ -5622,11 +5638,10 @@ namespace ts { // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N source = getErasedSignature(source); target = getErasedSignature(target); - let sourceLen = source.parameters.length; let targetLen = target.parameters.length; for (let i = 0; i < targetLen; i++) { - let s = source.hasRestParameter && i === sourceLen - 1 ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]); - let t = target.hasRestParameter && i === targetLen - 1 ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]); + let s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]); + let t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]); let related = compareTypes(s, t); if (!related) { return Ternary.False; @@ -5639,6 +5654,10 @@ namespace ts { return result; } + function isRestParameterIndex(signature: Signature, parameterIndex: number) { + return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1; + } + function isSupertypeOfEach(candidate: Type, types: Type[]): boolean { for (let type of types) { if (candidate !== type && !isTypeSubtypeOf(type, candidate)) return false; @@ -6592,7 +6611,7 @@ namespace ts { while (current && !nodeStartsNewLexicalEnvironment(current)) { if (isIterationStatement(current, /*lookInLabeledStatements*/ false)) { if (inFunction) { - grammarErrorOnFirstToken(current, Diagnostics.Loop_contains_block_scoped_variable_0_referenced_by_a_function_in_the_loop_This_is_only_supported_in_ECMAScript_6_or_higher, declarationNameToString(node)); + getNodeLinks(current).flags |= NodeCheckFlags.LoopWithBlockScopedBindingCapturedInFunction; } // mark value declaration so during emit they can have a special handling getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.BlockScopedBindingInLoop; @@ -6800,8 +6819,9 @@ namespace ts { } // If last parameter is contextually rest parameter get its type - if (indexOfParameter === (func.parameters.length - 1) && - funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) { + if (funcHasRestParameters && + indexOfParameter === (func.parameters.length - 1) && + isRestParameterIndex(contextualSignature, func.parameters.length - 1)) { return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters)); } } @@ -7033,7 +7053,7 @@ namespace ts { return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } - function getContextualTypeForJsxExpression(expr: JsxExpression|JsxSpreadAttribute): Type { + function getContextualTypeForJsxExpression(expr: JsxExpression | JsxSpreadAttribute): Type { // Contextual type only applies to JSX expressions that are in attribute assignments (not in 'Children' positions) if (expr.parent.kind === SyntaxKind.JsxAttribute) { let attrib = expr.parent; @@ -7541,7 +7561,7 @@ namespace ts { /** * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name */ - function isJsxIntrinsicIdentifier(tagName: Identifier|QualifiedName) { + function isJsxIntrinsicIdentifier(tagName: Identifier | QualifiedName) { if (tagName.kind === SyntaxKind.QualifiedName) { return false; } @@ -7627,7 +7647,7 @@ namespace ts { /// If this is a class-based tag (otherwise returns undefined), returns the symbol of the class /// type or factory function. /// Otherwise, returns unknownSymbol. - function getJsxElementTagSymbol(node: JsxOpeningLikeElement|JsxClosingElement): Symbol { + function getJsxElementTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { let flags: JsxFlags = JsxFlags.UnknownElement; let links = getNodeLinks(node); if (!links.resolvedSymbol) { @@ -7640,7 +7660,7 @@ namespace ts { } return links.resolvedSymbol; - function lookupIntrinsicTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol { + function lookupIntrinsicTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { let intrinsicElementsType = getJsxIntrinsicElementsType(); if (intrinsicElementsType !== unknownType) { // Property case @@ -7668,7 +7688,7 @@ namespace ts { } } - function lookupClassTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol { + function lookupClassTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { let valueSymbol: Symbol = resolveJsxTagName(node); // Look up the value in the current scope @@ -7682,7 +7702,7 @@ namespace ts { return valueSymbol || unknownSymbol; } - function resolveJsxTagName(node: JsxOpeningLikeElement|JsxClosingElement): Symbol { + function resolveJsxTagName(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { if (node.tagName.kind === SyntaxKind.Identifier) { let tag = node.tagName; let sym = getResolvedSymbol(tag); @@ -8391,7 +8411,7 @@ namespace ts { // If spread arguments are present, check that they correspond to a rest parameter. If so, no // further checking is necessary. if (spreadArgIndex >= 0) { - return signature.hasRestParameter && spreadArgIndex >= signature.parameters.length - 1; + return isRestParameterIndex(signature, spreadArgIndex); } // Too many arguments implies incorrect arity. @@ -9382,7 +9402,7 @@ namespace ts { let contextualParameterType = getTypeAtPosition(context, i); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); } - if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) { + if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { let parameter = lastOrUndefined(signature.parameters); let contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); @@ -9395,7 +9415,9 @@ namespace ts { if (isBindingPattern(node.name)) { for (let element of (node.name).elements) { if (element.kind !== SyntaxKind.OmittedExpression) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + if (element.name.kind === SyntaxKind.Identifier) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } assignBindingElementTypes(element); } } @@ -14552,6 +14574,10 @@ namespace ts { // Emitter support + function isArgumentsLocalBinding(node: Identifier): boolean { + return getReferencedValueSymbol(node) === argumentsSymbol; + } + // When resolved as an expression identifier, if the given node references an exported entity, return the declaration // node of the exported entity's container. Otherwise, return undefined. function getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration { @@ -14856,7 +14882,8 @@ namespace ts { collectLinkedAliases, getReferencedValueDeclaration, getTypeReferenceSerializationKind, - isOptionalParameter + isOptionalParameter, + isArgumentsLocalBinding }; } @@ -15539,7 +15566,7 @@ namespace ts { } } - function checkGrammarJsxElement(node: JsxOpeningElement|JsxSelfClosingElement) { + function checkGrammarJsxElement(node: JsxOpeningLikeElement) { const seen: Map = {}; for (let attr of node.attributes) { if (attr.kind === SyntaxKind.JsxSpreadAttribute) { @@ -15683,21 +15710,6 @@ namespace ts { } } - function isIterationStatement(node: Node, lookInLabeledStatements: boolean): boolean { - switch (node.kind) { - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - return true; - case SyntaxKind.LabeledStatement: - return lookInLabeledStatements && isIterationStatement((node).statement, lookInLabeledStatements); - } - - return false; - } - function checkGrammarBreakOrContinueStatement(node: BreakOrContinueStatement): boolean { let current: Node = node; while (current) { @@ -15951,11 +15963,14 @@ namespace ts { // DeclarationElement: // ExportAssignment // export_opt InterfaceDeclaration + // export_opt TypeAliasDeclaration // export_opt ImportDeclaration // export_opt ExternalImportDeclaration // export_opt AmbientDeclaration // + // TODO: The spec needs to be amended to reflect this grammar. if (node.kind === SyntaxKind.InterfaceDeclaration || + node.kind === SyntaxKind.TypeAliasDeclaration || node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration || node.kind === SyntaxKind.ExportDeclaration || diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b4f5185b6b4..7f3f9155a0e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -79,9 +79,9 @@ namespace ts { "es6": ModuleKind.ES6, "es2015": ModuleKind.ES2015, }, - description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6, + description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, paramType: Diagnostics.KIND, - error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6 + error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es2015 }, { name: "newLine", @@ -212,9 +212,9 @@ namespace ts { "es6": ScriptTarget.ES6, "es2015": ScriptTarget.ES2015, }, - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_experimental, paramType: Diagnostics.VERSION, - error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES6 + error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES2015 }, { name: "version", diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8fd92818c46..78fc4c5602e 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -365,10 +365,10 @@ namespace ts { export let localizedDiagnosticMessages: Map = undefined; - export function getLocaleSpecificMessage(message: string) { - return localizedDiagnosticMessages && localizedDiagnosticMessages[message] - ? localizedDiagnosticMessages[message] - : message; + export function getLocaleSpecificMessage(message: DiagnosticMessage) { + return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] + ? localizedDiagnosticMessages[message.key] + : message.message; } export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic; @@ -383,7 +383,7 @@ namespace ts { Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`); } - let text = getLocaleSpecificMessage(message.key); + let text = getLocaleSpecificMessage(message); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); @@ -402,7 +402,7 @@ namespace ts { export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic; export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic { - let text = getLocaleSpecificMessage(message.key); + let text = getLocaleSpecificMessage(message); if (arguments.length > 1) { text = formatStringFromArgs(text, arguments, 1); @@ -421,7 +421,7 @@ namespace ts { export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain; export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain { - let text = getLocaleSpecificMessage(message.key); + let text = getLocaleSpecificMessage(message); if (arguments.length > 2) { text = formatStringFromArgs(text, arguments, 2); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d54d49e7511..68b479e44fe 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -627,7 +627,7 @@ "category": "Error", "code": 1203 }, - "Cannot compile modules into 'es6' when targeting 'ES5' or lower.": { + "Cannot compile modules into 'es2015' when targeting 'ES5' or lower.": { "category": "Error", "code": 1204 }, @@ -1712,10 +1712,6 @@ "category": "Error", "code": 2654 }, - "Exported external package typings can only be in '.d.ts' files. Please contact the package author to update the package definition.": { - "category": "Error", - "code": 2655 - }, "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition.": { "category": "Error", "code": 2656 @@ -2004,10 +2000,6 @@ "category": "Error", "code": 4082 }, - "Loop contains block-scoped variable '{0}' referenced by a function in the loop. This is only supported in ECMAScript 6 or higher.": { - "category": "Error", - "code": 4091 - }, "The current host does not support the '{0}' option.": { "category": "Error", "code": 5001 @@ -2044,7 +2036,7 @@ "category": "Error", "code": 5042 }, - "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": { + "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher.": { "category": "Error", "code": 5047 }, @@ -2105,11 +2097,11 @@ "category": "Message", "code": 6010 }, - "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)": { - "category": "Message", - "code": 6015 - }, - "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'": { + "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": { + "category": "Message", + "code": 6015 + }, + "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'": { "category": "Message", "code": 6016 }, @@ -2193,14 +2185,14 @@ "category": "Error", "code": 6045 }, - "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'.": { + "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es2015'.": { "category": "Error", "code": 6046 }, - "Argument for '--target' option must be 'ES3', 'ES5', or 'ES6'.": { - "category": "Error", - "code": 6047 - }, + "Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": { + "category": "Error", + "code": 6047 + }, "Locale must be of the form or -. For example '{0}' or '{1}'.": { "category": "Error", "code": 6048 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 70ab3606c6c..8837972a916 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -9,6 +9,12 @@ namespace ts { type DependencyGroup = Array; + const enum Jump { + Break = 1 << 1, + Continue = 1 << 2, + Return = 1 << 3 + } + let entities: Map = { "quot": 0x0022, "amp": 0x0026, @@ -379,6 +385,99 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi return true; } + interface ConvertedLoopState { + /* + * set of labels that occured inside the converted loop + * used to determine if labeled jump can be emitted as is or it should be dispatched to calling code + */ + labels?: Map; + /* + * collection of labeled jumps that transfer control outside the converted loop. + * maps store association 'label -> labelMarker' where + * - label - value of label as it apprear in code + * - label marker - return value that should be interpreted by calling code as 'jump to