-
Notifications
You must be signed in to change notification settings - Fork 18
/
PreOrderCusrorIterator.ts
61 lines (48 loc) · 1.41 KB
/
PreOrderCusrorIterator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { TreeCursor as NodeTreeCursor, Point as NodePoint } from 'tree-sitter';
import { TreeCursor as WebTreeCursor, Point as WebPoint } from 'web-tree-sitter';
type TreeCursor = NodeTreeCursor | WebTreeCursor;
type Point = NodePoint | WebPoint;
interface SyntaxNodeSurrogate {
type: string;
startPosition: Point;
endPosition: Point;
[key: string]: unknown;
}
class PreOrderCursorIterator {
protected cursor;
constructor(cursor: TreeCursor) {
this.cursor = cursor;
}
protected createNode(): SyntaxNodeSurrogate {
return {
type: this.cursor.nodeType,
startPosition: this.cursor.startPosition,
endPosition: this.cursor.endPosition,
};
}
public *[Symbol.iterator]() {
let reachedRoot = false;
while (!reachedRoot) {
// @ts-ignore
const method = this[this.cursor.nodeType];
yield (method || this.createNode).call(this) as SyntaxNodeSurrogate;
if (this.cursor.gotoFirstChild()) {
continue; // eslint-disable-line no-continue
}
if (this.cursor.gotoNextSibling()) {
continue; // eslint-disable-line no-continue
}
let retracting = true;
while (retracting) {
if (!this.cursor.gotoParent()) {
retracting = false;
reachedRoot = true;
}
if (this.cursor.gotoNextSibling()) {
retracting = false;
}
}
}
}
}
export default PreOrderCursorIterator;