From bbdf71f611fcef2973ebc2d7cd32e92cd3982e9d 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 * forEachNextSibling * forEachPrevSibling --- packages/babel-traverse/src/path/family.js | 24 ++++++++++++++++++++++ packages/babel-traverse/test/family.js | 24 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/packages/babel-traverse/src/path/family.js b/packages/babel-traverse/src/path/family.js index d17ae8aed709..ba6c4da07f17 100644 --- a/packages/babel-traverse/src/path/family.js +++ b/packages/babel-traverse/src/path/family.js @@ -67,6 +67,30 @@ export function getSibling(key) { }); } +export function getPrevSibling() { + return this.getSibling(this.key - 1); +} + +export function getNextSibling() { + return this.getSibling(this.key + 1); +} + +export function forEachNextSibling(callback = Function.prototype) { + let _key = this.key, nextSibling = this.getSibling(++_key); + while (nextSibling.node) { + callback(nextSibling); + nextSibling = this.getSibling(++_key); + } +} + +export function forEachPrevSibling(callback = Function.prototype) { + let _key = this.key, nextSibling = this.getSibling(--_key); + while (nextSibling.node) { + callback(nextSibling); + nextSibling = this.getSibling(--_key); + } +} + 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..1bd4398490ce 100644 --- a/packages/babel-traverse/test/family.js +++ b/packages/babel-traverse/test/family.js @@ -52,6 +52,30 @@ 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() {}"); + let sibling = {}; + traverse(ast, { + VariableDeclaration(path) { + sibling = path.getSibling(path.key); + } + }); + it("should return traverse sibling nodes", function () { + assert.strictEqual(!!sibling.getNextSibling().node, true, "has property node"); + assert.strictEqual(!!sibling.getNextSibling().getPrevSibling().node, true, "has property node"); + let nextSiblings = 0, prevSiblings = 0; + sibling.forEachNextSibling(() => { + nextSiblings++; + }); + assert.strictEqual(!!nextSiblings, true, "Has next sibling"); + + sibling.getNextSibling().forEachPrevSibling(() => { + prevSiblings++; + }); + assert.strictEqual(!!prevSiblings, true, "Has prev sibling"); + }); }); });