split up tdz into an optional transformer until it has a better implementation - fixes #527

This commit is contained in:
Sebastian McKenzie
2015-01-19 08:54:04 +11:00
parent ca41612109
commit 16b7ff972c
4 changed files with 52 additions and 46 deletions

View File

@@ -79,6 +79,7 @@ _.each({
constants: require("./transformers/es6-constants"),
letScoping: require("./transformers/es6-let-scoping"),
blockScopingTDZ: require("./transformers/optional-block-scoping-tdz"),
_blockHoist: require("./transformers/_block-hoist"),

View File

@@ -84,7 +84,7 @@ function LetScoping(loopParent, block, parent, scope, file) {
this.outsideLetReferences = {};
this.hasLetReferences = false;
this.letReferences = {};
this.letReferences = block._letReferences = {};
this.body = [];
}
@@ -98,7 +98,6 @@ LetScoping.prototype.run = function () {
block._letDone = true;
var needsClosure = this.getLetReferences();
this.checkTDZ();
// this is a block within a `Function/Program` so we can safely leave it be
if (t.isFunction(this.parent) || t.isProgram(this.block)) return;
@@ -113,48 +112,6 @@ LetScoping.prototype.run = function () {
}
};
/**
* Description
*/
LetScoping.prototype.checkTDZ = function () {
var state = {
letRefs: this.letReferences,
file: this.file
};
traverse(this.block, {
enter: function (node, parent, scope, context, state) {
if (!t.isIdentifier(node)) return;
if (!t.isReferenced(node, parent)) return;
var declared = state.letRefs[node.name];
if (!declared) return;
// declared node is different in this scope
if (scope.get(node.name, true) !== declared) return;
var declaredLoc = declared.loc;
var referenceLoc = node.loc;
if (!declaredLoc || !referenceLoc) return;
// does this reference appear on a line before the declaration?
var before = referenceLoc.start.line < declaredLoc.start.line;
if (referenceLoc.start.line === declaredLoc.start.line) {
// this reference appears on the same line
// check it appears before the declaration
before = referenceLoc.start.col < declaredLoc.start.col;
}
if (before) {
throw state.file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
}
}
}, this.scope, state);
};
/**
* Description
*/
@@ -179,7 +136,7 @@ LetScoping.prototype.remap = function () {
var uid = file.generateUidIdentifier(ref.name, scope).name;
ref.name = uid;
remaps[key] = {
remaps[key] = remaps[uid] = {
node: ref,
uid: uid
};

View File

@@ -0,0 +1,47 @@
var traverse = require("../../traverse");
var t = require("../../types");
exports.optional = true;
exports.Loop
exports.Program =
exports.BlockStatement = function (node, parent, scope, context, file) {
var letRefs = node._letReferences;
if (!letRefs) return;
var state = {
letRefs: letRefs,
file: file
};
traverse(node, {
enter: function (node, parent, scope, context, state) {
if (!t.isIdentifier(node)) return;
if (!t.isReferenced(node, parent)) return;
var declared = state.letRefs[node.name];
if (!declared) return;
// declared node is different in this scope
if (scope.get(node.name, true) !== declared) return;
var declaredLoc = declared.loc;
var referenceLoc = node.loc;
if (!declaredLoc || !referenceLoc) return;
// does this reference appear on a line before the declaration?
var before = referenceLoc.start.line < declaredLoc.start.line;
if (referenceLoc.start.line === declaredLoc.start.line) {
// this reference appears on the same line
// check it appears before the declaration
before = referenceLoc.start.col < declaredLoc.start.col;
}
if (before) {
throw state.file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
}
}
}, scope, state);
};