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 util = require("../../util");
|
||||||
var t = require("../../types");
|
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) {
|
module.exports = function (node, file, scope) {
|
||||||
var key = t.toComputedKey(node, node.key);
|
var key = t.toComputedKey(node, node.key);
|
||||||
if (!t.isLiteral(key)) return node; // we can't set a function id with this
|
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),
|
outerDeclar: scope.get(id, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
traverse(node, {
|
traverse(node, traverser, scope, state);
|
||||||
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);
|
|
||||||
|
|
||||||
if (state.selfReference) {
|
if (state.selfReference) {
|
||||||
node.value = util.template("property-method-assignment-wrapper", {
|
node.value = util.template("property-method-assignment-wrapper", {
|
||||||
|
|||||||
@ -16,35 +16,51 @@ function DefaultFormatter(file) {
|
|||||||
//this.checkCollisions();
|
//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 () {
|
DefaultFormatter.prototype.getLocalExports = function () {
|
||||||
var localExports = {};
|
var localExports = {};
|
||||||
|
traverse(this.file.ast, exportsTraverser, null, 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);
|
|
||||||
|
|
||||||
return 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 () {
|
DefaultFormatter.prototype.getLocalImports = function () {
|
||||||
var localImports = {};
|
var localImports = {};
|
||||||
|
traverse(this.file.ast, importsTraverser, null, localImports);
|
||||||
traverse(this.file.ast, {
|
|
||||||
enter: function (node, parent, scope, context, localImports) {
|
|
||||||
if (t.isImportDeclaration(node)) {
|
|
||||||
_.extend(localImports, t.getIds(node, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, null, localImports);
|
|
||||||
|
|
||||||
return 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 () {
|
DefaultFormatter.prototype.checkCollisions = function () {
|
||||||
// todo: all check export collissions
|
// todo: all check export collissions
|
||||||
|
|
||||||
@ -61,21 +77,7 @@ DefaultFormatter.prototype.checkCollisions = function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
traverse(file.ast, {
|
traverse(file.ast, collissionsTraverser, null, check);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||||
|
|||||||
@ -1,6 +1,46 @@
|
|||||||
var traverse = require("../../traverse");
|
var traverse = require("../../traverse");
|
||||||
var t = require("../../types");
|
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 go = function (getBody, node, file, scope) {
|
||||||
var argumentsId;
|
var argumentsId;
|
||||||
var thisId;
|
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
|
// traverse the function and find all alias functions so we can alias
|
||||||
// `arguments` and `this` if necessary
|
// `arguments` and `this` if necessary
|
||||||
traverse(node, {
|
traverse(node, functionTraverser, null, state);
|
||||||
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);
|
|
||||||
|
|
||||||
var body;
|
var body;
|
||||||
|
|
||||||
|
|||||||
@ -129,6 +129,14 @@ exports.buildDefineProperties = function (mutatorMap) {
|
|||||||
return objExpr;
|
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) {
|
exports.template = function (name, nodes, keepExpression) {
|
||||||
var template = exports.templates[name];
|
var template = exports.templates[name];
|
||||||
if (!template) throw new ReferenceError("unknown template " + name);
|
if (!template) throw new ReferenceError("unknown template " + name);
|
||||||
@ -141,13 +149,7 @@ exports.template = function (name, nodes, keepExpression) {
|
|||||||
template = _.cloneDeep(template);
|
template = _.cloneDeep(template);
|
||||||
|
|
||||||
if (!_.isEmpty(nodes)) {
|
if (!_.isEmpty(nodes)) {
|
||||||
traverse(template, {
|
traverse(template, templateTraverser, null, nodes);
|
||||||
enter: function (node, parent, scope, context, nodes) {
|
|
||||||
if (t.isIdentifier(node) && _.has(nodes, node.name)) {
|
|
||||||
return nodes[node.name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, null, nodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var node = template.body[0];
|
var node = template.body[0];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user