Skip to content

Commit f7e4b43

Browse files
[3.4] Fix support for PHP8 union types
1 parent b30f4c1 commit f7e4b43

File tree

7 files changed

+56
-42
lines changed

7 files changed

+56
-42
lines changed

src/Symfony/Component/Config/Resource/ReflectionClassResource.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ private function generateSignature(\ReflectionClass $class)
177177
if (!$parametersWithUndefinedConstants) {
178178
yield preg_replace('/^ @@.*/m', '', $m);
179179
} else {
180+
$t = \PHP_VERSION_ID >= 70000 ? $m->getReturnType() : '';
180181
$stack = [
181182
$m->getDocComment(),
182183
$m->getName(),
@@ -187,15 +188,16 @@ private function generateSignature(\ReflectionClass $class)
187188
$m->isPrivate(),
188189
$m->isProtected(),
189190
$m->returnsReference(),
190-
\PHP_VERSION_ID >= 70000 && $m->hasReturnType() ? (\PHP_VERSION_ID >= 70100 ? $m->getReturnType()->getName() : (string) $m->getReturnType()) : '',
191+
$t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t,
191192
];
192193

193194
foreach ($m->getParameters() as $p) {
194195
if (!isset($parametersWithUndefinedConstants[$p->name])) {
195196
$stack[] = (string) $p;
196197
} else {
198+
$t = \PHP_VERSION_ID >= 70000 ? $p->getType() : '';
197199
$stack[] = $p->isOptional();
198-
$stack[] = \PHP_VERSION_ID >= 70000 && $p->hasType() ? (\PHP_VERSION_ID >= 70100 ? $p->getType()->getName() : (string) $p->getType()) : '';
200+
$stack[] = $t instanceof \ReflectionNamedType ? $t->getName() : (string) $t;
199201
$stack[] = $p->isPassedByReference();
200202
$stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : '';
201203
$stack[] = $p->getName();

src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,33 @@ public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionPa
3939
if (!$type) {
4040
return null;
4141
}
42-
if (!\is_string($type)) {
43-
$name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString();
4442

45-
if ($type->isBuiltin()) {
46-
return $noBuiltin ? null : $name;
43+
$types = [];
44+
45+
foreach ($type instanceof \ReflectionUnionType ? $type->getTypes() : [$type] as $type) {
46+
$name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
47+
48+
if ($noBuiltin && $type->isBuiltin()) {
49+
continue;
4750
}
48-
}
49-
$lcName = strtolower($name);
50-
$prefix = $noBuiltin ? '' : '\\';
5151

52-
if ('self' !== $lcName && 'parent' !== $lcName) {
53-
return $prefix.$name;
54-
}
55-
if (!$r instanceof \ReflectionMethod) {
56-
return null;
57-
}
58-
if ('self' === $lcName) {
59-
return $prefix.$r->getDeclaringClass()->name;
52+
$lcName = strtolower($name);
53+
$prefix = $noBuiltin ? '' : '\\';
54+
55+
if ('self' !== $lcName && 'parent' !== $lcName) {
56+
$types[] = '' !== $prefix ? $prefix.$name : $name;
57+
continue;
58+
}
59+
if (!$r instanceof \ReflectionMethod) {
60+
continue;
61+
}
62+
if ('self' === $lcName) {
63+
$types[] = $prefix.$r->getDeclaringClass()->name;
64+
} else {
65+
$types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null;
66+
}
6067
}
6168

62-
return ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null;
69+
return $types ? implode('|', $types) : null;
6370
}
6471
}

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ private function getParameterClassName(\ReflectionParameter $parameter)
10761076
return ($class = $parameter->getClass()) ? $class->name : null;
10771077
}
10781078

1079-
if (!($type = $parameter->getType()) || $type->isBuiltin()) {
1079+
if (!($type = $parameter->getType()) instanceof \ReflectionNamedType || $type->isBuiltin()) {
10801080
return null;
10811081
}
10821082

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,9 @@ private function readProperty($zval, $property)
519519
// handle uninitialized properties in PHP >= 7.4
520520
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
521521
$r = new \ReflectionProperty($matches[1], $matches[2]);
522+
$type = ($type = $r->getType()) instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
522523

523-
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e);
524+
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getName()), 0, $e);
524525
}
525526

