11
11
use GraphQL \Language \AST \OperationDefinitionNode ;
12
12
use GraphQL \Type \Definition \AbstractType ;
13
13
use GraphQL \Type \Definition \FieldDefinition ;
14
+ use GraphQL \Type \Definition \NamedType ;
14
15
use GraphQL \Type \Definition \ObjectType ;
15
16
use GraphQL \Type \Definition \ResolveInfo ;
16
17
use GraphQL \Type \Definition \Type ;
25
26
final class Execution
26
27
{
27
28
/**
28
- * @var \WeakMap<ObjectType >
29
+ * @var \WeakMap<NamedType&Type >
29
30
*/
30
- private \WeakMap $ hijackedResolvers ;
31
+ private \WeakMap $ preparedTypes ;
31
32
32
33
/**
33
34
* @var \WeakMap<OperationDefinitionNode>
@@ -38,7 +39,7 @@ private function __construct(
38
39
private readonly DelegatorInterface $ delegator ,
39
40
private readonly ?ErrorsReporterInterface $ errorsReporter
40
41
) {
41
- $ this ->hijackedResolvers = new \WeakMap ();
42
+ $ this ->preparedTypes = new \WeakMap ();
42
43
$ this ->delegatedPromises = new \WeakMap ();
43
44
}
44
45
@@ -56,26 +57,10 @@ public static function delegate(
56
57
continue ;
57
58
}
58
59
59
- $ execution ->hijackResolver ($ operationType );
60
+ $ execution ->prepareType ($ operationType );
60
61
}
61
62
}
62
63
63
- private function hijackResolver (ObjectType $ type ): void
64
- {
65
- if (isset ($ this ->hijackedResolvers [$ type ])) {
66
- return ;
67
- }
68
-
69
- foreach ($ type ->getFields () as $ fieldDef ) {
70
- /** @var FieldDefinition $fieldDef */
71
- $ fieldDef ->resolveFn = $ this ->resolve (...);
72
- }
73
-
74
- $ type ->resolveFieldFn = null ;
75
-
76
- $ this ->hijackedResolvers [$ type ] = true ;
77
- }
78
-
79
64
private function resolve (mixed $ value , array $ args , mixed $ context , ResolveInfo $ info ): Promise
80
65
{
81
66
$ promise = $ this ->delegatedPromises [$ info ->operation ] ??= $ this ->delegateToExecute (
@@ -87,7 +72,7 @@ private function resolve(mixed $value, array $args, mixed $context, ResolveInfo
87
72
88
73
return $ promise ->then (
89
74
function (ExecutionResult $ result ) use ($ info ): mixed {
90
- $ this ->prepareReturnType ($ info ->returnType );
75
+ $ this ->prepareType ($ info ->returnType );
91
76
92
77
return $ this ->accessResultByPath ($ info ->path , $ result );
93
78
}
@@ -135,19 +120,30 @@ function (ExecutionResult $result): ExecutionResult {
135
120
);
136
121
}
137
122
138
- private function prepareReturnType (Type $ type ): void
123
+ private function prepareType (Type $ type ): void
139
124
{
140
125
if ($ type instanceof WrappingType) {
141
126
$ type = $ type ->getInnermostType ();
142
127
}
143
128
129
+ if (isset ($ this ->preparedTypes [$ type ])) {
130
+ return ;
131
+ }
132
+
144
133
if ($ type instanceof ObjectType) {
145
- $ this ->hijackResolver ($ type );
134
+ foreach ($ type ->getFields () as $ fieldDef ) {
135
+ /** @var FieldDefinition $fieldDef */
136
+ $ fieldDef ->resolveFn = $ this ->resolve (...);
137
+ }
138
+
139
+ $ type ->resolveFieldFn = null ;
146
140
}
147
141
148
142
if ($ type instanceof AbstractType) {
149
143
$ type ->config ['resolveType ' ] = $ this ->resolveAbstractType (...);
150
144
}
145
+
146
+ $ this ->preparedTypes [$ type ] = true ;
151
147
}
152
148
153
149
private function resolveAbstractType (array $ value , mixed $ context , ResolveInfo $ info ): Type
@@ -172,7 +168,7 @@ private function resolveAbstractType(array $value, mixed $context, ResolveInfo $
172
168
173
169
assert ($ implType instanceof ObjectType);
174
170
175
- $ this ->hijackResolver ($ implType );
171
+ $ this ->prepareType ($ implType );
176
172
177
173
return $ implType ;
178
174
}
0 commit comments