Skip to content

Commit 647fe5a

Browse files
committed
wip
1 parent 1d60a2e commit 647fe5a

21 files changed

+1179
-1172
lines changed

src/Symfony/Component/PropertyInfo/Extractor/ConstructorExtractor.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
1515
use Symfony\Component\PropertyInfo\Type;
16+
use Symfony\Component\PropertyInfo\Util\BackwardCompatibilityHelper;
1617
use Symfony\Component\TypeInfo\Type as TypeInfoType;
1718

1819
/**
@@ -30,23 +31,6 @@ public function __construct(
3031
) {
3132
}
3233

33-
public function getTypes(string $class, string $property, array $context = []): ?array
34-
{
35-
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
36-
37-
if (null === $type = $this->getType($class, $property, $context)) {
38-
return null;
39-
}
40-
41-
$type = Type::convertFromTypeInfoType($type);
42-
43-
if (!\is_array($type)) {
44-
$type = [$type];
45-
}
46-
47-
return $type;
48-
}
49-
5034
public function getType(string $class, string $property, array $context = []): ?TypeInfoType
5135
{
5236
foreach ($this->extractors as $extractor) {
@@ -58,4 +42,11 @@ public function getType(string $class, string $property, array $context = []): ?
5842

5943
return null;
6044
}
45+
46+
public function getTypes(string $class, string $property, array $context = []): ?array
47+
{
48+
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
49+
50+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getType($class, $property, $context));
51+
}
6152
}

src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use phpDocumentor\Reflection\Types\ContextFactory;
2020
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
2121
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
22-
use Symfony\Component\PropertyInfo\Type;
22+
use Symfony\Component\PropertyInfo\Util\BackwardCompatibilityHelper;
2323
use Symfony\Component\PropertyInfo\Util\PhpDocTypeHelper;
2424
use Symfony\Component\TypeInfo\Type as TypeInfoType;
2525
use Symfony\Component\TypeInfo\Type\ObjectType;
@@ -113,27 +113,6 @@ public function getLongDescription(string $class, string $property, array $conte
113113
return '' === $contents ? null : $contents;
114114
}
115115

116-
public function getTypes(string $class, string $property, array $context = []): ?array
117-
{
118-
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
119-
120-
if (null === $type = $this->getType($class, $property, $context)) {
121-
return null;
122-
}
123-
124-
if ('mixed' === (string) $type) {
125-
return null;
126-
}
127-
128-
$type = Type::convertFromTypeInfoType($type);
129-
130-
if (!\is_array($type)) {
131-
$type = [$type];
132-
}
133-
134-
return $type;
135-
}
136-
137116
public function getType(string $class, string $property, array $context = []): ?TypeInfoType
138117
{
139118
/** @var $docBlock DocBlock */
@@ -194,25 +173,12 @@ public function getType(string $class, string $property, array $context = []): ?
194173
return TypeInfoType::list($type);
195174
}
196175

197-
public function getTypesFromConstructor(string $class, string $property): ?array
176+
public function getTypes(string $class, string $property, array $context = []): ?array
198177
{
199-
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getTypeFromConstructor()" instead.', __METHOD__, self::class);
200-
201-
if (null === $type = $this->getTypeFromConstructor($class, $property)) {
202-
return null;
203-
}
204-
205-
if ('mixed' === (string) $type) {
206-
return null;
207-
}
208-
209-
$type = Type::convertFromTypeInfoType($type);
210-
211-
if (!\is_array($type)) {
212-
$type = [$type];
213-
}
178+
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
214179

215-
return $type;
180+
dump($this->getType($class, $property, $context));
181+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getType($class, $property, $context));
216182
}
217183

218184
public function getTypeFromConstructor(string $class, string $property): ?TypeInfoType
@@ -234,6 +200,13 @@ public function getTypeFromConstructor(string $class, string $property): ?TypeIn
234200
return $types[0] ?? null;
235201
}
236202

