Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ca6aee7

Browse filesBrowse files
committed
Merge branch '5.3' into 5.4
* 5.3: [Form] Backport type fixes [Finder] Fix iterator return types [DependencyInjection] Support for intersection types
2 parents 5ebb1fe + cc89819 commit ca6aee7
Copy full SHA for ca6aee7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

44 files changed

+330
-170
lines changed

‎.github/patch-types.php

Copy file name to clipboardExpand all lines: .github/patch-types.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/ParseError.php'):
2323
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Compiler/OptionalServiceClass.php'):
2424
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php'):
25+
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/intersectiontype_classes.php'):
2526
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/MultipleArgumentsOptionalScalarNotReallyOptional.php'):
27+
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/IntersectionConstructor.php'):
2628
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ParentNotExists.php'):
2729
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Preload/'):
2830
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php'):

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,13 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
174174

175175
throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter);
176176
}
177+
if ($reflectionType instanceof \ReflectionIntersectionType) {
178+
foreach ($reflectionType->getTypes() as $t) {
179+
$this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $t);
180+
}
181+
182+
return;
183+
}
177184
if (!$reflectionType instanceof \ReflectionNamedType) {
178185
return;
179186
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/Preloader.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private static function preloadType(?\ReflectionType $t, array &$preloaded): voi
117117
return;
118118
}
119119

120-
foreach ($t instanceof \ReflectionUnionType ? $t->getTypes() : [$t] as $t) {
120+
foreach (($t instanceof \ReflectionUnionType || $t instanceof \ReflectionIntersectionType) ? $t->getTypes() : [$t] as $t) {
121121
if (!$t->isBuiltin()) {
122122
self::doPreload($t instanceof \ReflectionNamedType ? $t->getName() : $t, $preloaded);
123123
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php
+16-7Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,31 @@ public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionPa
3333
}
3434

3535
$types = [];
36+
$glue = '|';
37+
if ($type instanceof \ReflectionUnionType) {
38+
$reflectionTypes = $type->getTypes();
39+
} elseif ($type instanceof \ReflectionIntersectionType) {
40+
$reflectionTypes = $type->getTypes();
41+
$glue = '&';
42+
} elseif ($type instanceof \ReflectionNamedType) {
43+
$reflectionTypes = [$type];
44+
} else {
45+
return null;
46+
}
3647

37-
foreach ($type instanceof \ReflectionUnionType ? $type->getTypes() : [$type] as $type) {
38-
$name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
39-
48+
foreach ($reflectionTypes as $type) {
4049
if ($type->isBuiltin()) {
4150
if (!$noBuiltin) {
42-
$types[] = $name;
51+
$types[] = $type->getName();
4352
}
4453
continue;
4554
}
4655

47-
$lcName = strtolower($name);
56+
$lcName = strtolower($type->getName());
4857
$prefix = $noBuiltin ? '' : '\\';
4958

5059
if ('self' !== $lcName && 'parent' !== $lcName) {
51-
$types[] = '' !== $prefix ? $prefix.$name : $name;
60+
$types[] = $prefix.$type->getName();
5261
continue;
5362
}
5463
if (!$r instanceof \ReflectionMethod) {
@@ -61,6 +70,6 @@ public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionPa
6170
}
6271
}
6372

64-
return $types ? implode('|', $types) : null;
73+
return $types ? implode($glue, $types) : null;
6574
}
6675
}

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,25 @@ public function testTypeNotGuessableUnionType()
258258
$pass->process($container);
259259
}
260260

261+
/**
262+
* @requires PHP 8.1
263+
*/
264+
public function testTypeNotGuessableIntersectionType()
265+
{
266+
$this->expectException(AutowiringFailedException::class);
267+
$this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\IntersectionClasses::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface&Symfony\Component\DependencyInjection\Tests\Compiler\AnotherInterface" but this class was not found.');
268+
$container = new ContainerBuilder();
269+
270+
$container->register(CollisionInterface::class);
271+
$container->register(AnotherInterface::class);
272+
273+
$aDefinition = $container->register('a', IntersectionClasses::class);
274+
$aDefinition->setAutowired(true);
275+
276+
$pass = new AutowirePass();
277+
$pass->process($container);
278+
}
279+
261280
public function testTypeNotGuessableWithTypeSet()
262281
{
263282
$container = new ContainerBuilder();

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Deprecated;
3030
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo;
3131
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\FooObject;
32+
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\IntersectionConstructor;
3233
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\UnionConstructor;
3334
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Waldo;
35+
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\WaldoFoo;
3436
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Wobble;
3537
use Symfony\Component\ExpressionLanguage\Expression;
3638

@@ -950,4 +952,37 @@ public function testReferencePassesMixed()
950952

951953
$this->addToAssertionCount(1);
952954
}
955+
956+
/**
957+
* @requires PHP 8.1
958+
*/
959+
public function testIntersectionTypePassesWithReference()
960+
{
961+
$container = new ContainerBuilder();
962+
963+
$container->register('foo', WaldoFoo::class);
964+
$container->register('intersection', IntersectionConstructor::class)
965+
->setArguments([new Reference('foo')]);
966+
967+
(new CheckTypeDeclarationsPass(true))->process($container);
968+
969+
$this->addToAssertionCount(1);
970+
}
971+
972+
/**
973+
* @requires PHP 8.1
974+
*/
975+
public function testIntersectionTypeFailsWithReference()
976+
{
977+
$container = new ContainerBuilder();
978+
979+
$container->register('waldo', Waldo::class);
980+
$container->register('intersection', IntersectionConstructor::class)
981+
->setArguments([new Reference('waldo')]);
982+
983+
$this->expectException(InvalidArgumentException::class);
984+
$this->expectExceptionMessage('Invalid definition for service "intersection": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\IntersectionConstructor::__construct()" accepts "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo&Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\WaldoInterface", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Waldo" passed.');
985+
986+
(new CheckTypeDeclarationsPass(true))->process($container);
987+
}
953988
}

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/PreloaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/PreloaderTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\Dummy;
2121
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\DummyWithInterface;
2222
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\E;
23+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\F;
24+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\G;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\IntersectionDummy;
2326
use Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\UnionDummy;
2427

