@@ -111,6 +111,23 @@ module.exports = class SymbolTree {
111111 }
112112
113113 /**
114+ * Find the inclusive descendant that is last in tree order of the given object.
115+ *
116+ * `O(n)` (worst case)
117+ *
118+ * @method lastInclusiveDescendant
119+ * @param {Object } object
120+ * @return {Object }
121+ */
122+ lastInclusiveDescendant ( object ) {
123+ let last ;
124+
125+ while ( ( last = this . _node ( object ) . last ) ) {
126+ object = last ;
127+ }
128+
129+ return object ;
130+ }
114131 * Find the preceding object ( A ) of the given object ( B ) .
115132 * An object A is preceding an object B if A and B are in the same tree
116133 * and A comes before B in tree order .
@@ -126,15 +143,10 @@ module.exports = class SymbolTree {
126143 return null;
127144 }
128145
129- // if we have a previous sibling, return the last child of the last child of the ...
130- if ( this . _node ( object ) . prev ) {
131- object = this . _node ( object ) . prev ;
146+ const prev = this._node(object).prev;
132147
133- while ( this . _node ( object ) . last ) {
134- object = this . _node ( object ) . last ;
135- }
136-
137- return object ;
148+ if (prev) {
149+ return this.lastInclusiveDescendant(prev);
138150 }
139151
140152 // if there is no previous sibling return the parent (might be null)
@@ -154,17 +166,21 @@ module.exports = class SymbolTree {
154166 * @returns {?Object}
155167 */
156168 following(object, treeRoot, skipChildren) {
157- if ( ! skipChildren && this . _node ( object ) . first ) {
158- return this . _node ( object ) . first ;
169+ const first = !skipChildren && this._node(object).first;
170+
171+ if (first) {
172+ return first;
159173 }
160174
161175 do {
162176 if (object === treeRoot) {
163177 return null;
164178 }
165179
166- if ( this . _node ( object ) . next ) {
167- return this . _node ( object ) . next ;
180+ const next = this._node(object).next;
181+
182+ if (next) {
183+ return next;
168184 }
169185
170186 object = this._node(object).parent;
0 commit comments