rename traverse stop method to skip and add a stop method that actually breaks the current traversal

This commit is contained in:
Sebastian McKenzie
2015-01-03 20:08:31 +11:00
parent 51f7e75d2e
commit d20ab0eb05
8 changed files with 114 additions and 23 deletions

View File

@@ -51,7 +51,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
traverse(this.file.ast, {
enter: function (node, parent, scope) {
if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) {
this.stop();
this.skip();
// expand to long file assignment expression
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
@@ -79,7 +79,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
}
if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) {
this.stop();
this.skip();
return self.remapExportAssignment(node);
}
}

View File

@@ -114,7 +114,7 @@ SystemFormatter.prototype.transform = function (ast) {
enter: function (node, parent, scope) {
if (t.isFunction(node)) {
// nothing inside is accessible
return this.stop();
return this.skip();
}
if (t.isVariableDeclaration(node)) {
@@ -159,7 +159,7 @@ SystemFormatter.prototype.transform = function (ast) {
// hoist up function declarations for circular references
traverse(block, {
enter: function (node) {
if (t.isFunction(node)) this.stop();
if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || node._blockHoist) {
handlerBody.push(node);

View File

@@ -20,7 +20,7 @@ var go = function (getBody, node, file, scope) {
if (!node._aliasFunction) {
if (t.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return this.stop();
return this.skip();
} else {
return;
}
@@ -30,10 +30,10 @@ var go = function (getBody, node, file, scope) {
traverse(node, {
enter: function (node, parent) {
if (t.isFunction(node) && !node._aliasFunction) {
return this.stop();
return this.skip();
}
if (node._ignoreAliasFunctions) return this.stop();
if (node._ignoreAliasFunctions) return this.skip();
var getId;
@@ -49,7 +49,7 @@ var go = function (getBody, node, file, scope) {
}
});
return this.stop();
return this.skip();
}
});

View File

@@ -280,7 +280,7 @@ LetScoping.prototype.checkLoop = function () {
var replace;
if (t.isFunction(node) || t.isLoop(node)) {
return this.stop();
return this.skip();
}
if (node && !node.label) {
@@ -329,7 +329,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
} else if (isVar(node, parent)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return this.stop();
return this.skip();
}
}
});
@@ -388,9 +388,9 @@ LetScoping.prototype.getLetReferences = function () {
}
});
return this.stop();
return this.skip();
} else if (t.isLoop(node)) {
return this.stop();
return this.skip();
}
}
});

View File

@@ -0,0 +1,82 @@
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
exports.Property = function (node, parent, file, scope) {
if (!node.method) return;
node.method = false;
var key = t.toComputedPropertyKey(node);
if (!t.isLiteral(key)) return; // we can't set a function id with this
var id = t.toIdentifier(key.value);
key = t.identifier(id);
var selfReference = false;
var outerDeclar = scope.get(id, true);
traverse(node, {
enter: function (node, parent, scope) {
// check if this node is an identifier that matches the same as our function id
if (!t.isIdentifier(node, { name: id })) return;
// check if this node is the one referenced
if (!t.isReferenced(node, parent)) return;
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.get(id, true);
if (localDeclar !== outerDeclar) return;
selfReference = true;
this.stop();
}
}, scope);
if (selfReference) {
node.value = util.template("property-method-assignment-wrapper", {
FUNCTION: node.value,
FUNCTION_ID: key,
FUNCTION_KEY: file.generateUidIdentifier(id, scope),
WRAPPER_KEY: file.generateUidIdentifier(id + "Wrapper", scope)
});
} else {
node.value.id = key;
}
};
exports.ObjectExpression = function (node, parent, file) {
var mutatorMap = {};
var hasAny = false;
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
hasAny = true;
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
return false;
} else {
return true;
}
});
if (!hasAny) return;
if (node.properties.length) {
var objId = t.getUid(parent, file);
return util.template("object-define-properties-closure", {
KEY: objId,
OBJECT: node,
CONTENT: util.template("object-define-properties", {
OBJECT: objId,
PROPS: util.buildDefineProperties(mutatorMap)
})
});
} else {
return util.template("object-define-properties", {
OBJECT: node,
PROPS: util.buildDefineProperties(mutatorMap)
});
}
};

View File

@@ -29,7 +29,7 @@ exports.ast = {
if (!t.isReferenced(obj, node)) return;
if (!node.computed && coreHas(obj) && _.has(core[obj.name], prop.name)) {
this.stop();
this.skip();
return t.prependToMemberExpression(node, file._coreId);
}
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && coreHas(node)) {

View File

@@ -22,12 +22,14 @@ function traverse(parent, opts, scope) {
opts = opts || {};
var stopped = false;
for (var i in keys) {
var key = keys[i];
var nodes = parent[key];
if (!nodes) continue;
var updated = false;
var flatten = false;
var handle = function (obj, key) {
var node = obj[key];
@@ -50,7 +52,8 @@ function traverse(parent, opts, scope) {
// replace the node
node = obj[key] = result;
updated = true;
if (isArray) flatten = true;
// we're replacing a statement or block node with an array of statements so we better
// ensure that it's a block
@@ -59,16 +62,20 @@ function traverse(parent, opts, scope) {
}
};
var stopped = false;
var skipped = false;
var removed = false;
var context = {
stop: function () {
stopped = true;
skipped = stopped = true;
},
skip: function () {
skipped = true;
},
remove: function () {
this.stop();
this.skip();
removed = true;
}
};
@@ -84,11 +91,11 @@ function traverse(parent, opts, scope) {
if (removed) {
obj[key] = null;
updated = true;
flatten = true;
}
// stop iteration
if (stopped) return;
if (skipped) return;
}
// traverse node
@@ -103,9 +110,10 @@ function traverse(parent, opts, scope) {
if (_.isArray(nodes)) {
for (i in nodes) {
handle(nodes, i);
if (stopped) return;
}
if (updated) {
if (flatten) {
parent[key] = _.flatten(parent[key]);
if (key === "body") {
@@ -115,6 +123,7 @@ function traverse(parent, opts, scope) {
}
} else {
handle(parent, key);
if (stopped) return;
}
}
}
@@ -161,7 +170,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
enter: function (node) {
if (node.type === type) {
has = true;
this.stop();
this.skip();
}
}
});

View File

@@ -93,7 +93,7 @@ Scope.prototype.getInfo = function () {
// this block is a function so we'll stop since none of the variables
// declared within are accessible
if (t.isFunction(node)) return this.stop();
if (t.isFunction(node)) return this.skip();
// function identifier doesn't belong to this scope
if (block.id && node === block.id) return;