,error_levels?:string[]}> */ public function providerValidCodeParse() { return [ 'ignoreIssueAndAssign' => [ ' [ '$b' => 'null|stdClass', ], 'error_levels' => ['RedundantCondition'], ], 'byrefNoRedundantCondition' => [ ' [], 'error_levels' => [ 'RedundantConditionGivenDocblockType', 'DocblockTypeContradiction', ], ], 'assignmentInIf' => [ ' [ ' [], 'error_levels' => [ 'RedundantConditionGivenDocblockType', ], ], 'noRedundantConditionAfterDocblockTypeNullCheck' => [ 'foo) {} break; default: break; } }', 'assertions' => [], 'error_levels' => ['DocblockTypeContradiction'], ], 'noRedundantConditionTypeReplacementWithDocblock' => [ ' [], 'error_levels' => [ 'DocblockTypeContradiction', ], ], 'noRedundantConditionAfterPossiblyNullCheck' => [ ' [], 'error_levels' => ['PossiblyUndefinedGlobalVariable'], ], 'noRedundantConditionAfterFromDocblockRemoval' => [ 'foo() || $a->bar()) {}', 'assertions' => [], 'error_levels' => [ 'DocblockTypeContradiction', ], ], 'noEmptyUndefinedArrayVar' => [ ' [], 'error_levels' => ['MixedAssignment', 'MixedArrayAccess'], ], 'noComplaintWithIsNumericThenIsEmpty' => [ ' [ ' 0) { throw new RuntimeException("Failed"); } $value = new stdClass(); if (rand() % 2 > 0) { throw new RuntimeException("Failed"); } } catch (Exception $e) { if ($value) { var_export($value); } } if ($value) {} }', ], 'noRedundantConditionInFalseCheck' => [ ' [ 'next) {} } }', ], 'noRedundantConditionComparingBool' => [ ' [ ' [], 'error_levels' => [ 'DocblockTypeContradiction', 'RedundantConditionGivenDocblockType', ], ], 'evaluateArrayCheck' => [ ' false]; while (rand(0, 1) > 0 && !$data["f"]) { $data = ["f" => true]; } }', ], 'mixedArrayAssignment' => [ ' [], 'error_levels' => ['MixedAssignment', 'MixedArrayAccess'], ], 'hardPhpTypeAssertionsOnDocblockType' => [ ' [], 'error_levels' => ['DocblockTypeContradiction'], ], 'isObjectAssertionOnDocblockType' => [ ' [], 'error_levels' => ['RedundantConditionGivenDocblockType', 'DocblockTypeContradiction'], ], 'nullToMixedWithNullCheckNoContinue' => [ ' 3) {}', 'assignments' => [], 'error_levels' => [], ], 'replaceFalseTypeWithTrueConditionalOnMixedEquality' => [ ' [], 'error_levels' => ['MixedAssignment', 'MissingReturnType', 'MixedArrayAccess'], ], 'nullCoalescePossiblyUndefined' => [ ' true]; } $option = $options["option"] ?? false; if ($option) {}', 'assignments' => [], 'error_levels' => ['MixedAssignment', 'MixedArrayAccess'], ], 'allowIntValueCheckAfterComparisonDueToOverflow' => [ ' [ ' [ ' [ ' [ ' "value"]; if (rand(0, 1)) { $x = []; } if ($x) { var_export($x); }', ], 'arrayKeyExistsAccess' => [ ' $arr */ function foo(array $arr) : void { if (array_key_exists(1, $arr)) { $a = ($arr[1] === "b") ? true : false; } }', ], 'noRedundantConditionStringNotFalse' => [ ' [ ' [ ' [ ' [ ' [ ' [ ' ['MissingParamType'], ], 'notAlwaysTrueBinaryOp' => [ ' ['MissingParamType'] ], 'noRedundantConditionAfterAssertingValue' => [ ' [ ' [ ' $_) { if (rand(0, 1)) { unset($a["foo"][$key]); } } if (empty($a["foo"])) {} } }', [], ['MixedAssignment', 'MixedArrayAccess', 'MixedArrayOffset'] ], 'emptyKnowingArrayType' => [ '> $a */ function foo(array $a) : void { if (!empty($a["foo"])) { foreach ($a["foo"] as $key => $_) { if (rand(0, 1)) { unset($a["foo"][$key]); } } if (empty($a["foo"])) {} } }', ], ]; } /** * @return iterable */ public function providerInvalidCodeParse() { return [ 'ifFalse' => [ ' 'TypeDoesNotContainType', ], 'ifNotTrue' => [ ' 'TypeDoesNotContainType', ], 'ifTrue' => [ ' 'RedundantCondition', ], 'unnecessaryInstanceof' => [ 'fooFoo(); }', 'error_message' => 'RedundantCondition', ], 'failedTypeResolution' => [ ' 'RedundantCondition', ], 'failedTypeResolutionWithDocblock' => [ ' 'RedundantCondition', ], 'typeResolutionFromDocblockAndInstanceof' => [ ' 'RedundantCondition', ], 'typeResolutionRepeatingConditionWithSingleVar' => [ ' 5; if ($a && $a) {}', 'error_message' => 'RedundantCondition', ], 'typeResolutionRepeatingConditionWithVarInMiddle' => [ ' 5; $b = rand(0, 10) > 5; if ($a && $b && $a) {}', 'error_message' => 'RedundantCondition', ], 'typeResolutionRepeatingOredConditionWithSingleVar' => [ ' 5; if ($a || $a) {}', 'error_message' => 'ParadoxicalCondition', ], 'typeResolutionRepeatingOredConditionWithVarInMiddle' => [ ' 5; $b = rand(0, 10) > 5; if ($a || $b || $a) {}', 'error_message' => 'ParadoxicalCondition', ], 'typeResolutionIsIntAndIsNumeric' => [ ' 5 ? "hello" : 3; if (is_int($c) && is_numeric($c)) {}', 'error_message' => 'RedundantCondition', ], 'typeResolutionWithInstanceOfAndNotEmpty' => [ ' 5 ? new stdClass : null; if ($x instanceof stdClass && $x) {}', 'error_message' => 'RedundantCondition', ], 'methodWithMeaninglessCheck' => [ 'fooFoo(); } }', 'error_message' => 'TypeDoesNotContainType', ], 'twoVarLogicNotNestedWithElseifNegatedInIf' => [ ' 'RedundantCondition', ], 'refineTypeInMethodCall' => [ ' 'RedundantCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:15', ], 'replaceFalseType' => [ ' 'RedundantCondition', ], 'replaceTrueType' => [ ' 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:7', ], 'disallowFloatCheckAfterSettingToVar' => [ ' 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:7', ], 'disallowTwoIntValueChecksDueToConditionalOverflow' => [ ' 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:6', ], 'redundantEmptyArray' => [ ' "value"]; if ($x) { var_export($x); }', 'error_message' => 'RedundantCondition', ], 'redundantConditionStringNotFalse' => [ ' 'RedundantCondition', ], 'redundantConditionStringNotTrue' => [ ' 'RedundantCondition', ], 'redundantConditionAfterRemovingFalse' => [ ' 'RedundantCondition', ], 'redundantConditionAfterRemovingTrue' => [ ' 'RedundantCondition', ], 'impossibleNullEquality' => [ ' 'RedundantCondition', ], 'impossibleTrueEquality' => [ ' 'RedundantCondition', ], 'impossibleFalseEquality' => [ ' 'RedundantCondition', ], 'impossibleNumberEquality' => [ ' 'RedundantCondition', ], 'alwaysTrueBinaryOp' => [ ' 'RedundantCondition', 'error_levels' => ['MissingParamType'] ], ]; } }