Skip to content

Commit 13221d3

Browse files
committed
type context factory
1 parent a102064 commit 13221d3

File tree

7 files changed

+270
-49
lines changed

7 files changed

+270
-49
lines changed

src/Symfony/Component/TypeInfo/Tests/Fixtures/Dummy.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,15 @@
44

55
final class Dummy extends AbstractDummy
66
{
7+
private int $id;
8+
9+
public function getId(): int
10+
{
11+
return $this->id;
12+
}
13+
14+
public function setId(int $id): void
15+
{
16+
$this->id = $id;
17+
}
718
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Symfony\Component\TypeInfo\Tests\Fixtures;
4+
5+
/**
6+
* @template T of int|string
7+
* @template U
8+
*/
9+
final class DummyWithTemplates
10+
{
11+
private int $price;
12+
13+
public function getPrice(bool $inCents = false): int|float
14+
{
15+
return $inCents ? $this->price : $this->price / 100;
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Symfony\Component\TypeInfo\Tests\Fixtures;
4+
5+
use \DateTimeInterface;
6+
use \DateTimeImmutable as DateTime;
7+
8+
final class DummyWithUses
9+
{
10+
private DateTimeInterface $createdAt;
11+
12+
public function setCreatedAt(DateTime $createdAt): void
13+
{
14+
$this->createdAt = $createdAt;
15+
}
16+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\TypeInfo\Tests\TypeContext;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
16+
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
17+
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
18+
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplates;
19+
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithUses;
20+
use Symfony\Component\TypeInfo\Type;
21+
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
22+
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;
23+
24+
class TypeContextFactoryTest extends TestCase
25+
{
26+
private TypeContextFactory $typeContextFactory;
27+
28+
protected function setUp(): void
29+
{
30+
$this->typeContextFactory = new TypeContextFactory(new ArrayAdapter(), new StringTypeResolver(new ArrayAdapter()));
31+
}
32+
33+
public function testCollectClassNames()
34+
{
35+
$typeContext = $this->typeContextFactory->createFromClassName(Dummy::class, AbstractDummy::class);
36+
$this->assertSame('Dummy', $typeContext->calledClassName);
37+
$this->assertSame('AbstractDummy', $typeContext->declaringClassName);
38+
39+
$typeContext = $this->typeContextFactory->createFromReflection(new \ReflectionClass(Dummy::class));
40+
$this->assertSame('Dummy', $typeContext->calledClassName);
41+
$this->assertSame('Dummy', $typeContext->declaringClassName);
42+
43+
$typeContext = $this->typeContextFactory->createFromReflection(new \ReflectionProperty(Dummy::class, 'id'));
44+
$this->assertSame('Dummy', $typeContext->calledClassName);
45+
$this->assertSame('Dummy', $typeContext->declaringClassName);
46+
47+
$typeContext = $this->typeContextFactory->createFromReflection(new \ReflectionMethod(Dummy::class, 'getId'));
48+
$this->assertSame('Dummy', $typeContext->calledClassName);
49+
$this->assertSame('Dummy', $typeContext->declaringClassName);
50+
51+
$typeContext = $this->typeContextFactory->createFromReflection(new \ReflectionParameter([Dummy::class, 'setId'], 'id'));
52+
$this->assertSame('Dummy', $typeContext->calledClassName);
53+
$this->assertSame('Dummy', $typeContext->declaringClassName);
54+
}
55+
56+
public function testCollectNamespace()
57+
{
58+
$namespace = 'Symfony\\Component\\TypeInfo\\Tests\\Fixtures';
59+
60+
$this->assertSame($namespace, $this->typeContextFactory->createFromClassName(Dummy::class)->namespace);
61+
62+
$this->assertEquals($namespace, $this->typeContextFactory->createFromReflection(new \ReflectionClass(Dummy::class))->namespace);
63+
$this->assertEquals($namespace, $this->typeContextFactory->createFromReflection(new \ReflectionProperty(Dummy::class, 'id'))->namespace);
64+
$this->assertEquals($namespace, $this->typeContextFactory->createFromReflection(new \ReflectionMethod(Dummy::class, 'getId'))->namespace);
65+
$this->assertEquals($namespace, $this->typeContextFactory->createFromReflection(new \ReflectionParameter([Dummy::class, 'setId'], 'id'))->namespace);
66+
}
67+
68+
public function testCollectUses()
69+
{
70+
$this->assertSame([], $this->typeContextFactory->createFromClassName(Dummy::class)->uses);
71+
72+
$uses = [
73+
\DateTimeInterface::class => \DateTimeInterface::class,
74+
'DateTime' => \DateTimeImmutable::class,
75+
];
76+
77+
$this->assertSame($uses, $this->typeContextFactory->createFromClassName(DummyWithUses::class)->uses);
78+
79+
$this->assertEquals($uses, $this->typeContextFactory->createFromReflection(new \ReflectionClass(DummyWithUses::class))->uses);
80+
$this->assertEquals($uses, $this->typeContextFactory->createFromReflection(new \ReflectionProperty(DummyWithUses::class, 'createdAt'))->uses);
81+
$this->assertEquals($uses, $this->typeContextFactory->createFromReflection(new \ReflectionMethod(DummyWithUses::class, 'setCreatedAt'))->uses);
82+
$this->assertEquals($uses, $this->typeContextFactory->createFromReflection(new \ReflectionParameter([DummyWithUses::class, 'setCreatedAt'], 'createdAt'))->uses);
83+
}
84+
85+
public function testCollectClassTemplates()
86+
{
87+
$this->assertEquals([], $this->typeContextFactory->createFromClassName(Dummy::class)->classTemplates);
88+
89+
$templates = [
90+
['name' => 'T', 'type' => Type::union(Type::int(), Type::string())],
91+
['name' => 'U', 'type' => null],
92+
];
93+
94+
$this->assertEquals($templates, $this->typeContextFactory->createFromClassName(DummyWithTemplates::class)->classTemplates);
95+
96+
$this->assertEquals($templates, $this->typeContextFactory->createFromReflection(new \ReflectionClass(DummyWithTemplates::class))->classTemplates);
97+
$this->assertEquals($templates, $this->typeContextFactory->createFromReflection(new \ReflectionProperty(DummyWithTemplates::class, 'price'))->classTemplates);
98+
$this->assertEquals($templates, $this->typeContextFactory->createFromReflection(new \ReflectionMethod(DummyWithTemplates::class, 'getPrice'))->classTemplates);
99+
$this->assertEquals($templates, $this->typeContextFactory->createFromReflection(new \ReflectionParameter([DummyWithTemplates::class, 'getPrice'], 'inCents'))->classTemplates);
100+
}
101+
102+
public function testDoNotCollectClassTemplatesWhenToStringTypeResolver()
103+
{
104+
$typeContextFactory = new TypeContextFactory(new ArrayAdapter());
105+
106+
$this->assertEquals([], $typeContextFactory->createFromClassName(DummyWithTemplates::class)->classTemplates);
107+
}
108+
}

src/Symfony/Component/TypeInfo/Tests/TypeResolver/StringTypeResolverTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function resolveDataProvider(): iterable
5858
yield [Type::object(), 'object{foo: true, bar: false}'];
5959

6060
// this
61-
yield [Type::object(Dummy::class), '$this', $typeContextFactory->create(Dummy::class, AbstractDummy::class)];
61+
yield [Type::object(Dummy::class), '$this', $typeContextFactory->createFromClassName(Dummy::class, AbstractDummy::class)];
6262

6363
// const
6464
yield [Type::array(), 'array[1, 2, 3]'];
@@ -103,10 +103,10 @@ public function resolveDataProvider(): iterable
103103
yield [Type::null(), 'null'];
104104
yield [Type::union(Type::int(), Type::string()), 'array-key'];
105105
yield [Type::union(Type::int(), Type::float(), Type::string(), Type::bool()), 'scalar'];
106-
yield [Type::object(AbstractDummy::class), 'self', $typeContextFactory->create(Dummy::class, AbstractDummy::class)];
107-
yield [Type::object(Dummy::class), 'static', $typeContextFactory->create(Dummy::class, AbstractDummy::class)];
108-
yield [Type::object(AbstractDummy::class), 'parent', $typeContextFactory->create(Dummy::class)];
109-
yield [Type::object(Dummy::class), 'Dummy', $typeContextFactory->create(Dummy::class)];
106+
yield [Type::object(AbstractDummy::class), 'self', $typeContextFactory->createFromClassName(Dummy::class, AbstractDummy::class)];
107+
yield [Type::object(Dummy::class), 'static', $typeContextFactory->createFromClassName(Dummy::class, AbstractDummy::class)];
108+
yield [Type::object(AbstractDummy::class), 'parent', $typeContextFactory->createFromClassName(Dummy::class)];
109+
yield [Type::object(Dummy::class), 'Dummy', $typeContextFactory->createFromClassName(Dummy::class)];
110110
yield [Type::template('T'), 'T'];
111111

112112
// nullable

src/Symfony/Component/TypeInfo/TypeContext/TypeContext.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@
1717
* @author Mathias Arlaud <[email protected]>
1818
* @author Baptiste Leduc <[email protected]>
1919
*/
20-
final class TypeContext
20+
final readonly class TypeContext
2121
{
2222
/**
2323
* @param array<string, string> $uses
24+
* @param array<string, string> $classTemplates
2425
*/
2526
public function __construct(
26-
public readonly string $calledClassName,
27-
public readonly string $declaringClassName,
28-
public readonly ?string $namespace = null,
29-
public readonly array $uses = []
27+
public string $calledClassName,
28+
public string $declaringClassName,
29+
public ?string $namespace = null,
30+
public array $uses = [],
31+
public array $classTemplates = [],
3032
) {
3133
}
3234

0 commit comments

Comments
 (0)