[ 'code' => ' [ '$a===' => 'array{a: mixed}', ], ], 'sealedArrayCount' => [ 'code' => ' [ '$a===' => 'list{0?: 0, 1?: 1}', '$b===' => 'list{0, 1}|null', ], ], 'sealedArrayMagic' => [ 'code' => ' $time */ function mapTime($time): void { $atime = is_array($time) ? $time : []; if ($time === "24h") { return; } for ($day = 0; $day < 7; ++$day) { if (!array_key_exists($day, $atime) || !is_array($atime[$day])) { continue; } $dayWh = $atime[$day]; array_pop($dayWh); } }', 'assertions' => [ '$buttons===' => 'list', '$urls===' => 'list{0?: non-falsy-string}', '$mainUrlSet===' => 'bool', ], ], 'validSealedArrayAssertions' => [ 'code' => ' 2) { echo "Have C!"; } if (count($a) < 3) { echo "Do not have C!"; } ', ], 'validSealedArrayAssertions2' => [ 'code' => ' 2); ', 'assertions' => [ '$a===' => 'array{a: string, b: string, c: string}', ], ], 'instanceOfInterface' => [ 'code' => 'prop = $value; } public function do(): void { $var = $this->prop; if ($var instanceof Supplier) { $var->get(); } } }', 'assertions' => [], 'ignored_issues' => [], 'php_version' => '8.0', ], 'nullableMethodWithTernaryGuard' => [ 'code' => 'fooFoo() : null; } }', ], 'nullableMethodWithTernaryIfNullGuard' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithTernaryEmptyGuard' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithTernaryIsNullGuard' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithIfGuard' => [ 'code' => 'fooFoo(); } } }', ], 'nullableMethodWithTernaryGuardWithThis' => [ 'code' => 'a = $a; $b = $this->a ? $this->a->fooFoo() : null; } }', ], 'nullableMethodWithTernaryIfNullGuardWithThis' => [ 'code' => 'a = $a; $b = $this->a === null ? null : $this->a->fooFoo(); } }', ], 'nullableMethodWithIfGuardWithThis' => [ 'code' => 'a = $a; if ($this->a) { $this->a->fooFoo(); } } }', ], 'nullableMethodWithExceptionThrown' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithRedefinitionAndElse' => [ 'code' => 'two = 3; } $one->fooFoo(); } }', ], 'nullableMethodWithBooleanIfGuard' => [ 'code' => 'fooFoo(); } } }', ], 'nullableMethodWithNonNullBooleanIfGuard' => [ 'code' => 'fooFoo(); } } }', ], 'nullableMethodWithNonNullBooleanIfGuardAndBooleanAnd' => [ 'code' => 'fooFoo(); } } }', ], 'nullableMethodInConditionWithIfGuardBefore' => [ 'code' => 'a && $one->fooFoo()) { // do something } } }', ], 'nullableMethodWithBooleanIfGuardBefore' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedRedefinition' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedRedefinitionInElse' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedNestedRedefinition' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedSwitchRedefinition' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedSwitchRedefinitionDueToException' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedSwitchThatAlwaysReturns' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedNestedRedefinitionWithReturn' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedNestedRedefinitionWithElseReturn' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedNestedRedefinitionWithElseifReturn' => [ 'code' => 'fooFoo(); } }', ], 'nullableMethodWithGuardedSwitchBreak' => [ 'code' => 'fooFoo(); break; } } }', ], 'nullableMethodWithGuardedRedefinitionOnThis' => [ 'code' => 'one = $one; if ($this->one === null) { $this->one = new One(); } $this->one->fooFoo(); } }', ], 'arrayUnionTypeAssertion' => [ 'code' => ' [ '$ids' => 'array', ], ], 'arrayUnionTypeAssertionWithIsArray' => [ 'code' => ' [ '$ids' => 'array', ], ], '2dArrayUnionTypeAssertionWithIsArray' => [ 'code' => '>|null */ function foo() { $ids = rand(0, 1) ? [["hello"]] : null; if (is_array($ids)) { return $ids; } return null; }', ], 'variableReassignment' => [ 'code' => 'barBar();', ], 'variableReassignmentInIf' => [ 'code' => 'barBar(); }', ], 'unionTypeFlow' => [ 'code' => 'fooFoo(); } else { if ($var instanceof Two) { $var->barBar(); } else if ($var) { $var->baz(); } }', ], 'unionTypeFlowWithThrow' => [ 'code' => 'fooFoo(); } }', ], 'unionTypeFlowWithElseif' => [ 'code' => 'fooFoo(); }', ], 'typedAdjustment' => [ 'code' => ' [ '$var' => 'int|string', ], ], 'typeMixedAdjustment' => [ 'code' => ' [ '$var' => 'int|string', ], ], 'typeAdjustmentIfNull' => [ 'code' => ' 5 ? new A : null; if ($var === null) { $var = new B; }', 'assertions' => [ '$var' => 'A|B', ], ], 'whileTrue' => [ 'code' => 'fooFoo()) { $row[0] = "bad"; } } }', ], 'passingParam' => [ 'code' => 'barBar(new A);', ], 'nullToNullableParam' => [ 'code' => 'barBar(null);', ], 'objectToNullableObjectParam' => [ 'code' => 'barBar(new A);', ], 'paramCoercion' => [ 'code' => 'barBar(); } } }', ], 'paramElseifCoercion' => [ 'code' => 'barBar(); } elseif ($a instanceof C) { $a->baz(); } } }', ], 'plusPlus' => [ 'code' => ' [ '$a===' => '1', ], ], 'typedValueAssertion' => [ 'code' => ' [ 'code' => ' [ 'code' => 'fooFoo(); $a->barFoo(); } }', 'assertions' => [], ], 'trueFalseTest' => [ 'code' => ' 0) { return true; } return false; } }', ], 'intersectionTypeAfterInstanceof' => [ 'code' => 'foo = "bar"; } } interface I {}', ], 'intersectionTypeInsideInstanceof' => [ 'code' => ' [ 'code' => '&Countable $collection */ $collection = []; count($collection); /** * @param iterable&Countable $collection */ function mycount($collection): int { return count($collection); } mycount($collection);', ], 'scalarTypeParam' => [ 'code' => ' [ 'code' => ' ""]; if (rand(0, 1)) { $optgroup["a"] .= "v"; } if ($optgroup["a"] !== "") {}', ], 'redefineArrayKeyInsideIsStringConditional' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' $arr */ function foo(array $arr) : void { foreach ($arr as $k => $_) { if (is_numeric($k)) {} if (!is_numeric($k)) {} } }', ], 'narrowScalar' => [ 'code' => ' [ 'code' => ' [ '$b===' => 'int', '$c===' => 'int', '$d===' => 'int', ], ], 'narrowWithCountToAllowNonTupleKeyedArray' => [ 'code' => ' $arr */ function foo($arr): void { if (count($arr) === 2) { consume($arr); } } /** * @param array{0:string, 1: string} $input */ function consume($input): void{}', ], 'notDateTimeWithDateTimeInterface' => [ 'code' => 'add($dateInterval); return $dateTime; } else { return $dateTime->add($dateInterval); } } ', ], 'notDateTimeImmutableWithDateTimeInterface' => [ 'code' => 'add($dateInterval); } else { $dateTime->add($dateInterval); return $dateTime; } } ', ], 'CountEqual0MakesNonEmptyArray' => [ 'code' => ' [ 'code' => ',php_version?:string}> */ public function providerInvalidCodeParse(): iterable { return [ 'possiblyUndefinedVariable' => [ 'code' => ' 'PossiblyUndefinedGlobalVariable', ], 'nullableMethodCall' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodCallWithThis' => [ 'code' => 'a = $a; $this->a->fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithIfGuard' => [ 'code' => 'fooFoo(); } } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithWrongBooleanIfGuard' => [ 'code' => 'fooFoo(); } } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithWrongIfGuardedBefore' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithWrongBooleanIfGuardBefore' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithGuardedNestedIncompleteRedefinition' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithGuardedSwitchRedefinitionNoDefault' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithGuardedSwitchRedefinitionEmptyDefault' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'nullableMethodWithGuardedNestedRedefinitionWithUselessElseReturn' => [ 'code' => 'fooFoo(); } }', 'error_message' => 'PossiblyNullReference', ], 'variableReassignmentInIfWithOutsideCall' => [ 'code' => 'barBar(); } $one->barBar();', 'error_message' => 'PossiblyUndefinedMethod', ], 'wrongParam' => [ 'code' => 'barBar(5);', 'error_message' => 'InvalidArgument', ], 'intToNullableObjectParam' => [ 'code' => 'barBar(5);', 'error_message' => 'InvalidArgument', ], 'paramCoercionWithBadArg' => [ 'code' => 'barBar(); } } }', 'error_message' => 'UndefinedMethod', ], 'nullCheckInsideForeachWithNoLeaveStatement' => [ 'code' => 'fooBar();', 'error_message' => 'NullReference', ], 'possiblyUndefinedMethod' => [ 'code' => 'foo(); } }', 'error_message' => 'PossiblyUndefinedMethod', ], 'notTrueTest' => [ 'code' => ' 0; } ', 'error_message' => 'InvalidReturnStatement', ], 'notFalseTest' => [ 'code' => ' 0; } ', 'error_message' => 'InvalidReturnStatement', ], 'invalidSealedArrayAssertion1' => [ 'code' => ' 1) { }', 'error_message' => 'RedundantConditionGivenDocblockType', ], 'invalidSealedArrayAssertion2' => [ 'code' => ' 3) { }', 'error_message' => 'DocblockTypeContradiction', ], 'invalidSealedArrayAssertion3' => [ 'code' => ' 4) { }', 'error_message' => 'DocblockTypeContradiction', ], 'invalidSealedArrayAssertion4' => [ 'code' => ' 'DocblockTypeContradiction', ], 'invalidSealedArrayAssertion5' => [ 'code' => ' 'DocblockTypeContradiction', ], 'invalidSealedArrayAssertion6' => [ 'code' => ' 'RedundantConditionGivenDocblockType', ], 'intersectionTypeClassCheckAfterInstanceof' => [ 'code' => ' 'ArgumentTypeCoercion - src' . DIRECTORY_SEPARATOR . 'somefile.php:14:32 - Argument 1 of takesB expects B,' . ' but parent type A&static provided', ], 'intersectionTypeInterfaceCheckAfterInstanceof' => [ 'code' => ' 'InvalidArgument - src' . DIRECTORY_SEPARATOR . 'somefile.php:12:32 - Argument 1 of takesI expects I, but A&static provided', ], ]; } }