203+
public function getTypesFromConstructor(string $class, string $property): ?array
204+
{
205+
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getTypeFromConstructor()" instead.', __METHOD__, self::class);
206+
207+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getTypeFromConstructor($class, $property));
208+
}
209+
237210
private function getDocBlockFromConstructor(string $class, string $property): ?DocBlock
238211
{
239212
try {

src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111

1212
namespace Symfony\Component\PropertyInfo\Extractor;
1313

14-
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
15-
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
16-
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;
1714
use phpDocumentor\Reflection\Types\ContextFactory;
1815
use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
1916
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
@@ -24,11 +21,14 @@
2421
use PHPStan\PhpDocParser\Parser\PhpDocParser;
2522
use PHPStan\PhpDocParser\Parser\TokenIterator;
2623
use PHPStan\PhpDocParser\Parser\TypeParser;
27-
use Symfony\Component\PropertyInfo\PhpStan\NameScopeFactory;
2824
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
2925
use Symfony\Component\PropertyInfo\Type;
30-
use Symfony\Component\PropertyInfo\Util\PhpStanTypeHelper;
26+
use Symfony\Component\PropertyInfo\Util\BackwardCompatibilityHelper;
27+
use Symfony\Component\TypeInfo\Exception\LogicException;
28+
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
3129
use Symfony\Component\TypeInfo\Type as TypeInfoType;
30+
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
31+
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;
3232

3333
/**
3434
* Extracts data using PHPStan parser.
@@ -43,14 +43,12 @@ final class PhpStanExtractor implements PropertyTypeExtractorInterface, Construc
4343

4444
private PhpDocParser $phpDocParser;
4545
private Lexer $lexer;
46-
private NameScopeFactory $nameScopeFactory;
4746

4847
private StringTypeResolver $stringTypeResolver;
4948
private TypeContextFactory $typeContextFactory;
5049

5150
/** @var array<string, array{PhpDocNode|null, int|null, string|null, string|null}> */
5251
private array $docBlocks = [];
53-
private PhpStanTypeHelper $phpStanTypeHelper;
5452
private array $mutatorPrefixes;
5553
private array $accessorPrefixes;
5654
private array $arrayMutatorPrefixes;
@@ -70,52 +68,27 @@ public function __construct(array $mutatorPrefixes = null, array $accessorPrefix
7068
throw new \LogicException(sprintf('Unable to use the "%s" class as the "phpstan/phpdoc-parser" package is not installed. Try running composer require "phpstan/phpdoc-parser".', __CLASS__));
7169
}
7270

73-
$this->phpStanTypeHelper = new PhpStanTypeHelper();
7471
$this->mutatorPrefixes = $mutatorPrefixes ?? ReflectionExtractor::$defaultMutatorPrefixes;
7572
$this->accessorPrefixes = $accessorPrefixes ?? ReflectionExtractor::$defaultAccessorPrefixes;
7673
$this->arrayMutatorPrefixes = $arrayMutatorPrefixes ?? ReflectionExtractor::$defaultArrayMutatorPrefixes;
7774

7875
$this->phpDocParser = new PhpDocParser(new TypeParser(new ConstExprParser()), new ConstExprParser());
7976
$this->lexer = new Lexer();
80-
$this->nameScopeFactory = new NameScopeFactory();
8177
$this->stringTypeResolver = new StringTypeResolver();
8278
$this->typeContextFactory = new TypeContextFactory($this->stringTypeResolver);
8379
}
8480

85-
public function getTypes(string $class, string $property, array $context = []): ?array
86-
{
87-
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
88-
89-
try {
90-
$type = $this->getType($class, $property, $context);
91-
} catch (UnsupportedException) {
92-
// workaround to handle void
93-
return [new Type(Type::BUILTIN_TYPE_NULL)];
94-
}
95-
96-
if (null === $type || 'mixed' === (string) $type) {
97-
return null;
98-
}
99-
100-
$type = Type::convertFromTypeInfoType($type);
101-
102-
if (!\is_array($type)) {
103-
$type = [$type];
104-
}
105-
106-
return $type;
107-
}
108-
10981
public function getType(string $class, string $property, array $context = []): ?TypeInfoType
11082
{
83+
$backwardCompatible = \func_get_args()[3] ?? false;
84+
11185
/** @var PhpDocNode|null $docNode */
11286
[$docNode, $source, $prefix, $declaringClass] = $this->getDocBlock($class, $property);
11387

11488
if (null === $docNode) {
11589
return null;
11690
}
11791

118-
$nameScope = $this->nameScopeFactory->create($class, $declaringClass);
11992
$typeContext = $this->typeContextFactory->createFromClassName($class, $declaringClass);
12093

12194
$tag = match ($source) {
@@ -132,15 +105,25 @@ public function getType(string $class, string $property, array $context = []): ?
132105
continue;
133106
}
134107

135-
if (
136-
$tagDocNode->value instanceof ParamTagValueNode
137-
&& null === $prefix
138-
&& $tagDocNode->value->parameterName !== '$'.$property
139-
) {
108+
if ($tagDocNode->value instanceof ParamTagValueNode && null === $prefix && $tagDocNode->value->parameterName !== '$'.$property) {
140109
continue;
141110
}
142111

143-
$types[] = $this->stringTypeResolver->resolve((string) $tagDocNode->value->type, $typeContext);
112+
try {
113+
$types[] = $this->stringTypeResolver->resolve((string) $tagDocNode->value->type, $typeContext, $backwardCompatible);
114+
} catch (UnsupportedException) {
115+
// BC layer to handle "void" type in "getTypes"
116+
if ('void' === (string) $tagDocNode->value->type && $backwardCompatible) {
117+
return TypeInfoType::template('void');
118+
}
119+
} catch (LogicException $e) {
120+
// BC layer to handle "parent" type without existing parent
121+
if ('parent' === (string) $tagDocNode->value->type && $backwardCompatible) {
122+
return TypeInfoType::object('parent');
123+
}
124+
125+
throw $e;
126+
}
144127
}
145128

146129
if (null === ($type = $types[0] ?? null)) {
@@ -154,26 +137,31 @@ public function getType(string $class, string $property, array $context = []): ?
154137
return TypeInfoType::list($type);
155138
}
156139

157-
public function getTypeFromConstructor(string $class, string $property): ?TypeInfoType
140+
public function getTypes(string $class, string $property, array $context = []): ?array
158141
{
142+
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
143+
144+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getType($class, $property, $context, true));
159145
}
160146

161-
public function getTypesFromConstructor(string $class, string $property): ?array
147+
public function getTypeFromConstructor(string $class, string $property): ?TypeInfoType
162148
{
149+
$backwardCompatible = \func_get_args()[2] ?? false;
150+
163151
if (null === $tagDocNode = $this->getDocBlockFromConstructor($class, $property)) {
164152
return null;
165153
}
166154

167-
$types = [];
168-
foreach ($this->phpStanTypeHelper->getTypes($tagDocNode, $this->nameScopeFactory->create($class)) as $type) {
169-
$types[] = $type;
170-
}
155+
$typeContext = $this->typeContextFactory->createFromClassName($class);
171156

172-
if (!isset($types[0])) {
173-
return null;
174-
}
157+
return $this->stringTypeResolver->resolve((string) $tagDocNode->type, $typeContext, $backwardCompatible);
158+
}
159+
160+
public function getTypesFromConstructor(string $class, string $property): ?array
161+
{
162+
trigger_deprecation('symfony/property-info', '7.1', 'The "%s()" method is deprecated. Use "%s::getTypeFromConstructor()" instead.', __METHOD__, self::class);
175163

176-
return $types;
164+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getTypeFromConstructor($class, $property, true));
177165
}
178166

179167
private function getDocBlockFromConstructor(string $class, string $property): ?ParamTagValueNode

0 commit comments

Comments
 (0)