diff --git a/README.md b/README.md index 94a37e2..c72b5b5 100644 --- a/README.md +++ b/README.md @@ -69,26 +69,10 @@ This extension specifies types of values passed to: * `Assert::methodExists` * `Assert::propertyExists` * `Assert::isArrayAccessible` -* `Assert::contains` -* `Assert::startsWith` -* `Assert::startsWithLetter` -* `Assert::endsWith` -* `Assert::unicodeLetters` -* `Assert::alpha` -* `Assert::digits` -* `Assert::alnum` -* `Assert::lower` -* `Assert::upper` * `Assert::length` * `Assert::minLength` * `Assert::maxLength` * `Assert::lengthBetween` -* `Assert::uuid` -* `Assert::ip` -* `Assert::ipv4` -* `Assert::ipv6` -* `Assert::email` -* `Assert::notWhitespaceOnly` * `nullOr*` and `all*` variants of the above methods diff --git a/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php b/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php index b4cdcd0..b05be48 100644 --- a/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php +++ b/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php @@ -28,23 +28,6 @@ class AssertTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtension, TypeSpecifierAwareExtension { - private const ASSERTIONS_RESULTING_IN_NON_EMPTY_STRING = [ - 'stringNotEmpty', - 'startsWithLetter', - 'unicodeLetters', - 'alpha', - 'digits', - 'alnum', - 'lower', - 'upper', - 'uuid', - 'ip', - 'ipv4', - 'ipv6', - 'email', - 'notWhitespaceOnly', - ]; - /** @var \Closure[] */ private static $resolvers; @@ -67,10 +50,6 @@ public function isStaticMethodSupported( TypeSpecifierContext $context ): bool { - if (in_array($staticMethodReflection->getName(), self::ASSERTIONS_RESULTING_IN_NON_EMPTY_STRING, true)) { - return true; - } - if (substr($staticMethodReflection->getName(), 0, 6) === 'allNot') { $methods = [ 'allNotInstanceOf' => 2, @@ -165,11 +144,6 @@ private static function createExpression( ): ?\PhpParser\Node\Expr { $trimmedName = self::trimName($name); - - if (in_array($trimmedName, self::ASSERTIONS_RESULTING_IN_NON_EMPTY_STRING, true)) { - return self::createIsNonEmptyStringExpression($args); - } - $resolvers = self::getExpressionResolvers(); $resolver = $resolvers[$trimmedName]; $expression = $resolver($scope, ...$args); @@ -221,6 +195,18 @@ private static function getExpressionResolvers(): array [$value] ); }, + 'stringNotEmpty' => function (Scope $scope, Arg $value): \PhpParser\Node\Expr { + return new BooleanAnd( + new \PhpParser\Node\Expr\FuncCall( + new \PhpParser\Node\Name('is_string'), + [$value] + ), + new NotIdentical( + $value->value, + new String_('') + ) + ); + }, 'float' => function (Scope $scope, Arg $value): \PhpParser\Node\Expr { return new \PhpParser\Node\Expr\FuncCall( new \PhpParser\Node\Name('is_float'), @@ -486,27 +472,6 @@ private static function getExpressionResolvers(): array ) ); }, - 'contains' => function (Scope $scope, Arg $value, Arg $subString): \PhpParser\Node\Expr { - if ($scope->getType($subString->value)->isNonEmptyString()->yes()) { - return self::createIsNonEmptyStringExpression([$value]); - } - - return self::createIsStringExpression([$value]); - }, - 'startsWith' => function (Scope $scope, Arg $value, Arg $prefix): \PhpParser\Node\Expr { - if ($scope->getType($prefix->value)->isNonEmptyString()->yes()) { - return self::createIsNonEmptyStringExpression([$value]); - } - - return self::createIsStringExpression([$value]); - }, - 'endsWith' => function (Scope $scope, Arg $value, Arg $suffix): \PhpParser\Node\Expr { - if ($scope->getType($suffix->value)->isNonEmptyString()->yes()) { - return self::createIsNonEmptyStringExpression([$value]); - } - - return self::createIsStringExpression([$value]); - }, 'length' => function (Scope $scope, Arg $value, Arg $length): \PhpParser\Node\Expr { return new BooleanAnd( new \PhpParser\Node\Expr\FuncCall( @@ -709,32 +674,4 @@ private function arrayOrIterable( ); } - /** - * @param \PhpParser\Node\Arg[] $args - */ - private static function createIsStringExpression(array $args): \PhpParser\Node\Expr - { - return new \PhpParser\Node\Expr\FuncCall( - new \PhpParser\Node\Name('is_string'), - [$args[0]] - ); - } - - /** - * @param \PhpParser\Node\Arg[] $args - */ - private static function createIsNonEmptyStringExpression(array $args): \PhpParser\Node\Expr - { - return new BooleanAnd( - new \PhpParser\Node\Expr\FuncCall( - new \PhpParser\Node\Name('is_string'), - [$args[0]] - ), - new NotIdentical( - $args[0]->value, - new String_('') - ) - ); - } - } diff --git a/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php b/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php index 6c0f804..aa67576 100644 --- a/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php +++ b/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php @@ -26,9 +26,15 @@ public function testExtension(): void ]); } + public function testBug85(): void + { + $this->analyse([__DIR__ . '/data/bug-85.php'], []); + } + public static function getAdditionalConfigFiles(): array { return [ + __DIR__ . '/../../../vendor/phpstan/phpstan-strict-rules/rules.neon', __DIR__ . '/../../../extension.neon', ]; } diff --git a/tests/Type/WebMozartAssert/data/bug-85.php b/tests/Type/WebMozartAssert/data/bug-85.php new file mode 100644 index 0000000..8a0a60f --- /dev/null +++ b/tests/Type/WebMozartAssert/data/bug-85.php @@ -0,0 +1,34 @@ +