,error_levels?:string[]}> */ public function providerValidCodeParse(): iterable { return [ 'getClassConstArg' => [ 'fooFoo(); break; case B::class: $a->barBar(); break; }', ], 'getClassExteriorArgClassConsts' => [ 'getMessage(); break; case LogicException::class: $e->getMessage(); break; } } ', ], 'switchGetClassVar' => [ 'foo(); break; } }', ], 'getTypeArg' => [ ' [ 'a !== null: return $obj->a; // definitely not null case !is_null($obj->b): return $obj->b; // definitely not null default: throw new \InvalidArgumentException("$obj->a or $obj->b must be set"); } }', ], 'switchMoTruthy' => [ 'a: return $obj->a; // definitely not null case $obj->b: return $obj->b; // definitely not null default: throw new \InvalidArgumentException("$obj->a or $obj->b must be set"); } }', ], 'switchWithBadBreak' => [ ' [ ' [ ' [ '$x' => 'bool', '$y' => 'bool', ], ], 'continueIsBreak' => [ ' [ ' [ 'maybeReturnsDT(); if (!is_null($dt)) { $dt = $dt->format(\DateTime::ISO8601); } break; } class A { public function maybeReturnsDT(): ?\DateTimeInterface { return rand(0,1) ? new \DateTime("now") : null; } }', ], 'issetInFallthrough' => [ ' 2) { echo "$x is large"; } break; } }', ], 'switchManyGetClass' => [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ ' [ '$a' => 'bool', '$b' => 'int', ], ], 'switchVarConditionalReAssignment' => [ ' [ '$a' => 'bool', ], ], 'moreThan30Cases' => [ ' [ ' $predefined_constants * * @return string|null */ function getGlobalConstType( ?string $fq_const_name, string $const_name, array $predefined_constants ) { if ($const_name === "STDERR" || $const_name === "STDOUT" || $const_name === "STDIN" ) { return "hello"; } if (isset($predefined_constants[$fq_const_name]) || isset($predefined_constants[$const_name]) ) { switch ($const_name) { case "PHP_MAJOR_VERSION": case "PHP_ZTS": return "int"; case "PHP_FLOAT_EPSILON": case "PHP_FLOAT_MAX": case "PHP_FLOAT_MIN": return "float"; } if ($fq_const_name && isset($predefined_constants[$fq_const_name])) { return "mixed"; } return "hello"; } return null; }' ], 'evenLongerSwitch' => [ ' [ 'format("Y") === "2020": $a->format("d-m-Y"); }' ], 'evenWorseSwitch' => [ ' [ ' [ 'a = new A(); } /** @psalm-suppress MixedArgument */ switch (get_class($this->a)) { case B::class: echo "here"; } } }', ], 'noCrashOnComplicatedCases' => [ ' [ ' [ ' */ public function providerInvalidCodeParse(): iterable { return [ 'switchReturnTypeWithFallthroughAndBreak' => [ ' 'InvalidNullableReturnType', ], 'switchReturnTypeWithFallthroughAndConditionalBreak' => [ ' 'InvalidNullableReturnType', ], 'switchReturnTypeWithNoDefault' => [ ' 'InvalidNullableReturnType', ], 'getClassArgWrongClass' => [ 'barBar(); break; }', 'error_message' => 'UndefinedMethod', ], 'getClassMissingClass' => [ ' 'UndefinedClass', ], 'getTypeNotAType' => [ ' 'UnevaluatedCode', ], 'getTypeArgWrongArgs' => [ ' 'InvalidScalarArgument', ], 'switchBadMethodCallInCase' => [ ' 'InvalidScalarArgument', ], 'continueIsNotBreak' => [ ' 'ContinueOutsideLoop', ], 'defaultAboveCaseThatBreaks' => [ ' 'InvalidReturnType', ], 'SKIPPED-switchManyGetClassWithRepetitionWithProperLineNumber' => [ ' 'RedundantCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:10', 'error_levels' => ['ParadoxicalCondition'], ], 'repeatedCaseValue' => [ ' 'ParadoxicalCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:7', ], 'impossibleCaseValue' => [ ' 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:11', ], 'impossibleCaseDefault' => [ ' 'ParadoxicalCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:11', ], 'breakWithoutSettingVar' => [ ' 'PossiblyUndefinedVariable', ], 'getClassExteriorArgStringType' => [ ' 'TypeDoesNotContainType', ], 'paradoxInFunctionCall' => [ ' 'ParadoxicalCondition' ], 'loopWithSwitchDoesntReturnFirstCase' => [ ' 'InvalidReturnType' ], 'clearDependentTypeWhenAssigning' => [ 'bar(); } }', 'error_message' => 'UndefinedMethod' ], ]; } }