2 // Copyright 2004-present Facebook. All Rights Reserved.
4 class GenericBase
<Tfirst
, Tsecond
> {
5 const int GENERIC_CONSTANT
= -(1 +
2);
6 public function __construct(public Tfirst
$first, public Tsecond
$second) {}
9 type GenericType
<T
> = GenericBase
<T
, int>;
11 enum Mode
: int as int {
16 function with_enum_and_constant(Mode
$arg): int {
17 return $arg + Mode
::One + GenericBase
::GENERIC_CONSTANT
;
20 class GenericDerived
<Tfirst
> extends GenericBase
<Tfirst
, Mode
> {
21 public function __construct(Tfirst
$first, Mode
$second) {
22 parent
::__construct($first, $second);
23 $this->property
= $second;
26 protected int $property;
28 public function foo(): void
{}
34 class NonGenericDerived
extends GenericBase
<First
, Second
> {}
37 public function generic_method
<T
>(T
$arg): void
{}
40 function with_generic_method(int $arg): void
{
42 $r->generic_method($arg);
45 function with_generic_method_with_wildcard_tparam(int $arg): void
{
47 $r->generic_method
<_
>($arg);
50 function with_properties
<T
>(GenericDerived
<T
> $arg) : Mode
{
51 $x = new GenericDerived
<int>(1, Mode
::Two
);
55 function with_generic_type
<T
>(GenericType
<T
> $arg): void
{
58 function with_non_generic_type(NonGenericDerived
$_): void
{}
60 interface GenericInterface
<Tfirst
, Tsecond
> {}
62 interface IGenericDerived
<T
> extends GenericInterface
<T
, int> {
63 require extends GenericBase
<float, T
>;
66 function with_generic_interface
<T
>(IGenericDerived
<T
> $arg): void
{}
68 function with_is_refinement
<Tfirst
, Tsecond
>(
69 GenericBase
<Tfirst
, Tsecond
> $x,
71 if ($x is GenericDerived
<_
>) {
76 class BoundedGeneric
<T
as arraykey
> {
77 public function emptyKeyset(): keyset
<T
> {
82 function with_bounded_generic_class_tparam(BoundedGeneric
<int> $x): keyset
<int> {
83 return $x->emptyKeyset();
86 interface IResult
<+T
> {}
88 class Result
<+T
> implements IResult
<T
> {}
90 interface IKwery
<TResult
as Result
<mixed>> {}
92 class Kwery
<TValue
, TResult
as Result
<TValue
>> implements IKwery
<TResult
> {}
94 function kwery(): Kwery
<int, Result
<int>> {
98 <<__ConsistentConstruct
>>
99 abstract class Box
<+T
> {
100 private function __construct(private T
$value) {}
101 final public static function make(T
$value): this
{
102 return new static($value);
106 class IntBox
extends Box
<int> {}
108 function with_contra_tparam(): Box
<int> {
109 return IntBox
::make(42);
112 class WithReifiedGenerics
<reify T
as arraykey
> {}
114 function with_reified_generics(): WithReifiedGenerics
<int> {
115 return new WithReifiedGenerics
<int>();