2528
class PreloaderTest extends TestCase
@@ -72,4 +75,20 @@ public function testPreloadUnion()
7275
self::assertTrue(class_exists(D::class, false));
7376
self::assertTrue(class_exists(E::class, false));
7477
}
78+
79+
/**
80+
* @requires PHP 8.1
81+
*/
82+
public function testPreloadIntersection()
83+
{
84+
$r = new \ReflectionMethod(Preloader::class, 'doPreload');
85+
86+
$preloaded = [];
87+
88+
$r->invokeArgs(null, ['Symfony\Component\DependencyInjection\Tests\Fixtures\Preload\IntersectionDummy', &$preloaded]);
89+
90+
self::assertTrue(class_exists(IntersectionDummy::class, false));
91+
self::assertTrue(class_exists(F::class, false));
92+
self::assertTrue(class_exists(G::class, false));
93+
}
7594
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass;
4+
5+
class IntersectionConstructor
6+
{
7+
public function __construct(Foo&WaldoInterface $arg)
8+
{
9+
}
10+
}
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass;
4+
5+
class WaldoFoo extends Foo implements WaldoInterface
6+
{
7+
}
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Preload;
13+
14+
final class F
15+
{
16+
}
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Preload;
13+
14+
final class G
15+
{
16+
}
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Preload;
13+
14+
final class IntersectionDummy
15+
{
16+
public F&G $fg;
17+
}

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
require __DIR__.'/uniontype_classes.php';
99
require __DIR__.'/autowiring_classes_80.php';
1010
}
11+
if (\PHP_VERSION_ID >= 80100) {
12+
require __DIR__.'/intersectiontype_classes.php';
13+
}
1114

1215
class Foo
1316
{
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
4+
5+
interface AnotherInterface
6+
{
7+
}
8+
9+
class IntersectionClasses
10+
{
11+
public function __construct(CollisionInterface&AnotherInterface $collision)
12+
{
13+
}
14+
}

‎src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs
5858
*
5959
* @return SplFileInfo File information
6060
*/
61+
#[\ReturnTypeWillChange]
6162
public function current()
6263
{
6364
// the logic here avoids redoing the same work in all iterations
@@ -82,6 +83,7 @@ public function current()
8283
*
8384
* @throws AccessDeniedException
8485
*/
86+
#[\ReturnTypeWillChange]
8587
public function getChildren()
8688
{
8789
try {
@@ -109,7 +111,10 @@ public function getChildren()
109111

110112
/**
111113
* Do nothing for non rewindable stream.
114+
*
115+
* @return void
112116
*/
117+
#[\ReturnTypeWillChange]
113118
public function rewind()
114119
{
115120
if (false === $this->isRewindable()) {

‎src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,17 @@ public function getAcceptData()
6565

6666
class InnerTypeIterator extends \ArrayIterator
6767
{
68-
public function current()
68+
public function current(): \SplFileInfo
6969
{
7070
return new \SplFileInfo(parent::current());
7171
}
7272

73-
public function isFile()
73+
public function isFile(): bool
7474
{
7575
return $this->current()->isFile();
7676
}
7777

78-
public function isDir()
78+
public function isDir(): bool
7979
{
8080
return $this->current()->isDir();
8181
}

‎src/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function getAcceptData()
4242

4343
class InnerNameIterator extends \ArrayIterator
4444
{
45-
public function current()
45+
public function current(): \SplFileInfo
4646
{
4747
return new \SplFileInfo(parent::current());
4848
}

‎src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php
+4-8Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function __construct($param)
4848
}
4949
}
5050

51-
public function isFile()
51+
public function isFile(): bool
5252
{
5353
if (null === $this->type) {
5454
return false !== strpos($this->getFilename(), 'file');
@@ -57,7 +57,7 @@ public function isFile()
5757
return self::TYPE_FILE === $this->type;
5858
}
5959

60-
public function isDir()
60+
public function isDir(): bool
6161
{
6262
if (null === $this->type) {
6363
return false !== strpos($this->getFilename(), 'directory');
@@ -66,13 +66,9 @@ public function isDir()
6666
return self::TYPE_DIRECTORY === $this->type;
6767
}
6868

69-
public function isReadable()
69+
public function isReadable(): bool
7070
{
71-
if (null === $this->mode) {
72-
return preg_match('/r\+/', $this->getFilename());
73-
}
74-
75-
return preg_match('/r\+/', $this->mode);
71+
return (bool) preg_match('/r\+/', $this->mode ?? $this->getFilename());
7672
}
7773

7874
public function getContents()

‎src/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,22 @@ public function getAcceptData()
4848

4949
class InnerSizeIterator extends \ArrayIterator
5050
{
51-
public function current()
51+
public function current(): \SplFileInfo
5252
{
5353
return new \SplFileInfo(parent::current());
5454
}
5555

56-
public function getFilename()
56+
public function getFilename(): string
5757
{
5858
return parent::current();
5959
}
6060

61-
public function isFile()
61+
public function isFile(): bool
6262
{
6363
return $this->current()->isFile();
6464
}
6565

66-
public function getSize()
66+
public function getSize(): int
6767
{
6868
return $this->current()->getSize();
6969
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.