123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- <?php
- use Foo\Baz\Qux\Forest;
- use Some\ClassName as ClassAlias;
- use Tests\Fixtures\Model;
- use Tests\Fixtures\RegularClass;
- use function Tests\Fixtures\{makeModel};
- enum GlobalEnum {
- case Admin;
- case Guest;
- case Moderator;
- }
- test('named arguments', function () {
- $variable = new RegularClass();
- $f1 = function (string $a1) use ($variable) {
- return new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(),
- a11: RegularClass::C,
- a12: RegularClass::staticMethod(),
- a13: (new RegularClass())->instanceMethod(),
- a14: [new RegularClass(), RegularClass::C, RegularClass::staticMethod(), (new RegularClass())->instanceMethod()],
- ),
- a11: RegularClass::C,
- a12: [new RegularClass(), RegularClass::C],
- a13: RegularClass::staticMethod(),
- a14: (new RegularClass())->instanceMethod(),
- a15: fn () => new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(),
- a11: RegularClass::C,
- a12: RegularClass::staticMethod(),
- a13: (new RegularClass())->instanceMethod(),
- a14: [new RegularClass(), RegularClass::C, RegularClass::staticMethod(), (new RegularClass())->instanceMethod()],
- ),
- a11: RegularClass::C,
- a12: [new RegularClass(), RegularClass::C],
- a13: RegularClass::staticMethod(),
- a14: (new RegularClass())->instanceMethod(),
- ),
- a16: fn () => fn () => new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(),
- a11: RegularClass::C,
- a12: RegularClass::staticMethod(),
- a13: (new RegularClass())->instanceMethod(),
- a14: [new RegularClass(), RegularClass::C, RegularClass::staticMethod(), (new RegularClass())->instanceMethod()],
- ),
- a11: RegularClass::C,
- a12: [new RegularClass(), RegularClass::C],
- a13: RegularClass::staticMethod(),
- a14: (new RegularClass())->instanceMethod(),
- ),
- a17: function () use ($variable) {
- return new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(
- a1: $a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', $a1, 1, null, true],
- a9: [[[[['string', $a1, 1, null, true]]]]],
- a10: new RegularClass(),
- a11: RegularClass::C,
- a12: RegularClass::staticMethod(),
- a13: (new RegularClass())->instanceMethod(),
- a14: [new RegularClass(), RegularClass::C, RegularClass::staticMethod(), (new RegularClass())->instanceMethod()],
- ),
- a11: RegularClass::C,
- a12: [new RegularClass(), RegularClass::C],
- a13: RegularClass::staticMethod(),
- a14: (new RegularClass())->instanceMethod(),
- );
- },
- a18: reflection_closure_my_function(),
- a19: reflection_closure_my_function(ReflectionClosureGlobalEnum::Guest),
- a20: reflection_closure_my_function(enum: ReflectionClosureGlobalEnum::Guest),
- a21: match (true) {
- true => new RegularClass(),
- false => (new RegularClass()) instanceof RegularClass,
- default => reflection_closure_my_function(enum: ReflectionClosureGlobalEnum::Guest),
- },
- );
- };
- $e1 = "function (string \$a1) use (\$variable) {
- return new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: \Tests\Fixtures\RegularClass::staticMethod(),
- a13: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- a14: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C, \Tests\Fixtures\RegularClass::staticMethod(), (new \Tests\Fixtures\RegularClass())->instanceMethod()],
- ),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C],
- a13: \Tests\Fixtures\RegularClass::staticMethod(),
- a14: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- a15: fn () => new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: \Tests\Fixtures\RegularClass::staticMethod(),
- a13: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- a14: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C, \Tests\Fixtures\RegularClass::staticMethod(), (new \Tests\Fixtures\RegularClass())->instanceMethod()],
- ),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C],
- a13: \Tests\Fixtures\RegularClass::staticMethod(),
- a14: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- ),
- a16: fn () => fn () => new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: \Tests\Fixtures\RegularClass::staticMethod(),
- a13: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- a14: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C, \Tests\Fixtures\RegularClass::staticMethod(), (new \Tests\Fixtures\RegularClass())->instanceMethod()],
- ),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C],
- a13: \Tests\Fixtures\RegularClass::staticMethod(),
- a14: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- ),
- a17: function () use (\$variable) {
- return new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(
- a1: \$a1,
- a2: 'string',
- a3: 1,
- a4: 1.1,
- a5: true,
- a6: null,
- a7: ['string'],
- a8: ['string', \$a1, 1, null, true],
- a9: [[[[['string', \$a1, 1, null, true]]]]],
- a10: new \Tests\Fixtures\RegularClass(),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: \Tests\Fixtures\RegularClass::staticMethod(),
- a13: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- a14: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C, \Tests\Fixtures\RegularClass::staticMethod(), (new \Tests\Fixtures\RegularClass())->instanceMethod()],
- ),
- a11: \Tests\Fixtures\RegularClass::C,
- a12: [new \Tests\Fixtures\RegularClass(), \Tests\Fixtures\RegularClass::C],
- a13: \Tests\Fixtures\RegularClass::staticMethod(),
- a14: (new \Tests\Fixtures\RegularClass())->instanceMethod(),
- );
- },
- a18: \\reflection_closure_my_function(),
- a19: \\reflection_closure_my_function(\ReflectionClosureGlobalEnum::Guest),
- a20: \\reflection_closure_my_function(enum: \ReflectionClosureGlobalEnum::Guest),
- a21: match (true) {
- true => new \Tests\Fixtures\RegularClass(),
- false => (new \Tests\Fixtures\RegularClass()) instanceof \Tests\Fixtures\RegularClass,
- default => \\reflection_closure_my_function(enum: \ReflectionClosureGlobalEnum::Guest),
- },
- );
- }";
- expect($f1)->toBeCode($e1);
- })->with('serializers');
- test('enums', function () {
- $f = function (GlobalEnum $role) {
- return $role;
- };
- $e = 'function (\GlobalEnum $role) {
- return $role;
- }';
- expect($f)->toBeCode($e);
- enum ScopedEnum {
- case Admin;
- case Guest;
- case Moderator;
- }
- $f = function (ScopedEnum $role) {
- return $role;
- };
- $e = 'function (\ScopedEnum $role) {
- return $role;
- }';
- expect($f)->toBeCode($e);
- });
- enum GlobalBackedEnum: string {
- case Admin = 'Administrator';
- case Guest = 'Guest';
- case Moderator = 'Moderator';
- }
- test('backed enums', function () {
- $f = function (GlobalBackedEnum $role) {
- return $role;
- };
- $e = 'function (\GlobalBackedEnum $role) {
- return $role;
- }';
- expect($f)->toBeCode($e);
- enum ScopedBackedEnum: string {
- case Admin = 'Administrator';
- case Guest = 'Guest';
- case Moderator = 'Moderator';
- }
- $f = function (ScopedBackedEnum $role) {
- return $role;
- };
- $e = 'function (\ScopedBackedEnum $role) {
- return $role;
- }';
- expect($f)->toBeCode($e);
- });
- test('array unpacking', function () {
- $f = function () {
- $array1 = ['a' => 1];
- $array2 = ['b' => 2];
- return ['a' => 0, ...$array1, ...$array2];
- };
- $e = "function () {
- \$array1 = ['a' => 1];
- \$array2 = ['b' => 2];
- return ['a' => 0, ...\$array1, ...\$array2];
- }";
- expect($f)->toBeCode($e);
- });
- test('new in initializers', function () {
- $f = function () {
- return new ReflectionClosurePhp81Controller();
- };
- $e = 'function () {
- return new \ReflectionClosurePhp81Controller();
- }';
- expect($f)->toBeCode($e);
- });
- test('readonly properties', function () {
- $f = function () {
- $controller = new ReflectionClosurePhp81Controller();
- $controller->service = 'foo';
- };
- $e = 'function () {
- $controller = new \ReflectionClosurePhp81Controller();
- $controller->service = \'foo\';
- }';
- expect($f)->toBeCode($e);
- });
- test('first-class callable with closures', function () {
- $f = function ($a) {
- $f = fn ($b) => $a + $b + 1;
- return $f(...);
- };
- $e = 'function ($a) {
- $f = fn ($b) => $a + $b + 1;
- return $f(...);
- }';
- expect($f)->toBeCode($e);
- });
- test('first-class callable with methods', function () {
- $f = (new ReflectionClosurePhp81Controller())->publicGetter(...);
- $e = 'function ()
- {
- return $this->privateGetter();
- }';
- expect($f)->toBeCode($e);
- $f = (new ReflectionClosurePhp81Controller())->publicGetterResolver(...);
- $e = 'function ()
- {
- return $this->privateGetterResolver(...);
- }';
- expect($f)->toBeCode($e);
- });
- test('first-class callable with static methods', function () {
- $f = ReflectionClosurePhp81Controller::publicStaticGetter(...);
- $e = 'static function ()
- {
- return static::privateStaticGetter();
- }';
- expect($f)->toBeCode($e);
- $f = ReflectionClosurePhp81Controller::publicStaticGetterResolver(...);
- $e = 'static function ()
- {
- return static::privateStaticGetterResolver(...);
- }';
- expect($f)->toBeCode($e);
- });
- test('first-class callable final method', function () {
- $f = (new ReflectionClosurePhp81Controller())->finalPublicGetterResolver(...);
- $e = 'function ()
- {
- return $this->privateGetterResolver(...);
- }';
- expect($f)->toBeCode($e);
- $f = ReflectionClosurePhp81Controller::finalPublicStaticGetterResolver(...);
- $e = 'static function ()
- {
- return static::privateStaticGetterResolver(...);
- }';
- expect($f)->toBeCode($e);
- });
- test('first-class callable self return type', function () {
- $f = (new ReflectionClosurePhp81Controller())->getSelf(...);
- $e = 'function (self $instance): self
- {
- return $instance;
- }';
- expect($f)->toBeCode($e);
- });
- test('intersection types', function () {
- $f = function (ClassAlias&Forest $service): ClassAlias&Forest {
- return $service;
- };
- $e = 'function (\Some\ClassName&\Foo\Baz\Qux\Forest $service): \Some\ClassName&\Foo\Baz\Qux\Forest {
- return $service;
- }';
- expect($f)->toBeCode($e);
- });
- test('never type', function () {
- $f = function (): never {
- throw new RuntimeException('Something wrong happened.');
- };
- $e = 'function (): never {
- throw new \RuntimeException(\'Something wrong happened.\');
- }';
- expect($f)->toBeCode($e);
- });
- test('array_is_list', function () {
- $f = function () {
- return array_is_list([]);
- };
- $e = 'function () {
- return \array_is_list([]);
- }';
- expect($f)->toBeCode($e);
- });
- test('final class constants', function () {
- $f = function () {
- return ReflectionClosurePhp81Service::X;
- };
- $e = 'function () {
- return ReflectionClosurePhp81Service::X;
- };';
- expect($f)->toBeCode($e);
- })->skip('Constants in anonymous classes is not supported.');
- test('first-class callable namespaces', function () {
- $model = new Model();
- $f = $model->make(...);
- $e = 'function (\Tests\Fixtures\Model $model): \Tests\Fixtures\Model
- {
- return new \Tests\Fixtures\Model();
- }';
- expect($f)->toBeCode($e);
- });
- test('static first-class callable namespaces', function () {
- $model = new Model();
- $f = $model->staticMake(...);
- $e = 'static function (\Tests\Fixtures\Model $model): \Tests\Fixtures\Model
- {
- return new \Tests\Fixtures\Model();
- }';
- expect($f)->toBeCode($e);
- });
- test('function attributes without arguments', function () {
- $model = new Model();
- $f = #[MyAttribute] function () {
- return true;
- };
- $e = <<<EOF
- #[MyAttribute()]
- function () {
- return true;
- }
- EOF;
- expect($f)->toBeCode($e);
- });
- test('function attributes with arguments', function () {
- $model = new Model();
- $f = #[MyAttribute('My " \' Argument 1', Model::class)] function () {
- return true;
- };
- $e = <<<EOF
- #[MyAttribute('My " \' Argument 1', 'Tests\Fixtures\Model')]
- function () {
- return true;
- }
- EOF;
- expect($f)->toBeCode($e);
- });
- test('function attributes with named arguments', function () {
- $model = new Model();
- $f = #[MyAttribute(string: 'My " \' Argument 1', model:Model::class)] function () {
- return false;
- };
- $e = <<<EOF
- #[MyAttribute(string: 'My " \' Argument 1', model: 'Tests\Fixtures\Model')]
- function () {
- return false;
- }
- EOF;
- expect($f)->toBeCode($e);
- });
- test('function attributes with first-class callable with methods', function () {
- $model = new Model();
- $f = (new SerializerPhp81Controller())->publicGetter(...);
- $e = <<<EOF
- #[Tests\Fixtures\ModelAttribute()]
- #[MyAttribute('My " \' Argument 1', 'Tests\Fixtures\Model')]
- function ()
- {
- return \$this->privateGetter();
- }
- EOF;
- expect($f)->toBeCode($e);
- });
- class ReflectionClosurePhp81Service
- {
- }
- class ReflectionClosurePhp81Controller
- {
- public function __construct(
- public readonly ReflectionClosurePhp81Service $service = new ReflectionClosurePhp81Service(),
- ) {
- // ..
- }
- public function publicGetter()
- {
- return $this->privateGetter();
- }
- private function privateGetter()
- {
- return $this->service;
- }
- public static function publicStaticGetter()
- {
- return static::privateStaticGetter();
- }
- public static function privateStaticGetter()
- {
- return (new ReflectionClosurePhp81Controller())->service;
- }
- public function publicGetterResolver()
- {
- return $this->privateGetterResolver(...);
- }
- private function privateGetterResolver()
- {
- return fn () => $this->service;
- }
- public static function publicStaticGetterResolver()
- {
- return static::privateStaticGetterResolver(...);
- }
- public static function privateStaticGetterResolver()
- {
- return fn () => (new ReflectionClosurePhp81Controller())->service;
- }
- final public function finalPublicGetterResolver()
- {
- return $this->privateGetterResolver(...);
- }
- final public static function finalPublicStaticGetterResolver()
- {
- return static::privateStaticGetterResolver(...);
- }
- public function getSelf(self $instance): self
- {
- return $instance;
- }
- }
- enum ReflectionClosureGlobalEnum {
- case Admin;
- case Guest;
- case Moderator;
- }
- function reflection_closure_my_function(SerializerGlobalEnum $enum = SerializerGlobalEnum::Admin)
- {
- return $enum;
- }
|