526527
throw $e;

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

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -192,21 +192,21 @@ private function extractFromMutator($class, $property)
192192
}
193193
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $reflectionParameter, $info)) {
194194
if (Type::BUILTIN_TYPE_ARRAY === $info[1]) {
195-
$type = new Type(Type::BUILTIN_TYPE_ARRAY, $reflectionParameter->allowsNull(), null, true);
195+
$type = [new Type(Type::BUILTIN_TYPE_ARRAY, $reflectionParameter->allowsNull(), null, true)];
196196
} elseif (Type::BUILTIN_TYPE_CALLABLE === $info[1]) {
197-
$type = new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull());
197+
$type = [new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull())];
198198
} else {
199-
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod));
199+
$type = [new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod))];
200200
}
201201
} else {
202202
return null;
203203
}
204204

205-
if (\in_array($prefix, $this->arrayMutatorPrefixes)) {
206-
$type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type);
205+
if (1 === \count($type) && \in_array($prefix, $this->arrayMutatorPrefixes)) {
206+
$type = [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type[0])];
207207
}
208208

209-
return [$type];
209+
return $type;
210210
}
211211

212212
/**
@@ -225,7 +225,7 @@ private function extractFromAccessor($class, $property)
225225
}
226226

227227
if ($this->supportsParameterType && $reflectionType = $reflectionMethod->getReturnType()) {
228-
return [$this->extractFromReflectionType($reflectionType, $reflectionMethod)];
228+
return $this->extractFromReflectionType($reflectionType, $reflectionMethod);
229229
}
230230

231231
return \in_array($prefix, ['is', 'can']) ? [new Type(Type::BUILTIN_TYPE_BOOL)] : null;
@@ -234,24 +234,28 @@ private function extractFromAccessor($class, $property)
234234
/**
235235
* Extracts data from the PHP 7 reflection type.
236236
*
237-
* @return Type
237+
* @return Type[]
238238
*/
239239
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod)
240240
{
241-
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : $reflectionType->__toString();
241+
$types = [];
242242
$nullable = $reflectionType->allowsNull();
243243

244-
if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
245-
$type = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
246-
} elseif ('void' === $phpTypeOrClass) {
247-
$type = new Type(Type::BUILTIN_TYPE_NULL, $nullable);
248-
} elseif ($reflectionType->isBuiltin()) {
249-
$type = new Type($phpTypeOrClass, $nullable);
250-
} else {
251-
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));
244+
foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) {
245+
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type;
246+
247+
if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
248+
$types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
249+
} elseif ('void' === $phpTypeOrClass || 'null' === $phpTypeOrClass) {
250+
$types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable);
251+
} elseif ($reflectionType->isBuiltin()) {
252+
$types[] = new Type($phpTypeOrClass, $nullable);
253+
} else {
254+
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));
255+
}
252256
}
253257

254-
return $type;
258+
return $types;
255259
}
256260

257261
private function resolveTypeName($name, \ReflectionMethod $reflectionMethod)

src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara
388388
try {
389389
if (\PHP_VERSION_ID < 70100 && null !== $parameterClass = $parameter->getClass()) {
390390
$parameterClass = $parameterClass->name;
391-
} elseif (\PHP_VERSION_ID >= 70100 && ($parameterType = $parameter->getType()) && !$parameterType->isBuiltin()) {
391+
} elseif (\PHP_VERSION_ID >= 70100 && ($parameterType = $parameter->getType()) instanceof \ReflectionNamedType && !$parameterType->isBuiltin()) {
392392
$parameterClass = $parameterType->getName();
393393
new \ReflectionClass($parameterClass); // throws a \ReflectionException if the class doesn't exist
394394
} else {

src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNes
9191
$prefix = Caster::PREFIX_VIRTUAL;
9292

9393
$a += [
94-
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : $c->__toString(),
94+
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
9595
$prefix.'allowsNull' => $c->allowsNull(),
9696
$prefix.'isBuiltin' => $c->isBuiltin(),
9797
];
@@ -178,7 +178,7 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
178178

179179
if (isset($a[$prefix.'returnType'])) {
180180
$v = $a[$prefix.'returnType'];
181-
$v = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString();
181+
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
182182
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
183183
}
184184
if (isset($a[$prefix.'class'])) {
@@ -247,7 +247,7 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st
247247

248248
if (method_exists($c, 'getType')) {
249249
if ($v = $c->getType()) {
250-
$a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString();
250+
$a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
251251
}
252252
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $c, $v)) {
253253
$a[$prefix.'typeHint'] = $v[1];

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy