,error_levels?:string[]}> */ public function providerValidCodeParse() { return [ 'implictAssertInstanceOfB' => [ 'foo(); }', ], 'implicitAssertEqualsNull' => [ ' [ ' [ ' [ 'bar(); $a->foo(); }', ], 'implicitAssertInstanceOfMultipleInterfaces' => [ 'bar(); $a->foo1(); }', ], 'implicitAssertInstanceOfBInClassMethod' => [ 'assertInstanceOfB($a); $a->foo(); } }', ], 'implicitAssertPropertyNotNull' => [ 'a) { throw new \Exception(); } } public function takesA(A $a): void { $this->assertNotNullProperty(); $a->foo(); } }', ], 'implicitAssertWithoutRedundantCondition' => [ ' [ 'foo(); }', ], 'assertIfTrueAnnotation' => [ ' [ ' [ ' [ 'foo()); assertFalse($a->bar()); }', ], 'assertAllStrings' => [ ' $i * * @param iterable $i */ function assertAllStrings(iterable $i): void { /** @psalm-suppress MixedAssignment */ foreach ($i as $s) { if (!is_string($s)) { throw new \UnexpectedValueException(""); } } } function getArray(): array { return []; } function getIterable(): iterable { return []; } $array = getArray(); assertAllStrings($array); $iterable = getIterable(); assertAllStrings($iterable);', [ '$array' => 'array', '$iterable' => 'iterable', ], ], 'assertStaticMethodIfFalse' => [ ' [ ' [ 'bar();', ], 'assertThisTypeIfTrue' => [ 'isFoo()) { $t->bar(); } }' ], 'assertThisTypeSwitchTrue' => [ 'isFoo(): $t->bar(); } }' ], 'assertNotArray' => [ ' [ 'assertProperty()) { $this->a->foo(); } } /** * @psalm-assert-if-true !null $this->a */ public function assertProperty() : bool { return $this->a !== null; } }' ], 'assertIfFalseOnProperty' => [ 'assertProperty()) { $this->a->foo(); } } /** * @psalm-assert-if-false null $this->a */ public function assertProperty() : bool { return $this->a !== null; } }' ], 'assertIfTrueOnPropertyNegated' => [ 'assertProperty()) { $this->a->foo(); } } /** * @psalm-assert-if-true null $this->a */ public function assertProperty() : bool { return $this->a !== null; } }' ], 'assertIfFalseOnPropertyNegated' => [ 'assertProperty()) { $this->a->foo(); } } /** * @psalm-assert-if-false !null $this->a */ public function assertProperty() : bool { return $this->a !== null; } }' ], 'assertPropertyVisibleOutside' => [ 'x = 0; } } /** * @psalm-assert !null $this->x */ public function assertProperty() : void { if (is_null($this->x)) { throw new RuntimeException(); } } } $a = new A(); $a->maybeAssignX(); $a->assertProperty(); echo (2 * $a->x);', ], 'parseAssertion' => [ ' $data * @param mixed $data */ function isArrayOfStrings($data): void {} function foo(array $arr) : void { isArrayOfStrings($arr); foreach ($arr as $a) { foreach ($a as $b) { echo $b; } } }' ], 'noExceptionOnShortArrayAssertion' => [ ' [ ' $arr * @return array */ function foo(iterable $arr) : array { isArray($arr); return $arr; }' ], 'listAssertion' => [ ' $arr * @return list */ function foo(array $arr) : array { isList($arr); return $arr; }' ], 'scanAssertionTypes' => [ ' [ ' [ ' [ ' [ 'arr = $arr; } } /** @psalm-immutable */ class A { public B $b; public function __construct(B $b) { $this->b = $b; } /** @psalm-assert-if-true !null $this->b->arr */ public function hasArray() : bool { return $this->b->arr !== null; } } function foo(A $a) : void { if ($a->hasArray()) { echo count($a->b->arr); } }' ], 'assertOnNestedMethod' => [ 'arr = $arr; } public function getArray() : ?array { return $this->arr; } } /** @psalm-immutable */ class A { public B $b; public function __construct(B $b) { $this->b = $b; } /** @psalm-assert-if-true !null $this->b->getarray() */ public function hasArray() : bool { return $this->b->getArray() !== null; } } function foo(A $a) : void { if ($a->hasArray()) { echo count($a->b->getArray()); } }' ], 'assertOnThisMethod' => [ 'arr = $arr; } /** @psalm-assert-if-true !null $this->getarray() */ public function hasArray() : bool { return $this->arr !== null; } public function getArray() : ?array { return $this->arr; } } function foo(A $a) : void { if (!$a->hasArray()) { return; } echo count($a->getArray()); }' ], 'preventErrorWhenAssertingOnArrayUnion' => [ ' $data */ function validate(array $data): void {}' ], 'nonEmptyList' => [ ' */ function consume($value): array { isNonEmptyList($value); return $value; }' ], 'assertResource' => [ ' */ public function providerInvalidCodeParse() { return [ 'assertInstanceOfMultipleInterfaces' => [ 'bar(); $a->foo1(); }', 'error_message' => 'UndefinedMethod', ], 'assertIfTrueNoAnnotation' => [ ' 'PossiblyNullOperand', ], 'assertIfFalseNoAnnotation' => [ ' 'PossiblyNullOperand', ], 'assertIfTrueMethodCall' => [ 'isInt($p)) { strlen($p); } } }', 'error_message' => 'InvalidScalarArgument', ], 'assertIfStaticTrueMethodCall' => [ 'isInt($p)) { strlen($p); } } }', 'error_message' => 'InvalidScalarArgument', ], 'noFatalForUnknownAssertClass' => [ 'sayHello();', 'error_message' => 'UndefinedDocblockClass', ], 'assertValueImpossible' => [ ' 'InvalidDocblock', ], 'sortOfReplacementForAssert' => [ ' 'TypeDoesNotContainType', ], 'assertScalarAndEmpty' => [ ' 'RedundantCondition - src/somefile.php:19:29', ], ]; } }