Skip to content

Commit 6a40212

Browse files
tbreisacherblickly
authored andcommitted
Allow iteration over the 'arguments' object even if it escapes and cannot be detected. Note that this causes some incorrect code to "work" when transpiled.
let obj = { 0: 'x', 1: 'y', length: 2, }; for (let x of obj) {} should throw a TypeError, but will not when transpiled. However, if typechecking is enabled there will be a compiler error. Fixes #1303 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=116058485
1 parent 0affbf5 commit 6a40212

File tree

8 files changed

+111
-112
lines changed

8 files changed

+111
-112
lines changed

externs/es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Generator.prototype.return = function(value) {};
142142
Generator.prototype.throw = function(exception) {};
143143

144144

145-
// TODO(johnlenz): Array should be Iterable.
145+
// TODO(johnlenz): Array and Arguments should be Iterable.
146146

147147

148148

src/com/google/javascript/jscomp/Es6RewriteDestructuring.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ private void visitArrayPattern(NodeTraversal t, Node arrayPattern, Node parent)
294294
String tempVarName = DESTRUCTURING_TEMP_VAR + (destructuringVarCounter++);
295295
Node tempDecl = IR.var(
296296
IR.name(tempVarName),
297-
makeIterator(t, compiler, rhs.detachFromParent()));
297+
makeIterator(compiler, rhs.detachFromParent()));
298298
tempDecl.useSourceInfoIfMissingFromForTree(arrayPattern);
299299
nodeToDetach.getParent().addChildBefore(tempDecl, nodeToDetach);
300300

