Extract for-of iterator handling to a helper#11262
Conversation
2c08b9b to
40ce663
Compare
| // It must be kept for compatibility reasons. | ||
| // TODO (Babel 8): Remove this code. | ||
|
|
||
| export default function transformWithoutHelper(loose, path, state) { |
There was a problem hiding this comment.
This file contains the old plugin code needed when the helper isn't available. I just copy-pasted it without any edit.
d556229 to
f505349
Compare
| for (_iteratorHelper.s(); !(_step = _iteratorHelper.n()).done;) { | ||
| var i = _step.value; | ||
| var x; | ||
| var f; |
There was a problem hiding this comment.
This is a bug unrelated to this PR: f and x should be declared in the _loop function.
There was a problem hiding this comment.
I think they have to stay here. If we moved the var inside the _loop function, they would no longer declare the variable in the function scope (it's not a block let/const).
|
|
||
| helpers.createForOfIteratorHelperLoose = helper("7.9.0")` | ||
| export default function _createForOfIteratorHelperLoose(o) { | ||
| var i = 0; |
There was a problem hiding this comment.
Nit: Don't share the variable here.
There was a problem hiding this comment.
I mostly did it for code size, since this is a runtime helper, and i could stand both for index and iterator 😅
|
|
||
| const nodes = builder.build({ | ||
| CREATE_ITERATOR_HELPER: state.addHelper(builder.helper), | ||
| ITERATOR_HELPER: scope.generateUidIdentifier("iteratorHelper"), |
There was a problem hiding this comment.
Nit:
| ITERATOR_HELPER: scope.generateUidIdentifier("iteratorHelper"), | |
| ITERATOR_HELPER: scope.generateUidIdentifier("iterator"), |
| // push the rest of the original loop body onto our new body | ||
| block.body = block.body.concat(node.body.body); | ||
| t.inherits(container[0], node); | ||
| t.inherits(container[0].body, node.body); |
There was a problem hiding this comment.
Does container ever contain more than one element? If not, we can replace the replaceWithMultiple with replaceWith and drop the parent.isLabeledStatement() check.
There was a problem hiding this comment.
container always contains a single node. However:
- We are doing
replaceWithMultiple(nodes), and in non-loose modenodescontains 2 nodes (the var declaration and the try statement) - We can't drop the
parent.isLabeledStatement()check because in non-loose mode it the label must be moved to the inner loop. If we only didpath.replaceWith()it would be attached to thetrystatement.
There was a problem hiding this comment.
If we only did path.replaceWith() it would be attached to the try statement.
I think that would actually be equivalent. The finally block should still fire correctly.
There was a problem hiding this comment.
But then, it doesn't work with continue.
There was a problem hiding this comment.
Ohhh. I was only thinking about break.
| ); | ||
|
|
||
| if ( | ||
| t.isIdentifier(left) || |
There was a problem hiding this comment.
nit: It suffices to check t.isVariableDeclaration first and assuming it's LVal in the else branch, because we have validated ForOfStatement.left even when BABEL_TYPES_8_BREAKING is not enabled:
(Oh it is copied from the old codes.)
Dis greatly recudes the code size when for-of is used multiple times across the codebase. Also, makes it easier to read what's happening in a compiled loop.
4173b6c to
771986f
Compare
This greatly reduces the code size (*) when for-of is used multiple times across the
codebase. Also, makes it easier to read what's happening in a compiled loop.
(*) I tested the difference with 3 for loops before adding the human-friendly error message about the missing
Symbol.iterator. I didn't usetransform-runtimeorexternal-helpers, so these numbers include the helper size.These are the minified sizes (with terser):
Since the error message is a bit more than 100 bytes long, the size improvement probably needs 4 loops rather than one now. However, keep in mind that if I added the human-friendly error message to the old implementation it would have added 100 bytes 3 times, making the size improvement even bigger.
Size test code
Part 1/n