graphql.language.AstTransformer Maven / Gradle / Ivy
package graphql.language;
import graphql.PublicApi;
import graphql.util.NodePosition;
import graphql.util.TraversalControl;
import graphql.util.Traverser;
import graphql.util.TraverserContext;
import graphql.util.TraverserVisitor;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import static graphql.Assert.assertNotNull;
/**
* Allows for an easy way to "manipulate" the immutable Ast by changing specific nodes and getting back a new Ast
* containing the changed nodes while everything else is the same.
*/
@PublicApi
public class AstTransformer {
public Node transform(Node root, NodeVisitor nodeVisitor) {
assertNotNull(root);
assertNotNull(nodeVisitor);
AstMultiZipper astMultiZipper = new AstMultiZipper(root, Collections.emptyList());
Deque breadCrumbsStack = new ArrayDeque<>();
TraverserVisitor nodeTraverserVisitor = new TraverserVisitor() {
@Override
public TraversalControl enter(TraverserContext context) {
NodePosition generalNodePosition = context.getPosition();
if (generalNodePosition != null) {
NodeLocation location = new NodeLocation(generalNodePosition.getName(), generalNodePosition.getIndex());
breadCrumbsStack.push(new AstBreadcrumb(context.getParentContext().thisNode(), location));
}
List breadcrumbs = new ArrayList<>(breadCrumbsStack);
AstZipper astZipper = new AstZipper(context.thisNode(), breadcrumbs);
context.setVar(AstZipper.class, astZipper);
context.setVar(NodeTraverser.LeaveOrEnter.class, NodeTraverser.LeaveOrEnter.ENTER);
return context.thisNode().accept(context, nodeVisitor);
}
@Override
public TraversalControl leave(TraverserContext context) {
if (!breadCrumbsStack.isEmpty()) {
breadCrumbsStack.pop();
}
return TraversalControl.CONTINUE;
}
};
Traverser nodeTraverser = Traverser.depthFirstWithNamedChildren(node -> node.getNamedChildren().getChildren(), null, astMultiZipper);
AstMultiZipper multiZipperResult = (AstMultiZipper) nodeTraverser.traverse(root, nodeTraverserVisitor).getAccumulatedResult();
return multiZipperResult.toRootNode();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy