18
18
from ..utilities .type_from_ast import type_from_ast
19
19
from .values import get_directive_values
20
20
21
- __all__ = ["collect_fields" ]
21
+ __all__ = ["collect_fields" , "collect_sub_fields" ]
22
22
23
23
24
24
def collect_fields (
@@ -27,20 +27,68 @@ def collect_fields(
27
27
variable_values : Dict [str , Any ],
28
28
runtime_type : GraphQLObjectType ,
29
29
selection_set : SelectionSetNode ,
30
- fields : Dict [str , List [FieldNode ]],
31
- visited_fragment_names : Set [str ],
32
30
) -> Dict [str , List [FieldNode ]]:
33
31
"""Collect fields.
34
32
35
- Given a selection_set, adds all of the fields in that selection to the passed in
36
- map of fields, and returns it at the end.
33
+ Given a selection_set, collects all of the fields returns them at the end.
37
34
38
- collect_fields requires the "runtime type" of an object. For a field which
35
+ collect_fields requires the "runtime type" of an object. For a field that
39
36
returns an Interface or Union type, the "runtime type" will be the actual
40
- Object type returned by that field.
37
+ object type returned by that field.
41
38
42
39
For internal use only.
43
40
"""
41
+ fields : Dict [str , List [FieldNode ]] = {}
42
+ collect_fields_impl (
43
+ schema , fragments , variable_values , runtime_type , selection_set , fields , set ()
44
+ )
45
+ return fields
46
+
47
+
48
+ def collect_sub_fields (
49
+ schema : GraphQLSchema ,
50
+ fragments : Dict [str , FragmentDefinitionNode ],
51
+ variable_values : Dict [str , Any ],
52
+ return_type : GraphQLObjectType ,
53
+ field_nodes : List [FieldNode ],
54
+ ) -> Dict [str , List [FieldNode ]]:
55
+ """Collect sub fields.
56
+
57
+ Given a list of field nodes, collects all of the subfields of the passed
58
+ in fields, and returns them at the end.
59
+
60
+ collect_sub_fields requires the "return type" of an object. For a field that
61
+ returns an Interface or Union type, the "return type" will be the actual
62
+ object type returned by that field.
63
+
64
+ For internal use only.
65
+ """
66
+ sub_field_nodes : Dict [str , List [FieldNode ]] = {}
67
+ visited_fragment_names : Set [str ] = set ()
68
+ for node in field_nodes :
69
+ if node .selection_set :
70
+ collect_fields_impl (
71
+ schema ,
72
+ fragments ,
73
+ variable_values ,
74
+ return_type ,
75
+ node .selection_set ,
76
+ sub_field_nodes ,
77
+ visited_fragment_names ,
78
+ )
79
+ return sub_field_nodes
80
+
81
+
82
+ def collect_fields_impl (
83
+ schema : GraphQLSchema ,
84
+ fragments : Dict [str , FragmentDefinitionNode ],
85
+ variable_values : Dict [str , Any ],
86
+ runtime_type : GraphQLObjectType ,
87
+ selection_set : SelectionSetNode ,
88
+ fields : Dict [str , List [FieldNode ]],
89
+ visited_fragment_names : Set [str ],
90
+ ) -> None :
91
+ """Collect fields (internal implementation)."""
44
92
for selection in selection_set .selections :
45
93
if isinstance (selection , FieldNode ):
46
94
if not should_include_node (variable_values , selection ):
@@ -52,7 +100,7 @@ def collect_fields(
52
100
variable_values , selection
53
101
) or not does_fragment_condition_match (schema , selection , runtime_type ):
54
102
continue
55
- collect_fields (
103
+ collect_fields_impl (
56
104
schema ,
57
105
fragments ,
58
106
variable_values ,
@@ -73,7 +121,7 @@ def collect_fields(
73
121
schema , fragment , runtime_type
74
122
):
75
123
continue
76
- collect_fields (
124
+ collect_fields_impl (
77
125
schema ,
78
126
fragments ,
79
127
variable_values ,
@@ -82,7 +130,6 @@ def collect_fields(
82
130
fields ,
83
131
visited_fragment_names ,
84
132
)
85
- return fields
86
133
87
134
88
135
def should_include_node (
0 commit comments