1- package graphql .visitor ;
1+ package graphql .analysis ;
22
3+ import graphql .Internal ;
34import graphql .execution .ConditionalNodes ;
4- import graphql .language .Document ;
55import graphql .language .Field ;
66import graphql .language .FragmentDefinition ;
77import graphql .language .FragmentSpread ;
1818import java .util .LinkedHashMap ;
1919import java .util .Map ;
2020
21+ @ Internal
2122public class QueryTraversal {
2223
2324
24- private Document document ;
2525 private OperationDefinition operationDefinition ;
2626 private GraphQLSchema schema ;
2727 private Map <String , FragmentDefinition > fragmentsByName = new LinkedHashMap <>();
2828 private Map <String , Object > variables ;
2929
3030 private ConditionalNodes conditionalNodes = new ConditionalNodes ();
3131
32- private QueryVisitor visitor ;
3332
34- public QueryTraversal (Document document ,
35- OperationDefinition operationDefinition ,
33+ public QueryTraversal (OperationDefinition operationDefinition ,
3634 GraphQLSchema schema ,
3735 Map <String , FragmentDefinition > fragmentsByName ,
38- Map <String , Object > variables ,
39- QueryVisitor visitor ) {
40- this .document = document ;
36+ Map <String , Object > variables ) {
4137 this .operationDefinition = operationDefinition ;
4238 this .schema = schema ;
4339 this .fragmentsByName = fragmentsByName ;
4440 this .variables = variables ;
45- this .visitor = visitor ;
4641 }
4742
48- public void traverse () {
49- visit (operationDefinition .getSelectionSet (), schema .getQueryType (), null );
43+ public void visit (QueryVisitor visitor ) {
44+ visitImpl (visitor , operationDefinition .getSelectionSet (), schema .getQueryType (), null );
45+ }
46+
47+ public Object reduce (QueryReducer queryReducer , Object initialValue ) {
48+ // compiler hack to make acc final and mutable :-)
49+ final Object [] acc = {initialValue };
50+ visit ((env ) -> acc [0 ] = queryReducer .reduceField (env , acc [0 ]));
51+ return acc [0 ];
5052 }
5153
5254
53- private void visit ( SelectionSet selectionSet , GraphQLCompositeType type , VisitPath path ) {
55+ private void visitImpl ( QueryVisitor visitor , SelectionSet selectionSet , GraphQLCompositeType type , VisitPath path ) {
5456
5557 for (Selection selection : selectionSet .getSelections ()) {
5658 if (selection instanceof Field ) {
5759 GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer ) type ;
5860 GraphQLFieldDefinition fieldDefinition = fieldsContainer .getFieldDefinition (((Field ) selection ).getName ());
59- visitField ((Field ) selection , fieldDefinition , type , path );
61+ visitField (visitor , (Field ) selection , fieldDefinition , type , path );
6062 } else if (selection instanceof InlineFragment ) {
61- visitInlineFragment ((InlineFragment ) selection , type , path );
63+ visitInlineFragment (visitor , (InlineFragment ) selection , type , path );
6264 } else if (selection instanceof FragmentSpread ) {
63- visitFragmentSpread ((FragmentSpread ) selection , path );
65+ visitFragmentSpread (visitor , (FragmentSpread ) selection , path );
6466 }
6567 }
6668 }
6769
68- private void visitFragmentSpread (FragmentSpread fragmentSpread , VisitPath path ) {
70+ private void visitFragmentSpread (QueryVisitor visitor , FragmentSpread fragmentSpread , VisitPath path ) {
6971 if (!conditionalNodes .shouldInclude (this .variables , fragmentSpread .getDirectives ())) {
7072 return ;
7173 }
@@ -75,11 +77,11 @@ private void visitFragmentSpread(FragmentSpread fragmentSpread, VisitPath path)
7577 return ;
7678 }
7779 GraphQLCompositeType typeCondition = (GraphQLCompositeType ) schema .getType (fragmentDefinition .getTypeCondition ().getName ());
78- visit ( fragmentDefinition .getSelectionSet (), typeCondition , path );
80+ visitImpl ( visitor , fragmentDefinition .getSelectionSet (), typeCondition , path );
7981 }
8082
8183
82- private void visitInlineFragment (InlineFragment inlineFragment , GraphQLCompositeType parentType , VisitPath path ) {
84+ private void visitInlineFragment (QueryVisitor visitor , InlineFragment inlineFragment , GraphQLCompositeType parentType , VisitPath path ) {
8385 if (!conditionalNodes .shouldInclude (variables , inlineFragment .getDirectives ())) {
8486 return ;
8587 }
@@ -92,17 +94,17 @@ private void visitInlineFragment(InlineFragment inlineFragment, GraphQLComposite
9294 fragmentCondition = parentType ;
9395 }
9496 // for unions we only have other fragments inside
95- visit ( inlineFragment .getSelectionSet (), fragmentCondition , path );
97+ visitImpl ( visitor , inlineFragment .getSelectionSet (), fragmentCondition , path );
9698 }
9799
98- private void visitField (Field field , GraphQLFieldDefinition fieldDefinition , GraphQLCompositeType parentType , VisitPath parentPath ) {
100+ private void visitField (QueryVisitor visitor , Field field , GraphQLFieldDefinition fieldDefinition , GraphQLCompositeType parentType , VisitPath parentPath ) {
99101 if (!conditionalNodes .shouldInclude (variables , field .getDirectives ())) {
100102 return ;
101103 }
102- visitor .visitField (field , fieldDefinition , parentType , parentPath );
104+ visitor .visitField (new QueryVisitorEnvironment ( field , fieldDefinition , parentType , parentPath ) );
103105 if (fieldDefinition .getType () instanceof GraphQLCompositeType ) {
104106 VisitPath newPath = new VisitPath (field , fieldDefinition , parentType , parentPath );
105- visit ( field .getSelectionSet (), (GraphQLCompositeType ) fieldDefinition .getType (), newPath );
107+ visitImpl ( visitor , field .getSelectionSet (), (GraphQLCompositeType ) fieldDefinition .getType (), newPath );
106108 }
107109 }
108110
0 commit comments