get rid of recusrion
[fedora-idea.git] / lang-impl / src / com / intellij / psi / impl / source / tree / RecursiveTreeElementWalkingVisitor.java
blobbd23a9eab516eaf04931754163407762d3206c6e
1 package com.intellij.psi.impl.source.tree;
3 import com.intellij.psi.impl.source.parsing.ChameleonTransforming;
5 public abstract class RecursiveTreeElementWalkingVisitor extends TreeElementVisitor{
6 private boolean startedWalking;
7 private boolean isDown;
8 private final boolean myDoTransform;
10 protected RecursiveTreeElementWalkingVisitor() {
11 this(true);
13 protected RecursiveTreeElementWalkingVisitor(boolean doTransform) {
14 myDoTransform = doTransform;
17 @Override public void visitLeaf(LeafElement leaf) {
18 visitNode(leaf);
21 @Override public void visitComposite(CompositeElement composite) {
22 if (myDoTransform) ChameleonTransforming.transformChildren(composite);
23 isDown = visitNode(composite);
24 if (!startedWalking) {
25 startedWalking = true;
26 walk(composite);
27 startedWalking = false;
31 private void walk(TreeElement root) {
32 for (TreeElement element = next(root, root); element != null; element = next(element, root)) {
33 CompositeElement parent = element.getTreeParent();
34 TreeElement next = element.getTreeNext();
35 isDown = false; // if client visitor did not call default visitElement it means skip subtree
36 element.acceptTree(this);
37 assert element.getTreeNext() == next;
38 assert element.getTreeParent() == parent;
42 private TreeElement next(TreeElement element, TreeElement root) {
43 if (isDown) {
44 TreeElement child = element.getFirstChildNode();
45 if (child != null) return child;
48 // up
49 while (element != root) {
50 TreeElement next = element.getTreeNext();
51 if (next != null) {
52 assert next.getTreePrev() == element;
53 return next;
55 element = element.getTreeParent();
57 return null;
60 protected boolean visitNode(TreeElement element){
61 return true;