Skip to content

Commit 332e214

Browse files
committed
test(zend, reflection): add generics test suite and fix uncovered semantics
Signed-off-by: azjezz <azjezz@protonmail.com>
1 parent bd868b6 commit 332e214

162 files changed

Lines changed: 2251 additions & 19 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Erasure: arrow function with type parameters erases to bound
3+
--FILE--
4+
<?php
5+
$f = fn<T : int>(T $x): T => $x;
6+
$r = new ReflectionFunction($f);
7+
echo $r->getParameters()[0]->getType()->__toString(), "\n";
8+
?>
9+
--EXPECT--
10+
int
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Erasure: T : object erases to object
3+
--FILE--
4+
<?php
5+
function id<T : object>(T $x): T { return $x; }
6+
$r = new ReflectionFunction('id');
7+
echo $r->getParameters()[0]->getType()->__toString(), "\n";
8+
echo $r->getReturnType()->__toString(), "\n";
9+
?>
10+
--EXPECT--
11+
object
12+
object
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Erasure: T : Foo erases to Foo
3+
--FILE--
4+
<?php
5+
class Foo {}
6+
function id<T : Foo>(T $x): T { return $x; }
7+
$r = new ReflectionFunction('id');
8+
echo $r->getParameters()[0]->getType()->getName(), "\n";
9+
echo $r->getReturnType()->getName(), "\n";
10+
?>
11+
--EXPECT--
12+
Foo
13+
Foo
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Erasure: array<...> erases to plain array at runtime
3+
--FILE--
4+
<?php
5+
function f(array<int> $x): array<string, int> { return $x; }
6+
$r = new ReflectionFunction('f');
7+
$pt = $r->getParameters()[0]->getType();
8+
echo $pt->getName(), "\n";
9+
$rt = $r->getReturnType();
10+
echo $rt->getName(), "\n";
11+
12+
f([1, 2, 3]);
13+
echo "ok\n";
14+
?>
15+
--EXPECT--
16+
array
17+
array
18+
ok
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Erasure: closure with type parameters erases to bound
3+
--FILE--
4+
<?php
5+
$f = function <T : object>(T $x): T { return $x; };
6+
$r = new ReflectionFunction($f);
7+
echo $r->getParameters()[0]->getType()->__toString(), "\n";
8+
?>
9+
--EXPECT--
10+
object
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Erasure: composite bound erased
3+
--FILE--
4+
<?php
5+
class A {}
6+
function f<T : A|int>(T $x): T { return $x; }
7+
$rt = (new ReflectionFunction('f'))->getReturnType();
8+
echo get_class($rt), "\n";
9+
?>
10+
--EXPECT--
11+
ReflectionUnionType
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Erasure: generic signature matches hand-erased equivalent
3+
--FILE--
4+
<?php
5+
class Foo {}
6+
7+
class Generic<T : Foo> {
8+
public function get(): T { return new Foo; }
9+
}
10+
11+
class Erased {
12+
public function get(): Foo { return new Foo; }
13+
}
14+
15+
$rg = (new ReflectionClass('Generic'))->getMethod('get')->getReturnType()->__toString();
16+
$re = (new ReflectionClass('Erased'))->getMethod('get')->getReturnType()->__toString();
17+
var_dump($rg === $re);
18+
?>
19+
--EXPECT--
20+
bool(true)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Erasure: extends type arguments don't change runtime parent
3+
--FILE--
4+
<?php
5+
class Base<T> {}
6+
class Derived extends Base<int> {}
7+
echo (new ReflectionClass('Derived'))->getParentClass()->getName(), "\n";
8+
$d = new Derived;
9+
var_dump($d instanceof Base);
10+
?>
11+
--EXPECT--
12+
Base
13+
bool(true)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Erasure: generic class parameter type erased to bound
3+
--FILE--
4+
<?php
5+
interface Iface {}
6+
class Box<T : Iface> {
7+
public function set(T $x): void {}
8+
}
9+
$rm = (new ReflectionClass('Box'))->getMethod('set');
10+
echo $rm->getParameters()[0]->getType()->getName(), "\n";
11+
?>
12+
--EXPECT--
13+
Iface
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Erasure: get_class returns the erased class name
3+
--FILE--
4+
<?php
5+
class Box<T> {}
6+
$b = new Box::<int>;
7+
echo get_class($b), "\n";
8+
?>
9+
--EXPECT--
10+
Box

0 commit comments

Comments
 (0)