2 // Copyright 2004-present Facebook. All Rights Reserved.
8 class A
extends A0
implements I1
{}
10 class B
implements I1
{}
14 class D
<Tfirst
, Tsecond
> extends B
{}
16 class E
<T
> extends D
<T
, int> {}
18 type Complex
= shape('first' => int, 'second' => B
);
20 newtype Point
= shape('x' => int, 'y' => int);
22 function generic
<T
>(): int {
26 function generic_with_bound
<T
as arraykey
>(T
$x): keyset
<T
> {
34 function shallow_toplevel(C
$c): void
{
38 function with_generics
<Tfirst
, Tsecond
>(D
<Tfirst
, Tsecond
> $d, E
<Tfirst
> $e): int {
42 function with_generics_with_bounds(int $x): keyset
<int> {
43 return generic_with_bound($x);
46 function with_typedefs(Complex
$c, shape('x' => int, 'y' => C
) $pair) : Point
{
47 return shape('x' => $pair['x'], 'y' => $c['first']);
50 function with_defaults(int $arg = 42, float $argf = 4.2): void
{
53 function call_defaulted(int $arg): void
{
58 function with_default_and_variadic(mixed $x, ?
string $y = null, mixed ...$z): void
{}
60 function call_with_default_and_variadic(string $s): void
{
61 with_default_and_variadic(42);
62 with_default_and_variadic(42, 'meaning of life');
63 with_default_and_variadic(42, '%s', $s);
66 function nonexistent_dependency(BogusType
$arg): void
{}
68 function builtin_argument_types(Exception
$e, keyset
<string> $k): void
{}
70 function recursive_function(int $n): int {
74 return $n +
recursive_function($n - 1);
77 class WithRecursiveMethods
{
78 public function recursive_instance(): void
{
79 $this->recursive_instance();
81 public static function recursive_static(): void
{
82 WithRecursiveMethods
::recursive_static();
86 function with_mapped_namespace(): void
{
87 PHP\
ini_set('foo', 'bar');
90 function with_built_in_constant(): int {
94 function reactive(mixed $x = null): void
{}
96 function call_reactive(): void
{
104 public function __construct(Fred
$_) {
109 function with_constructor_dependency(Thud
$x): int {
113 function with_newtype_with_bound(dict
<N
, mixed> $_): void
{}
115 newtype M
as N
= nothing
;
117 function with_newtype_with_newtype_bound(M
$_): void
{}
119 type UNSAFE_TYPE_HH_FIXME_
<T
> = T
;
122 type UNSAFE_TYPE_HH_FIXME
= UNSAFE_TYPE_HH_FIXME_
;
124 function with_unsafe_type_hh_fixme(UNSAFE_TYPE_HH_FIXME
$x): int {
128 type Option
<T
> = Id
<?T
>;
131 class WithTypeAliasHint
{
132 private Option
<int> $x = null;
134 public function getX(): Option
<int> {
139 type TydefWithFun
<T
> = (
140 (function(int, ?T
): void
),
141 (function(int, float...):void
)
144 function function_in_typedef
<T
>(TydefWithFun
<T
> $y):void
{}
146 type TydefWithCapabilities
<T
> = (
148 (function()[]: void
),
149 (function()[write_props
,rx
]: void
),
152 function contexts_in_typedef
<T
>(TydefWithCapabilities
<T
> $y):void
{}
154 function with_argument_dependent_context_callee(
155 (function()[_
]: void
) $f,
156 )[write_props
, ctx
$f]: void
{
160 function with_argument_dependent_context()[ policied_local
, rx
]: void
{
161 with_argument_dependent_context_callee(()[policied_local
] ==> {
167 public static function with_argument_dependent_context(
168 (function()[_
]: void
) $f,
169 )[write_props
, ctx
$f]: void
{
174 class WithContextConstant
{
175 const ctx C
= [policied_local
];
176 public function has_io()[self
::C
]: void
{
181 function with_optional_argument_dependent_context_callee(
182 ?
(function()[_
]: void
) $f1,
184 if ($f1 is nonnull
) {
189 function with_optional_argument_dependent_context(): void
{
190 with_optional_argument_dependent_context_callee(null);
193 function my_keys
<Tk
as arraykey
, Tv
>(
194 KeyedTraversable
<Tk
, Tv
> $traversable,
197 foreach ($traversable as $key => $_) {
203 function with_expr_in_user_attrs(): void
{
207 <<MyUserAttr('blah')>>
208 type TransparentWithUserAttr
= int;
210 <<MyUserAttr('blah')>>
211 newtype OpaqueWithUserAttr
= int;
213 <<MyUserAttr('blah')>>
214 enum EnumWithUserAttr
: int as int {
218 function enum_with_user_attr(EnumWithUserAttr
$x): void
{}
220 function transparent_with_user_attr(TransparentWithUserAttr
$x): void
{}
222 function opaque_with_user_attr(OpaqueWithUserAttr
$x): void
{}
224 <<MyUserAttr('blah')>>
226 public function foo(): void
{}
229 class WithMethodWithUserAttr
{
230 <<MyUserAttr('blah')>>
231 public function foo(): void
{}
234 class WithTypeConstantWithUserAttr
{
235 <<MyUserAttr('blah')>>
237 public function foo(): self
::T
{
242 class WithStaticPropWithUserAttr
{
243 <<MyUserAttr('blah')>> public static int $i = 0;
244 public function foo(): int {
249 class WithPropWithUserAttr
{
250 <<MyUserAttr('blah')>> public int $i = 0;
251 public function foo(): int {
256 class WithConstrPropWithUserAttr
{
257 public function __construct(<<MyUserAttr('blah')>> private int $i){}
260 function with_constr_prop_with_user_attr():void
{
261 $_ = new WithConstrPropWithUserAttr(2);
264 <<MyUserAttr('blah')>>
265 function with_user_attr(): void
{}
267 function with_param_with_user_attr(<<MyUserAttr('blah')>> int $s): void
{}
269 function with_tparam_with_user_attr
<<<MyUserAttr('blah')>> T>(T $x): void {}
271 final class MyUserAttr
275 HH\TypeAliasAttribute
,
277 HH\FunctionAttribute
,
278 HH\InstancePropertyAttribute
,
279 HH\StaticPropertyAttribute
,
280 HH\ParameterAttribute
,
281 HH\TypeParameterAttribute
,
282 HH\TypeConstantAttribute
{
283 public function __construct(string $first, string ...$remainder)[] {}