src/com/google/javascript/jscomp/Es6RewriteGenerators.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private void visitYieldFor(NodeTraversal t, Node n, Node parent) {
179179
Node enclosingStatement = NodeUtil.getEnclosingStatement(n);
180180
Node generator = IR.var(
181181
IR.name(GENERATOR_YIELD_ALL_NAME),
182-
makeIterator(t, compiler, n.removeFirstChild()));
182+
makeIterator(compiler, n.removeFirstChild()));
183183
Node entryDecl = IR.var(IR.name(GENERATOR_YIELD_ALL_ENTRY));
184184
Node assignIterResult =
185185
IR.assign(

src/com/google/javascript/jscomp/Es6ToEs3Converter.java

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ private void visitForOf(NodeTraversal t, Node node, Node parent) {
259259
Node iterResult = IR.name(ITER_RESULT + variableName);
260260
iterResult.makeNonIndexable();
261261

262-
Node init = IR.var(iterName.cloneTree(), makeIterator(t, compiler, iterable));
262+
Node init = IR.var(iterName.cloneTree(), makeIterator(compiler, iterable));
263263
Node initIterResult = iterResult.cloneTree();
264264
initIterResult.addChildToFront(getNext.cloneTree());
265265
init.addChildToBack(initIterResult);
@@ -397,7 +397,7 @@ private void visitArrayLitOrCallWithSpread(NodeTraversal t, Node node, Node pare
397397
currGroup = null;
398398
}
399399
compiler.needsEs6Runtime = true;
400-
groups.add(arrayFromIterable(t, compiler, currElement.removeFirstChild()));
400+
groups.add(arrayFromIterable(compiler, currElement.removeFirstChild()));
401401
} else {
402402
if (currGroup == null) {
403403
currGroup = IR.arraylit();
@@ -937,36 +937,17 @@ private void cannotConvertYet(Node n, String feature) {
937937
}
938938

939939
/**
940-
* Returns a call to {@code $jscomp.makeIterator} with {@code iterable} as its argument, unless
941-
* {@code iterable} is the special {@code arguments} variable, in which case the returned Node is:
942-
* {@code $jscomp.makeIterator($jscomp.arrayFromArguments(iterable))}.
940+
* Returns a call to {@code $jscomp.makeIterator} with {@code iterable} as its argument.
943941
*/
944-
static Node makeIterator(NodeTraversal t, AbstractCompiler compiler, Node iterable) {
945-
if (iterable.isName()) {
946-
Var var = t.getScope().getVar(iterable.getString());
947-
if (var != null && var.isArguments()) {
948-
iterable = IR.call(
949-
NodeUtil.newQName(compiler, "$jscomp.arrayFromArguments"),
950-
iterable);
951-
}
952-
}
942+
static Node makeIterator(AbstractCompiler compiler, Node iterable) {
953943
return callEs6RuntimeFunction(compiler, iterable, "makeIterator");
954944
}
955945

956946
/**
957-
* Returns a call to $jscomp.arrayFromIterable with {@code iterable} as its argument, unless
958-
* {@code iterable} is the special {@code arguments} variable, in which case
959-
* {@code $jscomp.arrayFromArguments} is called instead.
947+
* Returns a call to $jscomp.arrayFromIterable with {@code iterable} as its argument.
960948
*/
961-
private static Node arrayFromIterable(NodeTraversal t, AbstractCompiler compiler, Node iterable) {
962-
String fnName = "arrayFromIterable";
963-
if (iterable.isName()) {
964-
Var var = t.getScope().getVar(iterable.getString());
965-
if (var != null && var.isArguments()) {
966-
fnName = "arrayFromArguments";
967-
}
968-
}
969-
return callEs6RuntimeFunction(compiler, iterable, fnName);
949+
private static Node arrayFromIterable(AbstractCompiler compiler, Node iterable) {
950+
return callEs6RuntimeFunction(compiler, iterable, "arrayFromIterable");
970951
}
971952

972953
private static Node callEs6RuntimeFunction(

src/com/google/javascript/jscomp/js/es6/runtime.js

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ $jscomp.initSymbolIterator = function() {
9090
/**
9191
* Creates an iterator for the given iterable.
9292
*
93-
* @param {string|!Array<T>|!Iterable<T>|!Iterator<T>} iterable
93+
* @param {string|!Array<T>|!Iterable<T>|!Iterator<T>|!Arguments<T>} iterable
9494
* @return {!Iterator<T>}
9595
* @template T
9696
* @suppress {reportUnknownTypes}
@@ -101,10 +101,7 @@ $jscomp.makeIterator = function(iterable) {
101101
if (iterable[$jscomp.global.Symbol.iterator]) {
102102
return iterable[$jscomp.global.Symbol.iterator]();
103103
}
104-
if (!(iterable instanceof Array) && typeof iterable != 'string' &&
105-
!(iterable instanceof String)) {
106-
throw new TypeError(iterable + ' is not iterable');
107-
}
104+
108105
let index = 0;
109106
return /** @type {!Iterator} */ ({
110107
next() {
@@ -142,7 +139,7 @@ $jscomp.arrayFromIterator = function(iterator) {
142139

143140
/**
144141
* Copies the values from an Iterable into an Array.
145-
* @param {string|!Array<T>|!Iterable<T>} iterable
142+
* @param {string|!Array<T>|!Iterable<T>|!Arguments<T>} iterable
146143
* @return {!Array<T>}
147144
* @template T
148145
*/
@@ -155,20 +152,6 @@ $jscomp.arrayFromIterable = function(iterable) {
155152
};
156153

157154

158-
/**
159-
* Copies the values from an Arguments object into an Array.
160-
* @param {!Arguments} args
161-
* @return {!Array}
162-
*/
163-
$jscomp.arrayFromArguments = function(args) {
164-
const result = [];
165-
for (let i = 0; i < args.length; i++) {
166-
result.push(args[i]);
167-
}
168-
return result;
169-
};
170-
171-
172155
/**
173156
* Inherit the prototype methods and static methods from one constructor
174157
* into another.

src/com/google/javascript/jscomp/js/es6_runtime.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,12 @@
5050
/**@suppress {reportUnknownTypes}
5151
@template T
5252
53-
@param {(string|!Array<T>|!Iterable<T>|!Iterator<T>)} iterable
53+
@param {(string|!Array<T>|!Iterable<T>|!Iterator<T>|!Arguments<T>)} iterable
5454
@return {!Iterator<T>} */$jscomp.makeIterator = function(iterable) {
5555
$jscomp.initSymbolIterator();
5656
if (iterable[$jscomp.global.Symbol.iterator]) {
5757
return iterable[$jscomp.global.Symbol.iterator]();
5858
}
59-
if (!(iterable instanceof Array) && typeof iterable != "string" && !(iterable instanceof String)) {
60-
throw new TypeError(iterable + " is not iterable");
61-
}
6259
var index = 0;
6360
return /**@type {!Iterator} */({next:function() {
6461
if (index == iterable.length) {
@@ -81,7 +78,7 @@
8178
};
8279
/**@template T
8380
84-
@param {(string|!Array<T>|!Iterable<T>)} iterable
81+
@param {(string|!Array<T>|!Iterable<T>|!Arguments<T>)} iterable
8582
@return {!Array<T>} */$jscomp.arrayFromIterable = function(iterable) {
8683
if (iterable instanceof Array) {
8784
return iterable;
@@ -90,15 +87,6 @@
9087
}
9188
};
9289
/**
93-
@param {!Arguments} args
94-
@return {!Array} */$jscomp.arrayFromArguments = function(args) {
95-
/**@const */var result = [];
96-
for (var i = 0;i < args.length;i++) {
97-
result.push(args[i]);
98-
}
99-
return result;
100-
};
101-
/**
10290
@param {!Function} childCtor
10391
@param {!Function} parentCtor */$jscomp.inherits = function(childCtor, parentCtor) {
10492
/**@constructor */function tempCtor() {

test/com/google/javascript/jscomp/Es6RewriteDestructuringTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,7 @@ public void testArrayDestructuringArguments() {
362362
"function f() { var [x, y] = arguments; }",
363363
LINE_JOINER.join(
364364
"function f() {",
365-
" var $jscomp$destructuring$var0 = $jscomp.makeIterator(",
366-
" $jscomp.arrayFromArguments(arguments));",
365+
" var $jscomp$destructuring$var0 = $jscomp.makeIterator(arguments);",
367366
" var x = $jscomp$destructuring$var0.next().value;",
368367
" var y = $jscomp$destructuring$var0.next().value;",
369368
"}"));

0 commit comments

Comments
 (0)