From e6cfc10acc90ccaf5072f0e0fd620ba2652190f1 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 17 Feb 2015 16:26:32 -0800 Subject: [PATCH] added missing files --- src/compiler/checker.ts | 11 +++++------ src/compiler/emitter.ts | 43 +++++++++++++++++++++++++++++------------ src/compiler/types.ts | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 211331579cd..748be3648ec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4939,15 +4939,14 @@ module ts { current = current.parent; } - if (!inFunction) { - return; - } - var current: Node = container; while (current && !isNameScopeBoundary(current)) { if (isIterationStatement(current, /*lookInLabeledStatements*/ false)) { - getNodeLinks(current).flags |= NodeCheckFlags.BlockScopedBindingCapturedInLoop; - grammarErrorOnFirstToken(current, Diagnostics.Code_in_the_loop_captures_block_scoped_variable_0_in_closure_This_is_natively_supported_in_ECMAScript_6_or_higher, declarationNameToString(node)); + if (inFunction) { + getNodeLinks(current).flags |= NodeCheckFlags.BlockScopedBindingInLoop; + grammarErrorOnFirstToken(current, Diagnostics.Code_in_the_loop_captures_block_scoped_variable_0_in_closure_This_is_natively_supported_in_ECMAScript_6_or_higher, declarationNameToString(node)); + } + getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.BlockScopedBindingInLoop; break; } current = current.parent; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 638b78812cc..2808b561256 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3282,7 +3282,7 @@ module ts { emitDestructuringAssignment(e, createElementAccess(value, createNumericLiteral(i))); } else { - if (i === elements.length - 1 && (e).expression.kind === SyntaxKind.Identifier) { + if (i === elements.length - 1) { value = ensureIdentifier(value); emitAssignment((e).expression, value); write(".slice(" + i + ")"); @@ -3384,12 +3384,23 @@ module ts { } } else { - var initializeToDefault = renameNonTopLevelLetAndConst(node.name); + var isLet = renameNonTopLevelLetAndConst(node.name); emitModuleMemberName(node); - var initializer = - node.initializer || - (initializeToDefault && createVoidZero()); + var initializer = node.initializer; + if (!initializer) { + // downlevel emit for non-initialized let bindings defined in loops + // for (...) { let x; } + // should be + // for (...) { var = void 0; } + // this is necessary to preserve ES6 semantic in scenarios like + // for (...) { let x; console.log(x); x = 1 } // assignment on one iteration should not affect other iterations + var initializer = + languageVersion < ScriptTarget.ES6 && + (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BlockScopedBindingInLoop) && + (getCombinedFlagsForIdentifier(node.name) & NodeFlags.Let) && + createVoidZero(); + } emitOptional(" = ", initializer); } @@ -3422,29 +3433,39 @@ module ts { } } - function renameNonTopLevelLetAndConst(node: Node): boolean { + function getCombinedFlagsForIdentifier(node: Identifier): NodeFlags { + if (!node.parent || (node.parent.kind !== SyntaxKind.VariableDeclaration && node.parent.kind !== SyntaxKind.BindingElement)) { + return 0; + } + + return getCombinedNodeFlags(node.parent); + } + + function renameNonTopLevelLetAndConst(node: Node): void { // do not rename if // - language version is ES6+ // - node is synthesized (does not have a parent) + // - node is not identifier (can happen when tree is malformed) // - node is definitely not name of variable declaration. // it still can be part of parameter declaration, this check will be done next if (languageVersion >= ScriptTarget.ES6 || !node.parent || + node.kind !== SyntaxKind.Identifier || (node.parent.kind !== SyntaxKind.VariableDeclaration && node.parent.kind !== SyntaxKind.BindingElement)) { - return false; + return; } - var combinedFlags = getCombinedNodeFlags(node.parent); + var combinedFlags = getCombinedFlagsForIdentifier(node); if (((combinedFlags & NodeFlags.BlockScoped) === 0) || combinedFlags & NodeFlags.Export) { // do not rename exported or non-block scoped variables - return false; + return; } // here it is known that node is a block scoped variable var list = getAncestor(node, SyntaxKind.VariableDeclarationList); if (list.parent.kind === SyntaxKind.VariableStatement && list.parent.parent.kind === SyntaxKind.SourceFile) { // do not rename variables that are defined on source file level - return false; + return; } var generatedName = makeUniqueName(getEnclosingBlockScopeContainer(node), (node).text); @@ -3453,8 +3474,6 @@ module ts { generatedBlockScopeNames = []; } generatedBlockScopeNames[symbolId] = generatedName; - - return (combinedFlags & NodeFlags.Let) !== 0; } function emitVariableStatement(node: VariableStatement) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 940a4a6e5a4..9c7c794d002 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1262,7 +1262,7 @@ module ts { // Values for enum members have been computed, and any errors have been reported for them. EnumValuesComputed = 0x00000080, - BlockScopedBindingCapturedInLoop = 0x00000100, + BlockScopedBindingInLoop = 0x00000100, } export interface NodeLinks {