Skip to content

Commit d88122f

Browse files
committed
Improve doc block reader
1 parent e53ffd4 commit d88122f

File tree

11 files changed

+189
-48
lines changed

11 files changed

+189
-48
lines changed

src/Mapping/Driver/ArrayConfigDriver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
88
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\ClassConfigLoaderInterface;
99
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\ErrorMessagePropertyConfigLoader;
10-
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\NamePropertyConfigLoader;
10+
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\AliasPropertyConfigLoader;
1111
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\PropertyConfigLoaderInterface;
1212
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\SchemaValidator;
1313
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\SkipConditionsPropertyConfigLoader;
@@ -82,7 +82,7 @@ private function createPropertyLoaders(): array
8282
{
8383
return [
8484
new TypePropertyConfigLoader(),
85-
new NamePropertyConfigLoader(),
85+
new AliasPropertyConfigLoader(),
8686
new ErrorMessagePropertyConfigLoader(),
8787
new SkipConditionsPropertyConfigLoader($this->expression),
8888
];

src/Mapping/Driver/ArrayConfigDriver/NamePropertyConfigLoader.php renamed to src/Mapping/Driver/ArrayConfigDriver/AliasPropertyConfigLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
99
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
1010

11-
final class NamePropertyConfigLoader extends PropertyConfigLoader
11+
final class AliasPropertyConfigLoader extends PropertyConfigLoader
1212
{
1313
public function load(
1414
array $config,

src/Mapping/Driver/AttributeDriver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\ClassMetadataLoaderInterface;
99
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\DiscriminatorMapClassMetadataLoader;
1010
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\ErrorMessagePropertyMetadataLoader;
11-
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\NamePropertyMetadataLoader;
11+
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\AliasPropertyMetadataLoader;
1212
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\NormalizeAsArrayClassMetadataLoader;
1313
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\PropertyMetadataLoaderInterface;
1414
use TypeLang\Mapper\Mapping\Driver\AttributeDriver\SkipConditionsPropertyMetadataLoader;
@@ -57,7 +57,7 @@ private function createPropertyLoaders(): array
5757
{
5858
return [
5959
new TypePropertyMetadataLoader(),
60-
new NamePropertyMetadataLoader(),
60+
new AliasPropertyMetadataLoader(),
6161
new ErrorMessagePropertyMetadataLoader(),
6262
new SkipConditionsPropertyMetadataLoader($this->expression),
6363
];

src/Mapping/Driver/AttributeDriver/NamePropertyMetadataLoader.php renamed to src/Mapping/Driver/AttributeDriver/AliasPropertyMetadataLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
1010
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
1111

12-
final class NamePropertyMetadataLoader extends PropertyMetadataLoader
12+
final class AliasPropertyMetadataLoader extends PropertyMetadataLoader
1313
{
1414
/**
1515
* @throws \Throwable

src/Mapping/Driver/DocBlockDriver.php

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
namespace TypeLang\Mapper\Mapping\Driver;
66

7-
use TypeLang\Mapper\Exception\Definition\PropertyTypeNotFoundException;
8-
use TypeLang\Mapper\Exception\Definition\TypeNotFoundException;
97
use TypeLang\Mapper\Exception\Environment\ComposerPackageRequiredException;
8+
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\ClassConfigLoaderInterface;
9+
use TypeLang\Mapper\Mapping\Driver\ArrayConfigDriver\PropertyConfigLoaderInterface;
10+
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver\ClassDocBlockLoaderInterface;
1011
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver\ClassPropertyTypeDriver;
1112
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver\PromotedPropertyTypeDriver;
13+
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver\PropertyDocBlockLoaderInterface;
14+
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver\TypePropertyDocBlockLoader;
1215
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
13-
use TypeLang\Mapper\Mapping\Metadata\PropertyMetadata;
14-
use TypeLang\Mapper\Mapping\Metadata\TypeMetadata;
1516
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
1617
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
17-
use TypeLang\Parser\Node\Stmt\TypeStatement;
1818
use TypeLang\PHPDoc\Parser;
1919
use TypeLang\PHPDoc\Standard\ParamTagFactory;
2020
use TypeLang\PHPDoc\Standard\VarTagFactory;
@@ -40,6 +40,16 @@ final class DocBlockDriver extends LoadableDriver
4040

4141
private readonly ClassPropertyTypeDriver $classProperties;
4242

43+
/**
44+
* @var list<ClassConfigLoaderInterface>
45+
*/
46+
private readonly array $classDocBlockLoaders;
47+
48+
/**
49+
* @var list<PropertyConfigLoaderInterface>
50+
*/
51+
private readonly array $propertyDocBlockLoaders;
52+
4353
/**
4454
* @param non-empty-string $paramTagName
4555
* @param non-empty-string $varTagName
@@ -69,9 +79,34 @@ classProperties: $this->classProperties,
6979
parser: $parser,
7080
);
7181

82+
$this->classDocBlockLoaders = $this->createClassLoaders();
83+
$this->propertyDocBlockLoaders = $this->createPropertyLoaders();
84+
7285
parent::__construct($delegate);
7386
}
7487

88+
/**
89+
* @return list<ClassDocBlockLoaderInterface>
90+
*/
91+
private function createClassLoaders(): array
92+
{
93+
return [
94+
];
95+
}
96+
97+
/**
98+
* @return list<PropertyDocBlockLoaderInterface>
99+
*/
100+
private function createPropertyLoaders(): array
101+
{
102+
return [
103+
new TypePropertyDocBlockLoader(
104+
promotedProperties: $this->promotedProperties,
105+
classProperties: $this->classProperties,
106+
),
107+
];
108+
}
109+
75110
/**
76111
* @throws ComposerPackageRequiredException
77112
*/
@@ -99,53 +134,33 @@ private static function assertKernelPackageIsInstalled(): void
99134
}
100135
}
101136

102-
/**
103-
* @param \ReflectionClass<object> $class
104-
*
105-
* @throws \ReflectionException
106-
*/
107-
private function findType(\ReflectionClass $class, PropertyMetadata $meta): ?TypeStatement
108-
{
109-
$property = $class->getProperty($meta->name);
110-
111-
if ($property->isPromoted()) {
112-
return $this->promotedProperties->findType($property, $meta);
113-
}
114-
115-
return $this->classProperties->findType($property);
116-
}
117-
118137
#[\Override]
119138
protected function load(
120139
\ReflectionClass $reflection,
121140
ClassMetadata $class,
122141
TypeRepositoryInterface $types,
123142
TypeParserInterface $parser,
124143
): void {
144+
foreach ($this->classDocBlockLoaders as $classDocBlockLoader) {
145+
$classDocBlockLoader->load(
146+
class: $reflection,
147+
metadata: $class,
148+
types: $types,
149+
parser: $parser,
150+
);
151+
}
152+
125153
foreach ($reflection->getProperties() as $property) {
126154
$metadata = $class->getPropertyOrCreate($property->getName());
127155

128-
$statement = $this->findType($reflection, $metadata);
129-
130-
if ($statement !== null) {
131-
try {
132-
$type = $types->getTypeByStatement($statement, $reflection);
133-
} catch (TypeNotFoundException $e) {
134-
throw PropertyTypeNotFoundException::becauseTypeOfPropertyNotDefined(
135-
class: $class->name,
136-
property: $metadata->name,
137-
type: $e->getType(),
138-
previous: $e,
139-
);
140-
}
141-
142-
$metadata->type = new TypeMetadata(
143-
type: $type,
144-
statement: $statement,
156+
foreach ($this->propertyDocBlockLoaders as $propertyDocBlockLoader) {
157+
$propertyDocBlockLoader->load(
158+
property: $property,
159+
metadata: $metadata,
160+
types: $types,
161+
parser: $parser,
145162
);
146163
}
147-
148-
$class->addProperty($metadata);
149164
}
150165

151166
$this->promotedProperties->cleanup();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
6+
7+
abstract class ClassDocBlockLoader implements ClassDocBlockLoaderInterface {}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
6+
7+
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
8+
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
9+
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
10+
11+
interface ClassDocBlockLoaderInterface
12+
{
13+
/**
14+
* @template T of object
15+
*
16+
* @param \ReflectionClass<T> $class
17+
* @param ClassMetadata<T> $metadata
18+
*/
19+
public function load(
20+
\ReflectionClass $class,
21+
ClassMetadata $metadata,
22+
TypeRepositoryInterface $types,
23+
TypeParserInterface $parser,
24+
): void;
25+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
6+
7+
abstract class PropertyDocBlockLoader implements PropertyDocBlockLoaderInterface {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
6+
7+
use TypeLang\Mapper\Mapping\Metadata\PropertyMetadata;
8+
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
9+
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
10+
11+
interface PropertyDocBlockLoaderInterface
12+
{
13+
public function load(
14+
\ReflectionProperty $property,
15+
PropertyMetadata $metadata,
16+
TypeRepositoryInterface $types,
17+
TypeParserInterface $parser,
18+
): void;
19+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
6+
7+
use TypeLang\Mapper\Exception\Definition\PropertyTypeNotFoundException;
8+
use TypeLang\Mapper\Exception\Definition\TypeNotFoundException;
9+
use TypeLang\Mapper\Mapping\Metadata\PropertyMetadata;
10+
use TypeLang\Mapper\Mapping\Metadata\TypeMetadata;
11+
use TypeLang\Mapper\Runtime\Parser\TypeParserInterface;
12+
use TypeLang\Mapper\Runtime\Repository\TypeRepositoryInterface;
13+
use TypeLang\Parser\Node\Stmt\TypeStatement;
14+
15+
final class TypePropertyDocBlockLoader extends PropertyDocBlockLoader
16+
{
17+
public function __construct(
18+
private readonly PromotedPropertyTypeDriver $promotedProperties,
19+
private readonly ClassPropertyTypeDriver $classProperties,
20+
) {}
21+
22+
public function load(
23+
\ReflectionProperty $property,
24+
PropertyMetadata $metadata,
25+
TypeRepositoryInterface $types,
26+
TypeParserInterface $parser,
27+
): void {
28+
$reflection = $property->getDeclaringClass();
29+
30+
$statement = $this->findType($reflection, $metadata);
31+
32+
if ($statement === null) {
33+
return;
34+
}
35+
36+
try {
37+
$type = $types->getTypeByStatement($statement, $reflection);
38+
} catch (TypeNotFoundException $e) {
39+
throw PropertyTypeNotFoundException::becauseTypeOfPropertyNotDefined(
40+
class: $reflection->name,
41+
property: $metadata->name,
42+
type: $e->getType(),
43+
previous: $e,
44+
);
45+
}
46+
47+
$metadata->type = new TypeMetadata(
48+
type: $type,
49+
statement: $statement,
50+
);
51+
}
52+
53+
/**
54+
* @param \ReflectionClass<object> $class
55+
*
56+
* @throws \ReflectionException
57+
*/
58+
private function findType(\ReflectionClass $class, PropertyMetadata $meta): ?TypeStatement
59+
{
60+
$property = $class->getProperty($meta->name);
61+
62+
if ($property->isPromoted()) {
63+
return $this->promotedProperties->findType($property, $meta);
64+
}
65+
66+
return $this->classProperties->findType($property);
67+
}
68+
}

0 commit comments

Comments
 (0)