automatically explode visitors
This commit is contained in:
@@ -26,7 +26,6 @@ export const MESSAGES = {
|
||||
|
||||
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
|
||||
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
||||
traverseVerifyVisitorFunction: "You passed \`traverse()\` a visitor object with the key $1 that's a `Function` instead of `{ enter: Function }`. You need to normalise your visitor with `traverse.explode(visitor)`.",
|
||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import object from "../../helpers/object";
|
||||
import * as util from "../../util";
|
||||
import * as t from "../../types";
|
||||
|
||||
var remapVisitor = traverse.explode({
|
||||
var remapVisitor = {
|
||||
enter(node, parent, scope, formatter) {
|
||||
if (node._skipModulesRemap) {
|
||||
return this.skip();
|
||||
@@ -63,7 +63,7 @@ var remapVisitor = traverse.explode({
|
||||
|
||||
return t.sequenceExpression(nodes);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var importsVisitor = {
|
||||
ImportDeclaration: {
|
||||
@@ -74,7 +74,7 @@ var importsVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
var exportsVisitor = traverse.explode({
|
||||
var exportsVisitor = {
|
||||
ExportDeclaration: {
|
||||
enter(node, parent, scope, formatter) {
|
||||
formatter.hasLocalExports = true;
|
||||
@@ -106,7 +106,7 @@ var exportsVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default class DefaultFormatter {
|
||||
constructor(file) {
|
||||
|
||||
@@ -35,7 +35,7 @@ var collectPropertyReferencesVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
var constructorVisitor = traverse.explode({
|
||||
var constructorVisitor = {
|
||||
ThisExpression: {
|
||||
enter(node, parent, scope, ref) {
|
||||
return ref;
|
||||
@@ -49,9 +49,9 @@ var constructorVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var verifyConstructorVisitor = traverse.explode({
|
||||
var verifyConstructorVisitor = {
|
||||
MethodDefinition: {
|
||||
enter() {
|
||||
this.skip();
|
||||
@@ -96,7 +96,7 @@ var verifyConstructorVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
class ClassTransformer {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ var hasDefaults = function (node) {
|
||||
return false;
|
||||
};
|
||||
|
||||
var iifeVisitor = traverse.explode({
|
||||
var iifeVisitor = {
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (!state.scope.hasOwnBinding(node.name)) return;
|
||||
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
|
||||
@@ -18,7 +18,7 @@ var iifeVisitor = traverse.explode({
|
||||
state.iife = true;
|
||||
this.stop();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (!hasDefaults(node)) return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import traverse from "../../../traversal";
|
||||
import * as t from "../../../types";
|
||||
|
||||
var visitor = traverse.explode({
|
||||
var visitor = {
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (t.isFor(parent) && parent.left === node) return;
|
||||
|
||||
@@ -25,7 +25,7 @@ var visitor = traverse.explode({
|
||||
return t.logicalExpression("&&", assert, node);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var metadata = {
|
||||
optional: true,
|
||||
|
||||
@@ -21,7 +21,7 @@ function returnBlock(expr) {
|
||||
}
|
||||
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = traverse.explode({
|
||||
var firstPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isTryStatement(parent)) {
|
||||
if (node === parent.block) {
|
||||
@@ -45,11 +45,11 @@ var firstPass = traverse.explode({
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// hoists up function declarations, replaces `this` and `arguments` and marks
|
||||
// them as needed
|
||||
var secondPass = traverse.explode({
|
||||
var secondPass = {
|
||||
ThisExpression(node, parent, scope, state) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
@@ -71,10 +71,10 @@ var secondPass = traverse.explode({
|
||||
return node;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// optimizes recursion by removing `this` and `arguments` if they aren't used
|
||||
var thirdPass = traverse.explode({
|
||||
var thirdPass = {
|
||||
ExpressionStatement(node, parent, scope, state) {
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr)) return;
|
||||
@@ -87,7 +87,7 @@ var thirdPass = traverse.explode({
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
class TailCallTransformer {
|
||||
constructor(path, scope, file) {
|
||||
|
||||
@@ -14,7 +14,9 @@ export default function traverse(parent, opts, scope, state, parentPath) {
|
||||
}
|
||||
|
||||
if (!opts) opts = {};
|
||||
|
||||
visitors.verify(opts);
|
||||
visitors.explode(opts);
|
||||
|
||||
// array of nodes
|
||||
if (Array.isArray(parent)) {
|
||||
|
||||
@@ -4,6 +4,9 @@ import * as t from "../types";
|
||||
import esquery from "esquery";
|
||||
|
||||
export function explode(visitor, mergeConflicts) {
|
||||
if (visitor._exploded) return visitor;
|
||||
visitor._exploded = true;
|
||||
|
||||
// make sure there's no __esModule type since this is because we're using loose mode
|
||||
// and it sets __esModule to be enumerable on all modules :(
|
||||
delete visitor.__esModule;
|
||||
@@ -86,15 +89,12 @@ export function verify(visitor) {
|
||||
for (var nodeType in visitor) {
|
||||
if (shouldIgnoreKey(nodeType)) continue;
|
||||
|
||||
if (t.TYPES.indexOf(nodeType) < 0) {
|
||||
if (t.TYPES.indexOf(nodeType) < 0 && !virtualTypes[nodeType]) {
|
||||
throw new Error(messages.get("traverseVerifyNodeType", nodeType));
|
||||
}
|
||||
|
||||
var visitors = visitor[nodeType];
|
||||
|
||||
if (typeof visitors === "function") {
|
||||
throw new Error(messages.get("traverseVerifyVisitorFunction", nodeType));
|
||||
} else if (typeof visitors === "object") {
|
||||
if (typeof visitors === "object") {
|
||||
for (var visitorKey in visitors) {
|
||||
if (visitorKey === "enter" || visitorKey === "exit") continue;
|
||||
throw new Error(messages.get("traverseVerifyVisitorProperty", nodeType, visitorKey));
|
||||
|
||||
Reference in New Issue
Block a user