Proof of concept of how traversal would look like with state parameter
This commit is contained in:
parent
f9480b5280
commit
ff9511d435
@ -2,6 +2,24 @@ var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var traverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: state.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(state.id, true);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
context.stop();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function (node, file, scope) {
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return node; // we can't set a function id with this
|
||||
@ -15,23 +33,7 @@ module.exports = function (node, file, scope) {
|
||||
outerDeclar: scope.get(id, true),
|
||||
};
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: state.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(state.id, true);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
context.stop();
|
||||
}
|
||||
}, scope, state);
|
||||
traverse(node, traverser, scope, state);
|
||||
|
||||
if (state.selfReference) {
|
||||
node.value = util.template("property-method-assignment-wrapper", {
|
||||
|
||||
@ -16,35 +16,51 @@ function DefaultFormatter(file) {
|
||||
//this.checkCollisions();
|
||||
}
|
||||
|
||||
var exportsTraverser = {
|
||||
enter: function (node, parent, scope, context, localExports) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) {
|
||||
_.extend(localExports, t.getIds(declar, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
var localExports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node, parent, scope, context, localExports) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) {
|
||||
_.extend(localExports, t.getIds(declar, true));
|
||||
}
|
||||
}
|
||||
}, null, localExports);
|
||||
|
||||
traverse(this.file.ast, exportsTraverser, null, localExports);
|
||||
return localExports;
|
||||
};
|
||||
|
||||
var importsTraverser = {
|
||||
enter: function (node, parent, scope, context, localImports) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
_.extend(localImports, t.getIds(node, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalImports = function () {
|
||||
var localImports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node, parent, scope, context, localImports) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
_.extend(localImports, t.getIds(node, true));
|
||||
}
|
||||
}
|
||||
}, null, localImports);
|
||||
|
||||
traverse(this.file.ast, importsTraverser, null, localImports);
|
||||
return localImports;
|
||||
};
|
||||
|
||||
var collissionsTraverser = {
|
||||
enter: function (node, parent, scope, context, check) {
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
|
||||
var left = node.left;
|
||||
if (t.isMemberExpression(left)) {
|
||||
while (left.object) left = left.object;
|
||||
}
|
||||
|
||||
check(left);
|
||||
} else if (t.isDeclaration(node)) {
|
||||
_.each(t.getIds(node, true), check);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.checkCollisions = function () {
|
||||
// todo: all check export collissions
|
||||
|
||||
@ -61,21 +77,7 @@ DefaultFormatter.prototype.checkCollisions = function () {
|
||||
}
|
||||
};
|
||||
|
||||
traverse(file.ast, {
|
||||
enter: function (node, parent, scope, context, check) {
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
|
||||
var left = node.left;
|
||||
if (t.isMemberExpression(left)) {
|
||||
while (left.object) left = left.object;
|
||||
}
|
||||
|
||||
check(left);
|
||||
} else if (t.isDeclaration(node)) {
|
||||
_.each(t.getIds(node, true), check);
|
||||
}
|
||||
}
|
||||
}, null, check);
|
||||
traverse(file.ast, collissionsTraverser, null, check);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
|
||||
@ -1,6 +1,46 @@
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
|
||||
var functionChildrenTraverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return context.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = state.getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = state.getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
}
|
||||
};
|
||||
|
||||
var functionTraverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return context.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, functionChildrenTraverser, null, state);
|
||||
|
||||
return context.skip();
|
||||
}
|
||||
};
|
||||
|
||||
var go = function (getBody, node, file, scope) {
|
||||
var argumentsId;
|
||||
var thisId;
|
||||
@ -16,43 +56,7 @@ var go = function (getBody, node, file, scope) {
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// `arguments` and `this` if necessary
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return context.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return context.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = state.getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = state.getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
}
|
||||
}, null, state);
|
||||
|
||||
return context.skip();
|
||||
}
|
||||
}, null, state);
|
||||
traverse(node, functionTraverser, null, state);
|
||||
|
||||
var body;
|
||||
|
||||
|
||||
@ -129,6 +129,14 @@ exports.buildDefineProperties = function (mutatorMap) {
|
||||
return objExpr;
|
||||
};
|
||||
|
||||
var templateTraverser = {
|
||||
enter: function (node, parent, scope, context, nodes) {
|
||||
if (t.isIdentifier(node) && _.has(nodes, node.name)) {
|
||||
return nodes[node.name];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.template = function (name, nodes, keepExpression) {
|
||||
var template = exports.templates[name];
|
||||
if (!template) throw new ReferenceError("unknown template " + name);
|
||||
@ -141,13 +149,7 @@ exports.template = function (name, nodes, keepExpression) {
|
||||
template = _.cloneDeep(template);
|
||||
|
||||
if (!_.isEmpty(nodes)) {
|
||||
traverse(template, {
|
||||
enter: function (node, parent, scope, context, nodes) {
|
||||
if (t.isIdentifier(node) && _.has(nodes, node.name)) {
|
||||
return nodes[node.name];
|
||||
}
|
||||
}
|
||||
}, null, nodes);
|
||||
traverse(template, templateTraverser, null, nodes);
|
||||
}
|
||||
|
||||
var node = template.body[0];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user