fix bad .gitignore paths resulting in some tests and path/lib files not being included...
This commit is contained in:
130
src/babel/traversal/path/lib/hoister.js
Normal file
130
src/babel/traversal/path/lib/hoister.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import * as react from "../../../transformation/helpers/react";
|
||||
import * as t from "../../../types";
|
||||
|
||||
var referenceVisitor = {
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (this.isJSXIdentifier() && react.isCompatTag(node.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// direct references that we need to track to hoist this to the highest scope we can
|
||||
var bindingInfo = scope.getBinding(node.name);
|
||||
if (!bindingInfo) return;
|
||||
|
||||
// this binding isn't accessible from the parent scope so we can safely ignore it
|
||||
// eg. it's in a closure etc
|
||||
if (bindingInfo !== state.scope.getBinding(node.name)) return;
|
||||
|
||||
if (bindingInfo.constant) {
|
||||
state.bindings[node.name] = bindingInfo;
|
||||
} else {
|
||||
for (var violationPath of (bindingInfo.constantViolations: Array)) {
|
||||
state.breakOnScopePaths.push(violationPath.scope.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default class PathHoister {
|
||||
constructor(path, scope) {
|
||||
this.breakOnScopePaths = [];
|
||||
this.bindings = {};
|
||||
this.scopes = [];
|
||||
this.scope = scope;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
isCompatibleScope(scope) {
|
||||
for (var key in this.bindings) {
|
||||
var binding = this.bindings[key];
|
||||
if (!scope.bindingIdentifierEquals(key, binding.identifier)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getCompatibleScopes() {
|
||||
var scope = this.path.scope;
|
||||
do {
|
||||
if (this.isCompatibleScope(scope)) {
|
||||
this.scopes.push(scope);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.breakOnScopePaths.indexOf(scope.path) >= 0) {
|
||||
break;
|
||||
}
|
||||
} while(scope = scope.parent);
|
||||
}
|
||||
|
||||
getAttachmentPath() {
|
||||
var scopes = this.scopes;
|
||||
|
||||
var scope = scopes.pop();
|
||||
if (!scope) return;
|
||||
|
||||
if (scope.path.isFunction()) {
|
||||
if (this.hasOwnParamBindings(scope)) {
|
||||
// should ignore this scope since it's ourselves
|
||||
if (this.scope.is(scope)) return;
|
||||
|
||||
// needs to be attached to the body
|
||||
return scope.path.get("body").get("body")[0];
|
||||
} else {
|
||||
// doesn't need to be be attached to this scope
|
||||
return this.getNextScopeStatementParent();
|
||||
}
|
||||
} else if (scope.path.isProgram()) {
|
||||
return this.getNextScopeStatementParent();
|
||||
}
|
||||
}
|
||||
|
||||
getNextScopeStatementParent() {
|
||||
var scope = this.scopes.pop();
|
||||
if (scope) return scope.path.getStatementParent();
|
||||
}
|
||||
|
||||
hasOwnParamBindings(scope) {
|
||||
for (var name in this.bindings) {
|
||||
if (!scope.hasOwnBinding(name)) continue;
|
||||
|
||||
var binding = this.bindings[name];
|
||||
if (binding.kind === "param") return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
run() {
|
||||
var node = this.path.node;
|
||||
if (node._hoisted) return;
|
||||
node._hoisted = true;
|
||||
|
||||
this.path.traverse(referenceVisitor, this);
|
||||
|
||||
this.getCompatibleScopes();
|
||||
|
||||
var path = this.getAttachmentPath();
|
||||
if (!path) return;
|
||||
|
||||
var uid = path.scope.generateUidIdentifier("ref");
|
||||
|
||||
path.insertBefore([
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, this.path.node)
|
||||
])
|
||||
]);
|
||||
|
||||
var parent = this.path.parentPath;
|
||||
|
||||
if (parent.isJSXElement() && this.path.container === parent.node.children) {
|
||||
// turning the `span` in `<div><span /></div>` to an expression so we need to wrap it with
|
||||
// an expression container
|
||||
uid = t.jSXExpressionContainer(uid);
|
||||
}
|
||||
|
||||
this.path.replaceWith(uid);
|
||||
}
|
||||
}
|
||||
71
src/babel/traversal/path/lib/removal-hooks.js
Normal file
71
src/babel/traversal/path/lib/removal-hooks.js
Normal file
@@ -0,0 +1,71 @@
|
||||
// This file contains all the cases where we have to perform additional logic when performing
|
||||
// specific operations in order to retain correct JavaScript semantics.
|
||||
|
||||
import * as t from "../../../types";
|
||||
|
||||
// pre hooks should be used for either rejecting removal or delegating removal to a replacement
|
||||
export var pre = [
|
||||
function (self, parent) {
|
||||
if (self.key === "body" && self.isBlockStatement() && parent.isFunction()) {
|
||||
// lol nah, you'll break stuff
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
function (self, parent) {
|
||||
// attempting to remove body of an arrow function so we just replace it with undefined
|
||||
if (self.key === "body" && parent.isArrowFunctionExpression()) {
|
||||
self.replaceWith(t.identifier("undefined"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// post hooks should be used for cleaning up parents
|
||||
export var post = [
|
||||
function (self, parent) {
|
||||
// just remove a declaration for an export so this is no longer valid
|
||||
if (self.key === "declaration" && parent.isExportDeclaration()) {
|
||||
parent.remove();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
function (self, parent) {
|
||||
// we've just removed the last declarator of a variable declaration so there's no point in
|
||||
// keeping it
|
||||
if (parent.isVariableDeclaration() && parent.node.declarations.length === 0) {
|
||||
parent.remove();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
function (self, parent) {
|
||||
// we're the child of an expression statement so we should remove the parent
|
||||
if (parent.isExpressionStatement()) {
|
||||
parent.remove();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
function (self, parent) {
|
||||
// we've just removed the second element of a sequence expression so let's turn that sequence
|
||||
// expression into a regular expression
|
||||
if (parent.isSequenceExpression() && parent.node.expressions.length === 1) {
|
||||
parent.replaceWith(parent.node.expressions[0]);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
function (self, parent) {
|
||||
// we're in a binary expression, better remove it and replace it with the last expression
|
||||
if (parent.isBinary()) {
|
||||
if (self.key === "left") {
|
||||
parent.replaceWith(parent.node.right);
|
||||
} else { // key === "right"
|
||||
parent.replaceWith(parent.node.left);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
];
|
||||
34
src/babel/traversal/path/lib/virtual-types.js
Normal file
34
src/babel/traversal/path/lib/virtual-types.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var ReferencedIdentifier = {
|
||||
types: ["Identifier", "JSXIdentifier"],
|
||||
checkPath(path, opts) {
|
||||
return t.isReferencedIdentifier(path.node, path.parent, opts);
|
||||
}
|
||||
};
|
||||
|
||||
export var Scope = {
|
||||
types: ["Scopable"],
|
||||
checkPath(path) {
|
||||
return t.isScope(path.node, path.parent);
|
||||
}
|
||||
};
|
||||
|
||||
export var Referenced = {
|
||||
checkPath(path) {
|
||||
return t.isReferenced(path.node, path.parent);
|
||||
}
|
||||
};
|
||||
|
||||
export var BlockScoped = {
|
||||
checkPath(path) {
|
||||
return t.isBlockScoped(path.node);
|
||||
}
|
||||
};
|
||||
|
||||
export var Var = {
|
||||
types: ["VariableDeclaration"],
|
||||
checkPath(path) {
|
||||
return t.isVar(path.node);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user