Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit da68e66

Browse files
Fix support for PHP8 union types
1 parent 7eca3a5 commit da68e66

File tree

10 files changed

+61
-21
lines changed

10 files changed

+61
-21
lines changed

src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,26 @@ private function checkTypeDeclarations(Definition $checkedDefinition, \Reflectio
153153
/**
154154
* @throws InvalidParameterTypeException When a parameter is not compatible with the declared type
155155
*/
156-
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix): void
156+
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, string $type = null): void
157157
{
158-
$type = $parameter->getType()->getName();
158+
if (null === $type) {
159+
$type = $parameter->getType();
160+
161+
if ($type instanceof \ReflectionUnionType) {
162+
foreach ($type->getTypes() as $type) {
163+
try {
164+
$this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $type);
165+
166+
return;
167+
} catch (InvalidParameterTypeException $e) {
168+
}
169+
}
170+
171+
throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter);
172+
}
173+
174+
$type = $type->getName();
175+
}
159176

160177
if ($value instanceof Reference) {
161178
if (!$this->container->has($value = (string) $value)) {
@@ -266,7 +283,7 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
266283
return;
267284
}
268285

269-
$checkFunction = sprintf('is_%s', $parameter->getType()->getName());
286+
$checkFunction = sprintf('is_%s', $type);
270287

271288
if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) {
272289
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : \gettype($value), $parameter);

src/Symfony/Component/DependencyInjection/Dumper/Preloader.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static function preload(array $classes)
4848
}
4949
}
5050

51-
private static function doPreload(string $class, array &$preloaded)
51+
private static function doPreload(string $class, array &$preloaded): void
5252
{
5353
if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], true)) {
5454
return;
@@ -68,9 +68,7 @@ private static function doPreload(string $class, array &$preloaded)
6868

6969
if (\PHP_VERSION_ID >= 70400) {
7070
foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) {
71-
if (($t = $p->getType()) && !$t->isBuiltin()) {
72-
self::doPreload($t->getName(), $preloaded);
73-
}
71+
self::preloadType($p->getType(), $preloaded);
7472
}
7573
}
7674

@@ -84,17 +82,26 @@ private static function doPreload(string $class, array &$preloaded)
8482
}
8583
}
8684

87-
if (($t = $p->getType()) && !$t->isBuiltin()) {
88-
self::doPreload($t->getName(), $preloaded);
89-
}
85+
self::preloadType($p->getType(), $preloaded);
9086
}
9187

92-
if (($t = $m->getReturnType()) && !$t->isBuiltin()) {
93-
self::doPreload($t->getName(), $preloaded);
94-
}
88+
self::preloadType($p->getReturnType(), $preloaded);
9589
}
9690
} catch (\ReflectionException $e) {
9791
// ignore missing classes
9892
}
9993
}
94+
95+
private static function preloadType(?\ReflectionType $t, array &$preloaded): void
96+
{
97+
if (!$t || $t->isBuiltin()) {
98+
return;
99+
}
100+
101+
foreach ($t instanceof \ReflectionUnionType ? $t->getTypes() : [$t] as $t) {
102+
if (!$t->isBuiltin()) {
103+
self::doPreload($t instanceof \ReflectionNamedType ? $t->getName() : $t, $preloaded);
104+
}
105+
}
106+
}
100107
}

src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class InvalidParameterTypeException extends InvalidArgumentException
2121
{
2222
public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter)
2323
{
24-
parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $parameter->getType()->getName(), $type));
24+
$acceptedType = $parameter->getType();
25+
$acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType;
26+
27+
parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type), $type);
2528
}
2629
}

src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private function getEventFromTypeDeclaration(ContainerBuilder $container, string
138138
|| !($r = $container->getReflectionClass($class, false))
139139
|| !$r->hasMethod($method)
140140
|| 1 > ($m = $r->getMethod($method))->getNumberOfParameters()
141-
|| !($type = $m->getParameters()[0]->getType())
141+
|| !($type = $m->getParameters()[0]->getType()) instanceof \ReflectionNamedType
142142
|| $type->isBuiltin()
143143
|| Event::class === ($name = $type->getName())
144144
|| LegacyEvent::class === $name

src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function createArgumentMetadata($controller): array
4545
*/
4646
private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function): ?string
4747
{
48-
if (!$type = $parameter->getType()) {
48+
if (!($type = $parameter->getType()) instanceof \ReflectionNamedType) {
4949
return null;
5050
}
5151
$name = $type->getName();

src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function onControllerArguments(ControllerArgumentsEvent $event)
9999
$r = new \ReflectionFunction(\Closure::fromCallable($event->getController()));
100100
$r = $r->getParameters()[$k] ?? null;
101101

102-
if ($r && (!$r->hasType() || \in_array($r->getType()->getName(), [FlattenException::class, LegacyFlattenException::class], true))) {
102+
if ($r && (!($r = $r->getType()) instanceof \ReflectionNamedType || \in_array($r->getName(), [FlattenException::class, LegacyFlattenException::class], true))) {
103103
$arguments = $event->getArguments();
104104
$arguments[$k] = FlattenException::createFromThrowable($e);
105105
$event->setArguments($arguments);

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,24 @@ private function guessHandledClasses(\ReflectionClass $handlerClass, string $ser
228228
throw new RuntimeException(sprintf('Invalid handler service "%s": argument "$%s" of method "%s::__invoke()" must have a type-hint corresponding to the message class it handles.', $serviceId, $parameters[0]->getName(), $handlerClass->getName()));
229229
}
230230

231+
if ($type instanceof \ReflectionUnionType) {
232+
$types = [];
233+
foreach ($type->getTypes() as $type) {
234+
if (!$type->isBuiltin()) {
235+
$types[] = (string) $type;
236+
}
237+
}
238+
239+
if ($types) {
240+
return $types;
241+
}
242+
}
243+
231244
if ($type->isBuiltin()) {
232245
throw new RuntimeException(sprintf('Invalid handler service "%s": type-hint of argument "$%s" in method "%s::__invoke()" must be a class , "%s" given.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type));
233246
}
234247

235-
return [$parameters[0]->getType()->getName()];
248+
return [$type->getName()];
236249
}
237250

238251
private function registerReceivers(ContainerBuilder $container, array $busIds)

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public function setDefault($option, $value)
201201
return $this;
202202
}
203203

204-
if (isset($params[0]) && null !== ($type = $params[0]->getType()) && self::class === $type->getName() && (!isset($params[1]) || (null !== ($type = $params[1]->getType()) && Options::class === $type->getName()))) {
204+
if (isset($params[0]) && null !== ($type = $params[0]->getType()) && self::class === $type->getName() && (!isset($params[1]) || (($type = $params[1]->getType()) instanceof \ReflectionNamedType && Options::class === $type->getName()))) {
205205
// Store closure for later evaluation
206206
$this->nested[$option][] = $value;
207207
$this->defaults[$option] = [];

src/Symfony/Contracts/Service/ServiceLocatorTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function getProvidedServices(): array
8787
} else {
8888
$type = (new \ReflectionFunction($factory))->getReturnType();
8989

90-
$this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').$type->getName() : '?';
90+
$this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
9191
}
9292
}
9393
}

src/Symfony/Contracts/Service/ServiceSubscriberTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static function getSubscribedServices(): array
4040
}
4141

4242
if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) {
43-
$services[self::class.'::'.$method->name] = '?'.$returnType->getName();
43+
$services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $type);
4444
}
4545
}
4646

0 commit comments

Comments
 (0)