Skip to content

Commit ee37736

Browse files
committed
Add building context to metadata
1 parent 7607ea1 commit ee37736

File tree

8 files changed

+73
-116
lines changed

8 files changed

+73
-116
lines changed

src/Mapping/Provider/Decorator.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44

55
namespace TypeLang\Mapper\Mapping\Provider;
66

7+
use TypeLang\Mapper\Context\BuildingContext;
78
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
89
use TypeLang\Mapper\Mapping\Reader\ReaderInterface;
9-
use TypeLang\Mapper\Type\Parser\TypeParserInterface;
10-
use TypeLang\Mapper\Type\Repository\TypeRepositoryInterface;
1110

1211
abstract class Decorator implements ProviderInterface
1312
{
@@ -33,11 +32,8 @@ private function createDefaultProvider(ReaderInterface $reader): ProviderInterfa
3332
return new MetadataBuilder($reader);
3433
}
3534

36-
public function getClassMetadata(
37-
\ReflectionClass $class,
38-
TypeRepositoryInterface $types,
39-
TypeParserInterface $parser,
40-
): ClassMetadata {
41-
return $this->delegate->getClassMetadata($class, $types, $parser);
35+
public function getClassMetadata(\ReflectionClass $class, BuildingContext $context): ClassMetadata
36+
{
37+
return $this->delegate->getClassMetadata($class, $context);
4238
}
4339
}

src/Mapping/Provider/InMemoryProvider.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44

55
namespace TypeLang\Mapper\Mapping\Provider;
66

7+
use TypeLang\Mapper\Context\BuildingContext;
78
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
8-
use TypeLang\Mapper\Type\Parser\TypeParserInterface;
9-
use TypeLang\Mapper\Type\Repository\TypeRepositoryInterface;
109

1110
final class InMemoryProvider extends Decorator
1211
{
@@ -15,13 +14,10 @@ final class InMemoryProvider extends Decorator
1514
*/
1615
private array $memory = [];
1716

18-
public function getClassMetadata(
19-
\ReflectionClass $class,
20-
TypeRepositoryInterface $types,
21-
TypeParserInterface $parser,
22-
): ClassMetadata {
17+
public function getClassMetadata(\ReflectionClass $class, BuildingContext $context): ClassMetadata
18+
{
2319
// @phpstan-ignore-next-line : class-string<T> key contains ClassMetadata<T> instance
2420
return $this->memory[$class->name]
25-
??= parent::getClassMetadata($class, $types, $parser);
21+
??= parent::getClassMetadata($class, $context);
2622
}
2723
}

src/Mapping/Provider/MetadataBuilder.php

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Psr\Clock\ClockInterface;
88
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
99
use Symfony\Component\ExpressionLanguage\ParsedExpression;
10+
use TypeLang\Mapper\Context\BuildingContext;
1011
use TypeLang\Mapper\Exception\Definition\PropertyTypeNotFoundException;
1112
use TypeLang\Mapper\Exception\Definition\TypeNotFoundException;
1213
use TypeLang\Mapper\Exception\Environment\ComposerPackageRequiredException;
@@ -35,8 +36,6 @@
3536
use TypeLang\Mapper\Mapping\Reference\Reader\NativeReferencesReader;
3637
use TypeLang\Mapper\Mapping\Reference\Reader\ReferencesReaderInterface;
3738
use TypeLang\Mapper\Mapping\Reference\ReferencesResolver;
38-
use TypeLang\Mapper\Type\Parser\TypeParserInterface;
39-
use TypeLang\Mapper\Type\Repository\TypeRepositoryInterface;
4039

4140
final class MetadataBuilder implements ProviderInterface
4241
{
@@ -71,18 +70,15 @@ private function now(): ?int
7170
* @return ClassMetadata<TArg>
7271
* @throws \Throwable
7372
*/
74-
public function getClassMetadata(
75-
\ReflectionClass $class,
76-
TypeRepositoryInterface $types,
77-
TypeParserInterface $parser,
78-
): ClassMetadata {
73+
public function getClassMetadata(\ReflectionClass $class, BuildingContext $context): ClassMetadata
74+
{
7975
if (\PHP_VERSION_ID >= 80400) {
8076
/** @var ClassMetadata<TArg> */
81-
return $this->toProxyClassMetadata($class, $types, $parser);
77+
return $this->toProxyClassMetadata($class, $context);
8278
}
8379

8480
/** @var ClassMetadata<TArg> */
85-
return $this->toLazyInitializedClassMetadata($class, $types, $parser);
81+
return $this->toLazyInitializedClassMetadata($class, $context);
8682
}
8783

8884
/**
@@ -93,32 +89,27 @@ public function getClassMetadata(
9389
* @return ClassMetadata<TArg>
9490
* @throws \Throwable
9591
*/
96-
private function toProxyClassMetadata(
97-
\ReflectionClass $class,
98-
TypeRepositoryInterface $types,
99-
TypeParserInterface $parser,
100-
): ClassMetadata {
92+
private function toProxyClassMetadata(\ReflectionClass $class, BuildingContext $context): ClassMetadata
93+
{
10194
/** @var ClassMetadata<TArg> */
10295
return $this->metadata[$class->name] ??=
10396
(new \ReflectionClass(ClassMetadata::class))
104-
->newLazyProxy(function () use ($class, $types, $parser): ClassMetadata {
97+
->newLazyProxy(function () use ($class, $context): ClassMetadata {
10598
$info = $this->reader->read($class);
10699

107100
$metadata = new ClassMetadata(
108101
name: $info->name,
109102
properties: $this->toPropertiesMetadata(
110-
context: $class,
103+
class: $class,
111104
parent: $info,
112105
properties: $info->properties,
113-
types: $types,
114-
parser: $parser,
106+
context: $context,
115107
),
116108
discriminator: $this->toOptionalDiscriminator(
117-
context: $class,
109+
class: $class,
118110
parent: $info,
119111
info: $info->discriminator,
120-
types: $types,
121-
parser: $parser,
112+
context: $context,
122113
),
123114
isNormalizeAsArray: $info->isNormalizeAsArray,
124115
typeErrorMessage: $info->typeErrorMessage,
@@ -141,8 +132,7 @@ private function toProxyClassMetadata(
141132
*/
142133
private function toLazyInitializedClassMetadata(
143134
\ReflectionClass $class,
144-
TypeRepositoryInterface $types,
145-
TypeParserInterface $parser,
135+
BuildingContext $context
146136
): ClassMetadata {
147137
if (isset($this->metadata[$class->name])) {
148138
/** @var ClassMetadata<TArg> */
@@ -160,20 +150,18 @@ private function toLazyInitializedClassMetadata(
160150

161151
/** @phpstan-ignore-next-line : Allow readonly writing */
162152
$metadata->properties = $this->toPropertiesMetadata(
163-
context: $class,
153+
class: $class,
164154
parent: $info,
165155
properties: $info->properties,
166-
types: $types,
167-
parser: $parser,
156+
context: $context,
168157
);
169158

170159
/** @phpstan-ignore-next-line : Allow readonly writing */
171160
$metadata->discriminator = $this->toOptionalDiscriminator(
172-
context: $class,
161+
class: $class,
173162
parent: $info,
174163
info: $info->discriminator,
175-
types: $types,
176-
parser: $parser,
164+
context: $context,
177165
);
178166

179167
unset($this->metadata[$class->name]);
@@ -183,50 +171,48 @@ private function toLazyInitializedClassMetadata(
183171
}
184172

185173
/**
186-
* @param \ReflectionClass<object> $context
174+
* @param \ReflectionClass<object> $class
187175
* @param ClassInfo<object> $parent
188176
* @param iterable<mixed, PropertyInfo> $properties
189177
*
190178
* @return array<non-empty-string, PropertyMetadata>
191179
* @throws \Throwable
192180
*/
193181
private function toPropertiesMetadata(
194-
\ReflectionClass $context,
182+
\ReflectionClass $class,
195183
ClassInfo $parent,
196184
iterable $properties,
197-
TypeRepositoryInterface $types,
198-
TypeParserInterface $parser,
185+
BuildingContext $context
199186
): array {
200187
$result = [];
201188

202189
foreach ($properties as $property) {
203-
$result[$property->name] = $this->toPropertyMetadata($context, $parent, $property, $types, $parser);
190+
$result[$property->name] = $this->toPropertyMetadata($class, $parent, $property, $context);
204191
}
205192

206193
return $result;
207194
}
208195

209196
/**
210-
* @param \ReflectionClass<object> $context
197+
* @param \ReflectionClass<object> $class
211198
* @param ClassInfo<object> $parent
212199
*
213200
* @throws \Throwable
214201
*/
215202
private function toPropertyMetadata(
216-
\ReflectionClass $context,
203+
\ReflectionClass $class,
217204
ClassInfo $parent,
218205
PropertyInfo $property,
219-
TypeRepositoryInterface $types,
220-
TypeParserInterface $parser,
206+
BuildingContext $context
221207
): PropertyMetadata {
222208
try {
223-
$read = $this->toTypeMetadata($context, $property->read, $types, $parser);
209+
$read = $this->toTypeMetadata($class, $property->read, $context);
224210
} catch (TypeNotFoundException $e) {
225211
throw $this->toPropertyTypeException($e, $parent, $property, $property->read);
226212
}
227213

228214
try {
229-
$write = $this->toTypeMetadata($context, $property->write, $types, $parser);
215+
$write = $this->toTypeMetadata($class, $property->write, $context);
230216
} catch (TypeNotFoundException $e) {
231217
throw $this->toPropertyTypeException($e, $parent, $property, $property->write);
232218
}
@@ -324,112 +310,109 @@ private function toDefaultValueMetadata(DefaultValueInfo $info): DefaultValueMet
324310
}
325311

326312
/**
327-
* @param \ReflectionClass<object> $context
313+
* @param \ReflectionClass<object> $class
328314
* @param ClassInfo<object> $parent
329315
*
330316
* @throws \Throwable
331317
*/
332318
private function toOptionalDiscriminator(
333-
\ReflectionClass $context,
319+
\ReflectionClass $class,
334320
ClassInfo $parent,
335321
?DiscriminatorInfo $info,
336-
TypeRepositoryInterface $types,
337-
TypeParserInterface $parser,
322+
BuildingContext $context
338323
): ?DiscriminatorMetadata {
339324
if ($info === null) {
340325
return null;
341326
}
342327

343-
return $this->toDiscriminator($context, $parent, $info, $types, $parser);
328+
return $this->toDiscriminator($class, $parent, $info, $context);
344329
}
345330

346331
/**
347-
* @param \ReflectionClass<object> $context
332+
* @param \ReflectionClass<object> $class
348333
* @param ClassInfo<object> $parent
349334
*
350335
* @throws \Throwable
351336
*/
352337
private function toDiscriminator(
353-
\ReflectionClass $context,
338+
\ReflectionClass $class,
354339
ClassInfo $parent,
355340
DiscriminatorInfo $info,
356-
TypeRepositoryInterface $types,
357-
TypeParserInterface $parser,
341+
BuildingContext $context
358342
): DiscriminatorMetadata {
359343
// TODO Customize discriminator errors
360344

361345
return new DiscriminatorMetadata(
362346
field: $info->field,
363-
map: $this->toDiscriminatorMap($context, $info->map, $types, $parser),
364-
default: $this->toOptionalTypeMetadata($context, $info->default, $types, $parser),
347+
map: $this->toDiscriminatorMap($class, $info->map, $context),
348+
default: $this->toOptionalTypeMetadata($class, $info->default, $context),
365349
createdAt: $this->now(),
366350
);
367351
}
368352

369353
/**
370-
* @param \ReflectionClass<object> $context
354+
* @param \ReflectionClass<object> $class
371355
* @param non-empty-array<non-empty-string, TypeInfo> $map
372356
*
373357
* @return non-empty-array<non-empty-string, TypeMetadata>
374358
* @throws \Throwable
375359
*/
376360
private function toDiscriminatorMap(
377-
\ReflectionClass $context,
361+
\ReflectionClass $class,
378362
array $map,
379-
TypeRepositoryInterface $types,
380-
TypeParserInterface $parser,
363+
BuildingContext $context
381364
): array {
382365
$result = [];
383366

384367
foreach ($map as $value => $type) {
385-
$result[$value] = $this->toTypeMetadata($context, $type, $types, $parser);
368+
$result[$value] = $this->toTypeMetadata($class, $type, $context);
386369
}
387370

388371
/** @var non-empty-array<non-empty-string, TypeMetadata> $result */
389372
return $result;
390373
}
391374

392375
/**
393-
* @param \ReflectionClass<object> $context
376+
* @param \ReflectionClass<object> $class
394377
*
395378
* @throws \Throwable
396379
*/
397380
private function toOptionalTypeMetadata(
398-
\ReflectionClass $context,
381+
\ReflectionClass $class,
399382
?TypeInfo $type,
400-
TypeRepositoryInterface $types,
401-
TypeParserInterface $parser,
383+
BuildingContext $context
402384
): ?TypeMetadata {
403385
if ($type === null) {
404386
return null;
405387
}
406388

407-
return $this->toTypeMetadata($context, $type, $types, $parser);
389+
return $this->toTypeMetadata($class, $type, $context);
408390
}
409391

410392
/**
411-
* @param \ReflectionClass<object> $context
393+
* @param \ReflectionClass<object> $class
412394
*
413395
* @throws \Throwable
414396
*/
415397
private function toTypeMetadata(
416-
\ReflectionClass $context,
398+
\ReflectionClass $class,
417399
TypeInfo $info,
418-
TypeRepositoryInterface $types,
419-
TypeParserInterface $parser,
400+
BuildingContext $context
420401
): TypeMetadata {
421402
$statement = match (true) {
422-
$info instanceof RawTypeInfo => $parser->getStatementByDefinition($info->definition),
403+
$info instanceof RawTypeInfo => $context->parser->getStatementByDefinition(
404+
definition: $info->definition,
405+
),
423406
$info instanceof ParsedTypeInfo => $info->statement,
424407
default => throw new \InvalidArgumentException(\sprintf(
425408
'Unsupported type info "%s"',
426409
$info::class,
427410
))
428411
};
429412

430-
$statement = $this->references->resolve($statement, $context);
413+
$statement = $this->references->resolve($statement, $class);
431414

432-
$type = $types->getTypeByStatement($statement);
415+
$type = $context->types->getTypeByStatement($statement);
433416

434417
return new TypeMetadata(
435418
type: $type,

src/Mapping/Provider/NullProvider.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@
44

55
namespace TypeLang\Mapper\Mapping\Provider;
66

7+
use TypeLang\Mapper\Context\BuildingContext;
78
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
8-
use TypeLang\Mapper\Type\Parser\TypeParserInterface;
9-
use TypeLang\Mapper\Type\Repository\TypeRepositoryInterface;
109

1110
final class NullProvider implements ProviderInterface
1211
{
13-
public function getClassMetadata(
14-
\ReflectionClass $class,
15-
TypeRepositoryInterface $types,
16-
TypeParserInterface $parser,
17-
): ClassMetadata {
12+
public function getClassMetadata(\ReflectionClass $class, BuildingContext $context): ClassMetadata
13+
{
1814
return new ClassMetadata($class->name);
1915
}
2016
}

0 commit comments

Comments
 (0)