Compare commits

...

4 Commits

Author SHA1 Message Date
Sebastian McKenzie
0ee4a15d01 v1.14.17 2014-12-06 23:37:32 +11:00
Sebastian McKenzie
fbdaedc4f8 remove unused loopParent variable 2014-12-06 23:36:28 +11:00
Sebastian McKenzie
75c8d73d35 add default initializer to let variables within loop bodies and fix excessive break replacement inside of switches in let scoping - fixes #255 2014-12-06 23:35:47 +11:00
Sebastian McKenzie
21599d3a9a change memoisation to memoization 2014-12-06 20:49:33 +11:00
6 changed files with 65 additions and 7 deletions

View File

@@ -1,3 +1,8 @@
# 1.14.17
* Add default initializer to let variables within loop bodies.
* Fix excessive `break` replacement inside of switches in let scoping.
# 1.14.16
* Add object getter memos and this shorthand to playground.

View File

@@ -18,7 +18,7 @@ to5.transform("code", { playground: true });
* [Memoization operator](#memoization-operator)
* [Method binding](#method-binding)
* [Object getter memoisation](#object-getter-memoisation)
* [Object getter memoization](#object-getter-memoization)
* [This shorthand](#this-shorthand)
### Memoization assignment operator
@@ -69,7 +69,7 @@ var fn = obj.method.bind(obj, "foob");
[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); });
```
### Object getter memoisation
### Object getter memoization
```javascript
var foo = {

View File

@@ -91,6 +91,9 @@ LetScoping.prototype.run = function () {
// remap all let references that exist in upper scopes to their uid
this.remap();
// add default initializer to let variables in loop bodys
this.initialiseLoopLets();
// this is a block within a `Function` so we can safely leave it be
if (t.isFunction(this.parent)) return this.noClosure();
@@ -106,7 +109,7 @@ LetScoping.prototype.run = function () {
// if we're inside of a for loop then we search to see if there are any
// `break`s, `continue`s, `return`s etc
this.has = this.checkFor();
this.has = this.checkLoop();
// hoist var references to retain scope
this.hoistVarDeclarations();
@@ -244,6 +247,30 @@ LetScoping.prototype.getInfo = function () {
return opts;
};
/**
* Any let variable declared within a loop body need to have an initializer or
* else they'll be hoisted and subsequent iterations of the loop will have a
* previous state. This function adds a default initializer of `undefined` to
* those variables.
*/
LetScoping.prototype.initialiseLoopLets = function () {
var loopParent = this.loopParent;
if (!loopParent) return;
traverse(this.block, function (node) {
if (t.isFunction(node) || t.isLoop(node)) {
return false;
}
if (isLet(node)) {
_.each(node.declarations, function (declar) {
declar.init = declar.init || t.identifier("undefined");
});
}
});
};
/**
* If we're inside of a `For*Statement` then traverse it and check if it has one
* of the following node types `ReturnStatement`, `BreakStatement`,
@@ -253,22 +280,24 @@ LetScoping.prototype.getInfo = function () {
* @returns {Object}
*/
LetScoping.prototype.checkFor = function () {
LetScoping.prototype.checkLoop = function () {
var has = {
hasContinue: false,
hasReturn: false,
hasBreak: false,
};
traverse(this.block, function (node) {
traverse(this.block, function (node, parent) {
var replace;
if (t.isFunction(node) || t.isLoop(node) || t.isSwitchStatement(node)) {
if (t.isFunction(node) || t.isLoop(node)) {
return false;
}
if (node && !node.label) {
if (t.isBreakStatement(node)) {
if (t.isSwitchCase(parent)) return;
has.hasBreak = true;
replace = t.returnStatement(t.literal("break"));
} else if (t.isContinueStatement(node)) {

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "1.14.16",
"version": "1.14.17",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://github.com/6to5/6to5",
"repository": {

View File

@@ -0,0 +1,11 @@
while (value) {
let foo;
if (bar) {
foo = [];
}
if (foo) {
doIt();
}
}

View File

@@ -0,0 +1,13 @@
"use strict";
while (value) {
var foo = undefined;
if (bar) {
foo = [];
}
if (foo) {
doIt();
}
}