clarity-pattern-parser 11.4.2 → 11.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/Node.d.ts +5 -5
- package/dist/index.browser.js +43 -13
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +43 -13
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +43 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ast/Node.test.ts +38 -0
- package/src/ast/Node.ts +41 -14
package/package.json
CHANGED
package/src/ast/Node.test.ts
CHANGED
|
@@ -477,4 +477,42 @@ describe("Node", () => {
|
|
|
477
477
|
expect(result.isEqual(expected)).toBeTruthy();
|
|
478
478
|
});
|
|
479
479
|
|
|
480
|
+
test("Find All", () => {
|
|
481
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
482
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
483
|
+
const a2 = a.clone();
|
|
484
|
+
const parent = new Node("parent", "parent", 0, 0, [a, b, a2]);
|
|
485
|
+
|
|
486
|
+
const result = parent.findAll(n => n.name === "a");
|
|
487
|
+
expect(result).toEqual([a, a2]);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
test("Breadth First Early Exit", () => {
|
|
491
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
492
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
493
|
+
const a2 = a.clone();
|
|
494
|
+
const parent = new Node("parent", "parent", 0, 0, [a, b, a2]);
|
|
495
|
+
|
|
496
|
+
let count = 0;
|
|
497
|
+
parent.walkBreadthFirst(n => {
|
|
498
|
+
count++;
|
|
499
|
+
if (n.name === "a") {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
return true;
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
expect(count).toBe(2);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test("Find All (Breadth First)", () => {
|
|
509
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
510
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
511
|
+
const a2 = a.clone();
|
|
512
|
+
const parent = new Node("parent", "parent", 0, 0, [a, b, a2]);
|
|
513
|
+
|
|
514
|
+
const result = parent.findAll(n => n.name === "a", true);
|
|
515
|
+
expect(result).toEqual([a, a2]);
|
|
516
|
+
});
|
|
517
|
+
|
|
480
518
|
});
|
package/src/ast/Node.ts
CHANGED
|
@@ -190,16 +190,40 @@ export class Node {
|
|
|
190
190
|
return null;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
find(predicate: (node: Node) => boolean): Node | null {
|
|
194
|
-
|
|
193
|
+
find(predicate: (node: Node) => boolean, breadthFirst = false): Node | null {
|
|
194
|
+
let match: Node | null = null;
|
|
195
|
+
|
|
196
|
+
if (breadthFirst) {
|
|
197
|
+
this.walkBreadthFirst(n => {
|
|
198
|
+
if (predicate(n)) {
|
|
199
|
+
match = n;
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
204
|
+
this.walkUp(n => {
|
|
205
|
+
if (predicate(n)) {
|
|
206
|
+
match = n;
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return match;
|
|
195
213
|
}
|
|
196
214
|
|
|
197
|
-
findAll(predicate: (node: Node) => boolean): Node[] {
|
|
215
|
+
findAll(predicate: (node: Node) => boolean, breadthFirst = false): Node[] {
|
|
198
216
|
const matches: Node[] = [];
|
|
199
217
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
218
|
+
if (breadthFirst) {
|
|
219
|
+
this.walkBreadthFirst(n => {
|
|
220
|
+
if (predicate(n)) { matches.push(n); }
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
this.walkUp(n => {
|
|
224
|
+
if (predicate(n)) { matches.push(n);}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
203
227
|
|
|
204
228
|
return matches;
|
|
205
229
|
}
|
|
@@ -229,28 +253,31 @@ export class Node {
|
|
|
229
253
|
return null;
|
|
230
254
|
}
|
|
231
255
|
|
|
232
|
-
walkUp(callback: (node: Node) => void) {
|
|
256
|
+
walkUp(callback: (node: Node) => boolean | void): boolean {
|
|
233
257
|
const childrenCopy = this._children.slice();
|
|
234
258
|
|
|
235
|
-
childrenCopy.
|
|
236
|
-
callback(this);
|
|
259
|
+
const result = childrenCopy.every(c => c.walkUp(callback));
|
|
260
|
+
return (callback(this) ?? true) && result;
|
|
237
261
|
}
|
|
238
262
|
|
|
239
|
-
walkDown(callback: (node: Node) => void) {
|
|
263
|
+
walkDown(callback: (node: Node) => boolean | void): boolean {
|
|
240
264
|
const childrenCopy = this._children.slice();
|
|
241
265
|
|
|
242
|
-
callback(this);
|
|
243
|
-
childrenCopy.forEach(c => c.walkDown(callback));
|
|
266
|
+
return (callback(this) ?? true) && childrenCopy.every(c => c.walkDown(callback));
|
|
244
267
|
}
|
|
245
268
|
|
|
246
|
-
walkBreadthFirst(callback: (node: Node) => void):
|
|
269
|
+
walkBreadthFirst(callback: (node: Node) => boolean | void): boolean {
|
|
247
270
|
const queue: Node[] = [this];
|
|
248
271
|
|
|
249
272
|
while (queue.length > 0) {
|
|
250
273
|
const current = queue.shift() as Node;
|
|
251
|
-
callback(current)
|
|
274
|
+
if (callback(current) === false) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
252
277
|
queue.push(...current.children);
|
|
253
278
|
}
|
|
279
|
+
|
|
280
|
+
return true;
|
|
254
281
|
}
|
|
255
282
|
|
|
256
283
|
transform(visitors: Record<string, (node: Node) => Node>) {
|