diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c6b8ea0506..987cde8057e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36095,15 +36095,16 @@ namespace ts { // Emitter support function isArgumentsLocalBinding(nodeIn: Identifier): boolean { - if (!isGeneratedIdentifier(nodeIn)) { - const node = getParseTreeNode(nodeIn, isIdentifier); - if (node) { - const isPropertyName = node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).name === node; - return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol; - } - } - - return false; + // Note: does not handle isShorthandPropertyAssignment (and probably a few more) + if (isGeneratedIdentifier(nodeIn)) return false; + const node = getParseTreeNode(nodeIn, isIdentifier); + if (!node) return false; + const parent = node.parent; + if (!parent) return false; + const isPropertyName = ((isPropertyAccessExpression(parent) + || isPropertyAssignment(parent)) + && parent.name === node); + return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol; } function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index fb545f17d1b..a23b701cf07 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -583,13 +583,10 @@ namespace ts { if (!convertedLoopState) { return node; } - if (isGeneratedIdentifier(node)) { - return node; + if (resolver.isArgumentsLocalBinding(node)) { + return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); } - if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) { - return node; - } - return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); + return node; } function visitBreakOrContinueStatement(node: BreakOrContinueStatement): Statement { @@ -3517,7 +3514,7 @@ namespace ts { return setTextRange( createPropertyAssignment( node.name, - getSynthesizedClone(node.name) + visitIdentifier(getSynthesizedClone(node.name)) ), /*location*/ node ); diff --git a/tests/baselines/reference/argumentsAsPropertyName2.js b/tests/baselines/reference/argumentsAsPropertyName2.js new file mode 100644 index 00000000000..878178ed39c --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName2.js @@ -0,0 +1,29 @@ +//// [argumentsAsPropertyName2.ts] +// target: es5 + +function foo() { + for (let x = 0; x < 1; ++x) { + let i : number; + [].forEach(function () { i }); + ({ arguments: 0 }); + ({ arguments }); + ({ arguments: arguments }); + } +} + + +//// [argumentsAsPropertyName2.js] +// target: es5 +function foo() { + var _loop_1 = function (x) { + var i; + [].forEach(function () { i; }); + ({ arguments: 0 }); + ({ arguments: arguments_1 }); + ({ arguments: arguments_1 }); + }; + var arguments_1 = arguments; + for (var x = 0; x < 1; ++x) { + _loop_1(x); + } +} diff --git a/tests/baselines/reference/argumentsAsPropertyName2.symbols b/tests/baselines/reference/argumentsAsPropertyName2.symbols new file mode 100644 index 00000000000..a9d73f1faa5 --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName2.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/argumentsAsPropertyName2.ts === +// target: es5 + +function foo() { +>foo : Symbol(foo, Decl(argumentsAsPropertyName2.ts, 0, 0)) + + for (let x = 0; x < 1; ++x) { +>x : Symbol(x, Decl(argumentsAsPropertyName2.ts, 3, 12)) +>x : Symbol(x, Decl(argumentsAsPropertyName2.ts, 3, 12)) +>x : Symbol(x, Decl(argumentsAsPropertyName2.ts, 3, 12)) + + let i : number; +>i : Symbol(i, Decl(argumentsAsPropertyName2.ts, 4, 11)) + + [].forEach(function () { i }); +>[].forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(argumentsAsPropertyName2.ts, 4, 11)) + + ({ arguments: 0 }); +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName2.ts, 6, 10)) + + ({ arguments }); +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName2.ts, 7, 10)) + + ({ arguments: arguments }); +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName2.ts, 8, 10)) +>arguments : Symbol(arguments) + } +} + diff --git a/tests/baselines/reference/argumentsAsPropertyName2.types b/tests/baselines/reference/argumentsAsPropertyName2.types new file mode 100644 index 00000000000..488edd8ea0d --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName2.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/argumentsAsPropertyName2.ts === +// target: es5 + +function foo() { +>foo : () => void + + for (let x = 0; x < 1; ++x) { +>x : number +>0 : 0 +>x < 1 : boolean +>x : number +>1 : 1 +>++x : number +>x : number + + let i : number; +>i : number + + [].forEach(function () { i }); +>[].forEach(function () { i }) : void +>[].forEach : (callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any) => void +>[] : undefined[] +>forEach : (callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any) => void +>function () { i } : () => void +>i : number + + ({ arguments: 0 }); +>({ arguments: 0 }) : { arguments: number; } +>{ arguments: 0 } : { arguments: number; } +>arguments : number +>0 : 0 + + ({ arguments }); +>({ arguments }) : { arguments: IArguments; } +>{ arguments } : { arguments: IArguments; } +>arguments : IArguments + + ({ arguments: arguments }); +>({ arguments: arguments }) : { arguments: IArguments; } +>{ arguments: arguments } : { arguments: IArguments; } +>arguments : IArguments +>arguments : IArguments + } +} + diff --git a/tests/cases/compiler/argumentsAsPropertyName2.ts b/tests/cases/compiler/argumentsAsPropertyName2.ts new file mode 100644 index 00000000000..4c17a8a96a6 --- /dev/null +++ b/tests/cases/compiler/argumentsAsPropertyName2.ts @@ -0,0 +1,11 @@ +// target: es5 + +function foo() { + for (let x = 0; x < 1; ++x) { + let i : number; + [].forEach(function () { i }); + ({ arguments: 0 }); + ({ arguments }); + ({ arguments: arguments }); + } +}