diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index b1df07ee02..7adb46e867 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -759,6 +759,8 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6682.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/preg_filter.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5759.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5668.php'); } /** diff --git a/tests/PHPStan/Analyser/data/bug-5668.php b/tests/PHPStan/Analyser/data/bug-5668.php new file mode 100644 index 0000000000..5633ce0ab0 --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-5668.php @@ -0,0 +1,44 @@ + $in + */ + function has(array $in): void + { + assertType('bool', in_array('test', $in, true)); + } + + /** + * @param array $in + */ + function has2(array $in): void + { + assertType('bool', in_array('test', $in, true)); + } + + /** + * @param non-empty-array $in + */ + function has3(array $in): void + { + assertType('bool', in_array('test', $in, true)); + } + + + /** + * @param non-empty-array $in + */ + function has4(array $in): void + { + assertType('true', in_array('test', $in, true)); + } + +} diff --git a/tests/PHPStan/Analyser/data/bug-5759.php b/tests/PHPStan/Analyser/data/bug-5759.php new file mode 100644 index 0000000000..e3511e869b --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-5759.php @@ -0,0 +1,39 @@ + $fields */ + function strict(array $fields): void + { + assertType('bool', in_array(ITF::FIELD_A, $fields, true)); + } + + + /** @param array $fields */ + function loose(array $fields): void + { + assertType('bool', in_array(ITF::FIELD_A, $fields, false)); + } + + function another(): void + { + /** @var array<'source'|'dist'> $arr */ + $arr = ['source']; + + assertType('bool', in_array('dist', $arr, true)); + assertType('bool', in_array('dist', $arr)); + } + +} diff --git a/tests/PHPStan/Rules/Comparison/BooleanAndConstantConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/BooleanAndConstantConditionRuleTest.php index e16bdb0b06..267074ca19 100644 --- a/tests/PHPStan/Rules/Comparison/BooleanAndConstantConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/BooleanAndConstantConditionRuleTest.php @@ -212,4 +212,17 @@ public function testBug1746(): void ]); } + public function testBug4666(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-4666.php'], []); + } + + public function testBug2870(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-2870.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php index 4caa18dcfa..02ef452f79 100644 --- a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php @@ -482,4 +482,39 @@ public function testBugInArrayDateFormat(): void ]); } + public function testBug5496(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-5496.php'], []); + } + + public function testBug3892(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-3892.php'], []); + } + + public function testBug3314(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-3314.php'], []); + } + + public function testBug2870(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-2870.php'], []); + } + + public function testBug5354(): void + { + $this->checkAlwaysTrueCheckTypeFunctionCall = true; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-5354.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-2870.php b/tests/PHPStan/Rules/Comparison/data/bug-2870.php new file mode 100644 index 0000000000..79d9d76cfc --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-2870.php @@ -0,0 +1,9 @@ + '200', ReceiptOrder::class => '300']; + + /** @var Order[] */ + private array $dtos; + + public function __construct(OrderEntity $order) + { + $this->dtos = \array_filter([ReceiptOrder::fromOrder($order), PickingOrder::fromOrder($order)]); + } + + + /** + * @return Order[] + */ + public function getDTOs(): array + { + return $this->dtos; + } +} + +abstract class Order +{ + public const TYP = [PickingOrder::class => '200', ReceiptOrder::class => '300']; +} + +class PickingOrder extends Order +{ + public static function fromOrder(OrderEntity $order): ?self + { + return $order->isLoaded() ? new self() : null; + } +} + +class ReceiptOrder extends Order +{ + public static function fromOrder(OrderEntity $order): ?self + { + return $order->isLoaded() ? new self() : null; + } +} + +class Foo +{ + + public function doFoo(OrderSaved $event) + { + $DTOs = $event->getDTOs(); + + $DTOClasses = \array_map('\get_class', $DTOs); + $missingClasses = \array_diff(\array_keys(Order::TYP), $DTOClasses); + + if (\in_array(ReceiptOrder::class, $missingClasses, true)) { + + } + + } + +} diff --git a/tests/PHPStan/Rules/Comparison/data/bug-4666.php b/tests/PHPStan/Rules/Comparison/data/bug-4666.php new file mode 100644 index 0000000000..b9e67f0a50 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-4666.php @@ -0,0 +1,29 @@ + $objects */ + public function test(array $objects): void + { + $types = []; + foreach ($objects as $object) { + if (self::CONST_1 === $object->getType() && !in_array(self::CONST_2, $types, true)) { + $types[] = self::CONST_2; + } + } + } +} + +class MyObject +{ + /** @var string */ + private $type; + public function getType(): string{ + return $this->type; + } +} diff --git a/tests/PHPStan/Rules/Comparison/data/bug-5354.php b/tests/PHPStan/Rules/Comparison/data/bug-5354.php new file mode 100644 index 0000000000..6d8571af09 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-5354.php @@ -0,0 +1,21 @@ + 10 ? 0 : 1; + } + + if (\in_array(0, $a, true)) { + return; + } + } +} diff --git a/tests/PHPStan/Rules/Comparison/data/bug-5496.php b/tests/PHPStan/Rules/Comparison/data/bug-5496.php new file mode 100644 index 0000000000..dc5f9c6f77 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-5496.php @@ -0,0 +1,32 @@ + $propagation + */ + public function propagate($propagation): void + { + } +} + +class Foo +{ + + public function doFoo() + { + $type = new ConstParamTypes(); + + /** @var array $propagation */ + $propagation = []; + + if (\in_array('auto', $propagation, true)) { + $type->propagate($propagation); + } + + $type->propagate(['yakdam' => 'copy']); + } + +}