Skip to content

Commit 3f909e3

Browse files
committed
Separate utility for extractTypes
1 parent dd4acfd commit 3f909e3

File tree

3 files changed

+403
-48
lines changed

3 files changed

+403
-48
lines changed

src/Type/EagerResolution.php

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ class EagerResolution implements Resolution
3636
*/
3737
public function __construct(array $initialTypes)
3838
{
39+
$typeMap = [];
3940
foreach ($initialTypes as $type) {
40-
$this->extractTypes($type);
41+
$typeMap = Utils\TypeInfo::extractTypes($type, $typeMap);
4142
}
42-
$this->typeMap += Type::getInternalTypes();
43+
$this->typeMap = $typeMap + Type::getInternalTypes();
4344

4445
// Keep track of all possible types for abstract types
4546
foreach ($this->typeMap as $typeName => $type) {
@@ -112,50 +113,4 @@ public function getDescriptor()
112113
'possibleTypeMap' => $possibleTypesMap
113114
];
114115
}
115-
116-
/**
117-
* @param $type
118-
* @return array
119-
*/
120-
private function extractTypes($type)
121-
{
122-
if (!$type) {
123-
return $this->typeMap;
124-
}
125-
126-
if ($type instanceof WrappingType) {
127-
return $this->extractTypes($type->getWrappedType(true));
128-
}
129-
130-
if (!empty($this->typeMap[$type->name])) {
131-
Utils::invariant(
132-
$this->typeMap[$type->name] === $type,
133-
"Schema must contain unique named types but contains multiple types named \"$type\"."
134-
);
135-
return $this->typeMap;
136-
}
137-
$this->typeMap[$type->name] = $type;
138-
139-
$nestedTypes = [];
140-
141-
if ($type instanceof UnionType) {
142-
$nestedTypes = $type->getTypes();
143-
}
144-
if ($type instanceof ObjectType) {
145-
$nestedTypes = array_merge($nestedTypes, $type->getInterfaces());
146-
}
147-
if ($type instanceof ObjectType || $type instanceof InterfaceType || $type instanceof InputObjectType) {
148-
foreach ((array) $type->getFields() as $fieldName => $field) {
149-
if (isset($field->args)) {
150-
$fieldArgTypes = array_map(function(FieldArgument $arg) { return $arg->getType(); }, $field->args);
151-
$nestedTypes = array_merge($nestedTypes, $fieldArgTypes);
152-
}
153-
$nestedTypes[] = $field->getType();
154-
}
155-
}
156-
foreach ($nestedTypes as $type) {
157-
$this->extractTypes($type);
158-
}
159-
return $this->typeMap;
160-
}
161116
}

src/Utils/TypeInfo.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use GraphQL\Type\Definition\NonNull;
2121
use GraphQL\Type\Definition\ObjectType;
2222
use GraphQL\Type\Definition\Type;
23+
use GraphQL\Type\Definition\UnionType;
24+
use GraphQL\Type\Definition\WrappingType;
2325
use GraphQL\Type\Introspection;
2426
use GraphQL\Utils;
2527

@@ -162,6 +164,66 @@ public static function typeFromAST(Schema $schema, $inputTypeNode)
162164
return $schema->getType($inputTypeNode->name->value);
163165
}
164166

167+
/**
168+
* Given root type scans through all fields to find nested types. Returns array where keys are for type name
169+
* and value contains corresponding type instance.
170+
*
171+
* Example output:
172+
* [
173+
* 'String' => $instanceOfStringType,
174+
* 'MyType' => $instanceOfMyType,
175+
* ...
176+
* ]
177+
*
178+
* @param Type $type
179+
* @param array|null $typeMap
180+
* @return array
181+
*/
182+
public static function extractTypes($type, array $typeMap = null)
183+
{
184+
if (!$typeMap) {
185+
$typeMap = [];
186+
}
187+
if (!$type) {
188+
return $typeMap;
189+
}
190+
191+
if ($type instanceof WrappingType) {
192+
return self::extractTypes($type->getWrappedType(true), $typeMap);
193+
}
194+
195+
if (!empty($typeMap[$type->name])) {
196+
Utils::invariant(
197+
$typeMap[$type->name] === $type,
198+
"Schema must contain unique named types but contains multiple types named \"$type\"."
199+
);
200+
return $typeMap;
201+
}
202+
$typeMap[$type->name] = $type;
203+
204+
$nestedTypes = [];
205+
206+
if ($type instanceof UnionType) {
207+
$nestedTypes = $type->getTypes();
208+
}
209+
if ($type instanceof ObjectType) {
210+
$nestedTypes = array_merge($nestedTypes, $type->getInterfaces());
211+
}
212+
if ($type instanceof ObjectType || $type instanceof InterfaceType || $type instanceof InputObjectType) {
213+
foreach ((array) $type->getFields() as $fieldName => $field) {
214+
if (isset($field->args)) {
215+
$fieldArgTypes = array_map(function(FieldArgument $arg) { return $arg->getType(); }, $field->args);
216+
$nestedTypes = array_merge($nestedTypes, $fieldArgTypes);
217+
}
218+
$nestedTypes[] = $field->getType();
219+
}
220+
}
221+
foreach ($nestedTypes as $type) {
222+
$typeMap = self::extractTypes($type, $typeMap);
223+
}
224+
return $typeMap;
225+
}
226+
165227
/**
166228
* Not exactly the same as the executor's definition of getFieldDef, in this
167229
* statically evaluated environment we do not always have an Object type,

0 commit comments

Comments
 (0)