From e9274823c00ca90129456084507b366bdc8dec9a Mon Sep 17 00:00:00 2001 From: Vicente Jr Yuchitcho Date: Fri, 27 Jan 2017 17:00:08 +1100 Subject: [PATCH] Add path sibling traversal methods * getPrevSibling * getNextSibling * getAllNextSiblings * getAllPrevSiblings --- packages/babel-traverse/src/path/family.js | 32 +++++++++++++++++++++- packages/babel-traverse/test/family.js | 25 +++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/babel-traverse/src/path/family.js b/packages/babel-traverse/src/path/family.js index d17ae8aed709..3af5c1e02251 100644 --- a/packages/babel-traverse/src/path/family.js +++ b/packages/babel-traverse/src/path/family.js @@ -57,7 +57,7 @@ export function getCompletionRecords(): Array { return paths; } -export function getSibling(key) { +export function getSibling(key): NodePath { return NodePath.get({ parentPath: this.parentPath, parent: this.parent, @@ -67,6 +67,36 @@ export function getSibling(key) { }); } +export function getPrevSibling(): NodePath { + return this.getSibling(this.key - 1); +} + +export function getNextSibling(): NodePath { + return this.getSibling(this.key + 1); +} + +export function getAllNextSiblings(): Array { + let _key = this.key; + let sibling:NodePath = this.getSibling(++_key); + const siblings:Array = []; + while (sibling.node) { + siblings.push(sibling); + sibling = this.getSibling(++_key); + } + return siblings; +} + +export function getAllPrevSiblings(): Array { + let _key = this.key; + let sibling:NodePath = this.getSibling(--_key); + const siblings:Array = []; + while (sibling.node) { + siblings.push(sibling); + sibling = this.getSibling(--_key); + } + return siblings; +} + export function get(key: string, context?: boolean | TraversalContext): NodePath { if (context === true) context = this.context; const parts = key.split("."); diff --git a/packages/babel-traverse/test/family.js b/packages/babel-traverse/test/family.js index 6e9a497df746..6c34906c4401 100644 --- a/packages/babel-traverse/test/family.js +++ b/packages/babel-traverse/test/family.js @@ -52,6 +52,31 @@ describe("path/family", function () { assert.strictEqual(outerNodes[id], outerPaths[id].node, "nodes match"); }); }); + + }); + describe("getSibling", function () { + const ast = parse("var a = 1, {b} = c, [d] = e; function f() {} function g() {}"); + let sibling = {}, lastSibling = {}; + traverse(ast, { + VariableDeclaration(path) { + sibling = path.getSibling(path.key); + lastSibling = sibling.getNextSibling().getNextSibling(); + } + }); + + it("should return traverse sibling nodes", function () { + assert.ok(sibling.getNextSibling().node, "has property node"); + assert.ok(lastSibling.getPrevSibling().node, "has property node"); + assert.equal(!!sibling.getPrevSibling().node, false, "out of scope"); + assert.equal(!!lastSibling.getNextSibling().node, false, "out of scope"); + }); + + it("should return all preceding and succeeding sibling nodes", function () { + assert.ok(sibling.getAllNextSiblings().length, "Has next sibling"); + assert.ok(lastSibling.getAllPrevSiblings().length, "Has prev sibling"); + assert.equal(sibling.getAllNextSiblings().length, 2, "Has 2 succeeding sibling"); + assert.equal(lastSibling.getAllPrevSiblings().length, 2, "Has 2 preceeding sibling"); + }); }); });