-
-
Notifications
You must be signed in to change notification settings - Fork 347
/
CtIterator.java
87 lines (79 loc) · 2.5 KB
/
CtIterator.java
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
* SPDX-License-Identifier: (MIT OR CECILL-C)
*
* Copyright (C) 2006-2019 INRIA and contributors
*
* Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) of the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon.
*/
package spoon.reflect.visitor;
import spoon.reflect.declaration.CtElement;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
/**
* A class to be able to iterate over the children elements in the tree of a given node, in depth-first order.
*/
public class CtIterator extends CtScanner implements Iterator<CtElement> {
/**
* A deque containing the elements the iterator has seen but not expanded
*/
private ArrayDeque<CtElement> deque = new ArrayDeque<CtElement>() {
/**
* add a collection of elements with addFirst instead of default add() which defaults to addLast()
* @param c Collection of CtElements
* @return true if this deque has changed, in accordance with original method
*/
@Override
public boolean addAll(Collection c) {
for (Object aC : c) {
this.addFirst((CtElement) aC);
}
return !c.isEmpty();
}
};
/**
* A deque to be used when scanning an element so that @deque preserves the elements in dfs without complete expansion
*/
private ArrayDeque<CtElement> current_children = new ArrayDeque<>();
/**
* CtIterator constructor, prepares the iterator from the @root node
*
* @param root the initial node to expand
*/
public CtIterator(CtElement root) {
if (root != null) {
deque.add(root);
}
}
/**
* prevent scanner from going down the tree, instead save with other CtElement children of the current node
*
* @param element the next direct child of the current node being expanded
*/
@Override
public void scan(CtElement element) {
if (element != null) {
current_children.addFirst(element);
}
}
@Override
public boolean hasNext() {
return !deque.isEmpty();
}
/**
* Dereference the "iterator"
*
* @return CtElement the next element in DFS order without going down the tree
*/
@Override
public CtElement next() {
if (!hasNext()) {
throw new java.util.NoSuchElementException();
}
CtElement next = deque.pollFirst(); // get the element to expand from the deque
current_children.clear(); // clear for this scan
next.accept(this); // call @scan for each direct child of the node
deque.addAll(current_children); // overridden method to add all to first
return next;
}
}