11from collections import defaultdict
2- from typing import Dict , List , Set
2+ from typing import DefaultDict , Dict , List , Set
33
44from ..language import (
55 DocumentNode ,
6- ExecutableDefinitionNode ,
76 FragmentDefinitionNode ,
87 OperationDefinitionNode ,
98 Visitor ,
1312__all__ = ["separate_operations" ]
1413
1514
16- DepGraph = Dict [str , Set [str ]]
15+ DepGraph = DefaultDict [str , Set [str ]]
1716
1817
1918def separate_operations (document_ast : DocumentNode ) -> Dict [str , DocumentNode ]:
@@ -23,13 +22,10 @@ def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
2322 fragments and returns a collection of AST documents each of which contains a single
2423 operation as well the fragment definitions it refers to.
2524 """
26-
2725 # Populate metadata and build a dependency graph.
2826 visitor = SeparateOperations ()
2927 visit (document_ast , visitor )
3028 operations = visitor .operations
31- fragments = visitor .fragments
32- positions = visitor .positions
3329 dep_graph = visitor .dep_graph
3430
3531 # For each operation, produce a new synthesized AST which includes only what is
@@ -40,44 +36,42 @@ def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
4036 dependencies : Set [str ] = set ()
4137 collect_transitive_dependencies (dependencies , dep_graph , operation_name )
4238
43- # The list of definition nodes to be included for this operation, sorted to
44- # retain the same order as the original document.
45- definitions : List [ExecutableDefinitionNode ] = [operation ]
46- for name in dependencies :
47- definitions .append (fragments [name ])
48- definitions .sort (key = lambda n : positions .get (n , 0 ))
49-
50- separated_document_asts [operation_name ] = DocumentNode (definitions = definitions )
39+ # The list of definition nodes to be included for this operation, sorted
40+ # to retain the same order as the original document.
41+ separated_document_asts [operation_name ] = DocumentNode (
42+ definitions = [
43+ node
44+ for node in document_ast .definitions
45+ if node is operation
46+ or (
47+ isinstance (node , FragmentDefinitionNode )
48+ and node .name .value in dependencies
49+ )
50+ ]
51+ )
5152
5253 return separated_document_asts
5354
5455
55- # noinspection PyAttributeOutsideInit
5656class SeparateOperations (Visitor ):
57+ operations : List [OperationDefinitionNode ]
58+ dep_graph : DepGraph
59+ from_name : str
60+
5761 def __init__ (self ):
5862 super ().__init__ ()
59- self .operations : List [OperationDefinitionNode ] = []
60- self .fragments : Dict [str , FragmentDefinitionNode ] = {}
61- self .positions : Dict [ExecutableDefinitionNode , int ] = {}
62- self .dep_graph : DepGraph = defaultdict (set )
63- self .from_name : str
64- self .idx = 0
63+ self .operations = []
64+ self .dep_graph = defaultdict (set )
6565
6666 def enter_operation_definition (self , node , * _args ):
6767 self .from_name = op_name (node )
6868 self .operations .append (node )
69- self .positions [node ] = self .idx
70- self .idx += 1
7169
7270 def enter_fragment_definition (self , node , * _args ):
7371 self .from_name = node .name .value
74- self .fragments [self .from_name ] = node
75- self .positions [node ] = self .idx
76- self .idx += 1
7772
7873 def enter_fragment_spread (self , node , * _args ):
79- to_name = node .name .value
80- self .dep_graph [self .from_name ].add (to_name )
74+ self .dep_graph [self .from_name ].add (node .name .value )
8175
8276
8377def op_name (operation : OperationDefinitionNode ) -> str :
0 commit comments