Add getBindingIdentifierPaths/getOuterBindingIdentifierPaths (#4876)

This commit is contained in:
Boopathi Rajaa 2016-12-08 18:43:14 +01:00 committed by Henry Zhu
parent 32aa1f75d6
commit 73ff13f326
2 changed files with 121 additions and 0 deletions

View File

@ -125,3 +125,64 @@ export function getBindingIdentifiers(duplicates?) {
export function getOuterBindingIdentifiers(duplicates?) {
return t.getOuterBindingIdentifiers(this.node, duplicates);
}
// original source - https://github.com/babel/babel/blob/master/packages/babel-types/src/retrievers.js
// path.getBindingIdentifiers returns nodes where the following re-implementation
// returns paths
export function getBindingIdentifierPaths(duplicates = false, outerOnly = false) {
let path = this;
let search = [].concat(path);
let ids = Object.create(null);
while (search.length) {
let id = search.shift();
if (!id) continue;
if (!id.node) continue;
let keys = t.getBindingIdentifiers.keys[id.node.type];
if (id.isIdentifier()) {
if (duplicates) {
let _ids = ids[id.node.name] = ids[id.node.name] || [];
_ids.push(id);
} else {
ids[id.node.name] = id;
}
continue;
}
if (id.isExportDeclaration()) {
const declaration = id.get("declaration");
if (declaration.isDeclaration()) {
search.push(declaration);
}
continue;
}
if (outerOnly) {
if (id.isFunctionDeclaration()) {
search.push(id.get("id"));
continue;
}
if (id.isFunctionExpression()) {
continue;
}
}
if (keys) {
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let child = id.get(key);
if (Array.isArray(child) || child.node) {
search = search.concat(child);
}
}
}
}
return ids;
}
export function getOuterBindingIdentifierPaths(duplicates?) {
return this.getBindingIdentifierPaths(duplicates, true);
}

View File

@ -0,0 +1,60 @@
let traverse = require("../lib").default;
let assert = require("assert");
let parse = require("babylon").parse;
describe("path/family", function () {
describe("getBindingIdentifiers", function () {
let ast = parse("var a = 1, {b} = c, [d] = e; function f() {}");
let nodes = {}, paths = {}, outerNodes = {}, outerPaths = {};
traverse(ast, {
VariableDeclaration(path) {
nodes = path.getBindingIdentifiers();
paths = path.getBindingIdentifierPaths();
},
FunctionDeclaration(path) {
outerNodes = path.getOuterBindingIdentifiers();
outerPaths = path.getOuterBindingIdentifierPaths();
}
});
it("should contain keys of nodes in paths", function () {
Object.keys(nodes).forEach((id) => {
assert.strictEqual(hop(paths, id), true, "Node's keys exists in paths");
});
});
it("should contain outer bindings", function () {
Object.keys(outerNodes).forEach((id) => {
assert.strictEqual(hop(outerPaths, id), true, "Has same outer keys");
});
});
it("should return paths", function () {
Object.keys(paths).forEach((id) => {
assert.strictEqual(!!paths[id].node, true, "Has a property node that's not falsy");
assert.strictEqual(paths[id].type, paths[id].node.type, "type matches");
});
Object.keys(outerPaths).forEach((id) => {
assert.strictEqual(!!outerPaths[id].node, true, "has property node");
assert.strictEqual(outerPaths[id].type, outerPaths[id].node.type, "type matches");
});
});
it("should match paths and nodes returned for the same ast", function () {
Object.keys(nodes).forEach((id) => {
assert.strictEqual(nodes[id], paths[id].node, "Nodes match");
});
});
it("should match paths and nodes returned for outer Bindings", function () {
Object.keys(outerNodes).forEach((id) => {
assert.strictEqual(outerNodes[id], outerPaths[id].node, "nodes match");
});
});
});
});
function hop(o, key) {
return Object.hasOwnProperty.call(o, key);
}