[ 'code' => ' */ function test1($a) {} /** * @psalm-suppress InvalidReturnType * @return properties-of */ function test2() {} /** * @psalm-suppress InvalidReturnType * @return properties-of */ function test3() {} /** @var i $i */ assert($i instanceof b); $result1 = test1($i); $result2 = test2(); $result3 = test3(); ', 'assertions' => [ '$result1===' => 'array{a: int, ...}', '$result2===' => 'array{a: int, ...}', '$result3===' => 'array{a: int, ...}', ], ], 'publicPropertiesOf' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', ], 'protectedPropertiesOf' => [ 'code' => ' */ function returnPropertyOfA() { return ["adams" => 42]; } ', ], 'privatePropertiesOf' => [ 'code' => ' */ function returnPropertyOfA() { return ["bar" => "foo"]; } ', ], 'allPropertiesOf' => [ 'code' => ' */ function returnPropertyOfA(int $visibility) { return [ "foo" => true, "bar" => "foo", "adams" => 1 ]; } ', ], 'finalPropertiesOf' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', ], 'allPropertiesOfContainsNoStatic' => [ 'code' => ' */ function returnPropertyOfA(int $visibility) { return [ "foo" => true, "bar" => "foo", "adams" => 1 ]; } ', ], 'usePropertiesOfSelfAsArrayKey' => [ 'code' => ' */ public function asArray() { return [ "a" => $this->a, "b" => $this->b ]; } } ', ], 'usePropertiesOfStaticAsArrayKey' => [ 'code' => ' */ public function asArray() { return [ "a" => $this->a, "b" => $this->b ]; } } class B extends A { /** @var int */ public $c = 3; public function asArray() { return [ "a" => $this->a, "b" => $this->b, "c" => $this->c, ]; } } ', ], 'propertiesOfMultipleInheritanceStaticAsArrayKey' => [ 'code' => ' */ public function asArray() { return [ "a" => $this->a, "b" => $this->b ]; } } class B extends A { /** @var int */ public $c = 3; } class C extends B { /** @var int */ public $d = 4; public function asArray() { return [ "a" => $this->a, "b" => $this->b, "c" => $this->c, "d" => $this->d, ]; } } ', ], ]; } public function providerInvalidCodeParse(): iterable { return [ 'onlyOneTemplateParam' => [ 'code' => ' */ $test = "foobar"; ', 'error_message' => 'InvalidDocblock', ], 'propertiesOfPicksNoStatic' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'publicPropertiesOfPicksNoPrivate' => [ 'code' => ' */ function returnPropertyOfA() { return ["bar" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'publicPropertiesOfPicksNoProtected' => [ 'code' => ' */ function returnPropertyOfA() { return ["adams" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'protectedPropertiesOfPicksNoPublic' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'protectedPropertiesOfPicksNoPrivate' => [ 'code' => ' */ function returnPropertyOfA() { return ["bar" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'privatePropertiesOfPicksNoPublic' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'privatePropertiesOfPicksNoProtected' => [ 'code' => ' */ function returnPropertyOfA() { return ["adams" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], 'finalPropertiesOfInexact' => [ 'code' => ' */ function returnPropertyOfA() { return ["foo" => true]; } ', 'error_message' => 'InvalidReturnStatement', ], ]; } }