in src/main/com/intellij/lang/jsgraphql/types/util/Traverser.java [111:186]
public TraverserResult traverse(Collection<? extends T> roots, TraverserVisitor<? super T> visitor) {
assertNotNull(roots);
assertNotNull(visitor);
// "artificial" parent context for all roots with rootVars
DefaultTraverserContext<T> rootContext = traverserState.newRootContext(rootVars);
traverserState.addNewContexts(roots, rootContext);
DefaultTraverserContext currentContext;
Object currentAccValue = initialAccumulate;
traverseLoop:
while (!traverserState.isEmpty()) {
Object top = traverserState.pop();
if (top instanceof TraverserState.EndList) {
Map<String, List<TraverserContext<T>>> childrenContextMap = ((TraverserState.EndList<T>)top).childrenContextMap;
// end-of-list marker, we are done recursing children,
// mark the current node as fully visited
currentContext = (DefaultTraverserContext)traverserState.pop();
currentContext.setCurAccValue(currentAccValue);
currentContext.setChildrenContexts(childrenContextMap);
currentContext.setPhase(TraverserContext.Phase.LEAVE);
TraversalControl traversalControl = visitor.leave(currentContext);
currentAccValue = currentContext.getNewAccumulate();
assertNotNull(traversalControl, () -> "result of leave must not be null");
assertTrue(CONTINUE_OR_QUIT.contains(traversalControl), () -> "result can only return CONTINUE or QUIT");
switch (traversalControl) {
case QUIT:
break traverseLoop;
case CONTINUE:
continue;
default:
assertShouldNeverHappen();
}
}
currentContext = (DefaultTraverserContext)top;
if (currentContext.isVisited()) {
currentContext.setCurAccValue(currentAccValue);
currentContext.setPhase(TraverserContext.Phase.BACKREF);
TraversalControl traversalControl = visitor.backRef(currentContext);
currentAccValue = currentContext.getNewAccumulate();
assertNotNull(traversalControl, () -> "result of backRef must not be null");
assertTrue(CONTINUE_OR_QUIT.contains(traversalControl), () -> "backRef can only return CONTINUE or QUIT");
if (traversalControl == QUIT) {
break traverseLoop;
}
}
else {
currentContext.setCurAccValue(currentAccValue);
Object nodeBeforeEnter = currentContext.thisNode();
currentContext.setPhase(TraverserContext.Phase.ENTER);
TraversalControl traversalControl = visitor.enter(currentContext);
currentAccValue = currentContext.getNewAccumulate();
assertNotNull(traversalControl, () -> "result of enter must not be null");
this.traverserState.addVisited((T)nodeBeforeEnter);
switch (traversalControl) {
case QUIT:
break traverseLoop;
case ABORT:
continue;
case CONTINUE:
traverserState.pushAll(currentContext, getChildren);
continue;
default:
assertShouldNeverHappen();
}
}
}
TraverserResult traverserResult = new TraverserResult(currentAccValue);
return traverserResult;
}