markTestSkipped('Cannot run test, base class "GMP" does not exist!'); return; } $this->addFile( 'somefile.php', ' 'GMP', '$b' => 'GMP', '$c' => 'GMP', '$d' => 'GMP', '$f' => 'GMP', '$g' => 'GMP', '$h' => 'GMP', '$i' => 'GMP', '$j' => 'GMP', '$k' => 'GMP', '$l' => 'GMP', '$m' => 'GMP', '$n' => 'GMP', '$o' => 'GMP', '$p' => 'GMP', '$q' => 'GMP', '$r' => 'GMP', '$s' => 'GMP', '$t' => 'GMP', ]; $context = new \Psalm\Context(); $this->analyzeFile('somefile.php', $context); $actual_vars = []; foreach ($assertions as $var => $_) { if (isset($context->vars_in_scope[$var])) { $actual_vars[$var] = (string)$context->vars_in_scope[$var]; } } $this->assertSame($assertions, $actual_vars); } public function testStrictTrueEquivalence(): void { $config = \Psalm\Config::getInstance(); $config->strict_binary_operands = true; $this->addFile( 'somefile.php', 'expectException(\Psalm\Exception\CodeException::class); $this->expectExceptionMessage('RedundantIdentityWithTrue'); $this->analyzeFile('somefile.php', new \Psalm\Context()); } /** * @return iterable,error_levels?:string[]}> */ public function providerValidCodeParse(): iterable { return [ 'regularAddition' => [ ' [ '$a' => 'int', ], ], 'differingNumericTypesAdditionInWeakMode' => [ ' [ '$a' => 'float', ], ], 'modulo' => [ ' [ '$a' => 'int', '$b' => 'int', '$c' => 'int', '$d' => 'int', ], ], 'numericAddition' => [ ' [ ' [ ' [ ' [], 'error_levels' => ['PossiblyFalseOperand'], ], 'bitwiseoperations' => [ '> 2; $f = "a" & "b";', 'assertions' => [ '$a' => 'int', '$b' => 'int', '$c' => 'positive-int', '$d' => 'positive-int', '$e' => 'positive-int', '$f' => 'string', ], ], 'booleanXor' => [ ' [ '$a' => 'positive-int', '$b' => 'positive-int', '$c' => 'bool', '$d' => 'bool', ], ], 'ternaryAssignment' => [ ' [ ' [ ' [ '$a' => 'float', '$b' => 'float', ], ], 'exponent' => [ ' [ '$a' => 'string', '$b' => 'positive-int', ], ], 'bitwiseNot' => [ ' [ '$a' => 'int', '$b' => 'int', '$c' => 'int', '$d' => 'string', ], ], 'stringIncrementSuppressed' => [ ' [ '$a' => 'string', ], ], 'nullCoalescingAssignment' => [ ' [], 'error_levels' => [], '7.4', ], 'nullCoalescingArrayAssignment' => [ ' $arr */ function foo(array $arr) : void { $b = []; foreach ($arr as $a) { $b[0] ??= $a; } }', 'assertions' => [], 'error_levels' => [], '7.4', ], 'addArrays' => [ ' 5]; }' ], 'addIntToZero' => [ ' [ ' [ ' [ ' $b); }' ] ]; } /** * @return iterable */ public function providerInvalidCodeParse(): iterable { return [ 'badAddition' => [ ' 'InvalidOperand', ], 'differingNumericTypesAdditionInStrictMode' => [ ' 'InvalidOperand', 'error_levels' => [], 'strict_mode' => true, ], 'concatenationWithNumberInStrictMode' => [ ' 'InvalidOperand', 'error_levels' => [], 'strict_mode' => true, ], 'addArrayToNumber' => [ ' 'InvalidOperand', 'error_levels' => [], 'strict_mode' => true, ], 'additionWithClassInWeakMode' => [ ' 'InvalidOperand', ], 'possiblyInvalidOperand' => [ ' 'PossiblyInvalidOperand', ], 'possiblyInvalidConcat' => [ ' 'PossiblyInvalidOperand', ], 'invalidGMPOperation' => [ ' 'InvalidOperand - src' . DIRECTORY_SEPARATOR . 'somefile.php:3:26 - Cannot add GMP to non-numeric type', ], 'stringIncrement' => [ ' 'StringIncrement', ], 'falseIncrement' => [ ' 'FalseOperand', ], 'trueIncrement' => [ ' 'InvalidOperand', ], 'possiblyDivByZero' => [ ' 'PossiblyNullOperand', ], 'invalidExponent' => [ ' 'InvalidOperand', ], 'invalidBitwiseOr' => [ ' 'InvalidOperand', ], 'invalidBitwiseNot' => [ ' 'InvalidOperand', ], 'possiblyInvalidBitwiseNot' => [ ' 'PossiblyInvalidOperand', ], 'invalidBooleanBitwiseNot' => [ ' 'InvalidOperand', ], 'substrImpossible' => [ ' 'TypeDoesNotContainType', ], ]; } }