diff --git a/ci/phpstan/baselines/lexer-constants.neon b/ci/phpstan/baselines/lexer-constants.neon index 7c8abdf1..943744fd 100644 --- a/ci/phpstan/baselines/lexer-constants.neon +++ b/ci/phpstan/baselines/lexer-constants.neon @@ -9,3 +9,5 @@ parameters: - '#Fetching deprecated class constant T_ORDER of class Doctrine\\ORM\\Query\\Lexer#' - '#Fetching deprecated class constant T_AS of class Doctrine\\ORM\\Query\\Lexer#' - '#Fetching deprecated class constant T_DISTINCT of class Doctrine\\ORM\\Query\\Lexer#' + - '#Parameter \#1 \$token of method Doctrine\\ORM\\Query\\Parser::match\(\) expects Doctrine\\ORM\\Query\\TokenType, mixed given.#' + - '#Parameter \#1 \$type of method Doctrine\\Common\\Lexer\\AbstractLexer::isNextToken\(\) expects Doctrine\\ORM\\Query\\TokenType, mixed given.#' diff --git a/ci/phpstan/config.neon b/ci/phpstan/config.neon index e7c54625..22d0a60e 100644 --- a/ci/phpstan/config.neon +++ b/ci/phpstan/config.neon @@ -22,3 +22,4 @@ parameters: errorFormat: table reportUnmatchedIgnoredErrors: false + treatPhpDocTypesAsCertain: false diff --git a/composer.json b/composer.json index 3cb91185..7249e87b 100644 --- a/composer.json +++ b/composer.json @@ -45,14 +45,14 @@ "require-dev": { "deptrac/deptrac": "^3.0", "doctrine/orm": "~2.14||~3.0", - "ekino/phpstan-banned-code": "^1.0", + "ekino/phpstan-banned-code": "^3.0", "friendsofphp/php-cs-fixer": "^3.72.0", - "phpstan/phpstan": "^1.12.21", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-doctrine": "^1.5.7", - "phpstan/phpstan-phpunit": "^1.4.2", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-doctrine": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.5.45", - "rector/rector": "^1.2.10", + "rector/rector": "^2.0", "symfony/cache": "^6.4||^7.0" }, "suggest": { diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseType.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseType.php index 1f2598d1..a4d0e644 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseType.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseType.php @@ -16,7 +16,10 @@ */ abstract class BaseType extends Type { - protected const TYPE_NAME = null; + /** + * @var string + */ + protected const TYPE_NAME = ''; public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { @@ -42,7 +45,7 @@ public function requiresSQLCommentHint(AbstractPlatform $platform): bool private function throwExceptionIfTypeNameNotConfigured(): void { - if (null === static::TYPE_NAME) { + if (static::TYPE_NAME === '') { throw new \LogicException(\sprintf('Doctrine type defined in class %s has no meaningful value for TYPE_NAME constant', self::class)); } } diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php index 15115b4e..d9360e98 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php @@ -38,10 +38,6 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str protected function transformToPostgresTextArray(array $phpTextArray): string { - if (!\is_array($phpTextArray)) { - throw new \InvalidArgumentException(\sprintf('Value %s is not an array', \var_export($phpTextArray, true))); - } - if ($phpTextArray === []) { return '{}'; } diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunction.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunction.php index cc908881..f5ed3783 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunction.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunction.php @@ -64,6 +64,7 @@ protected function feedParserWithNodes(Parser $parser): void $lastNode = $nodesMappingCount - 1; for ($i = 0; $i < $nodesMappingCount; $i++) { $parserMethod = $this->nodesMapping[$i]; + // @phpstan-ignore-next-line $this->nodes[$i] = $parser->{$parserMethod}(); if ($i < $lastNode) { $parser->match(\class_exists(TokenType::class) ? TokenType::T_COMMA : Lexer::T_COMMA); diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php index 988e9ee2..df2a08ba 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php @@ -28,6 +28,7 @@ protected function feedParserWithNodes(Parser $parser): void $lexer = $parser->getLexer(); try { + // @phpstan-ignore-next-line $this->nodes[] = $parser->{$this->commonNodeMapping}(); if ($lexer->lookahead?->type === null) { throw ParserException::missingLookaheadType(); @@ -42,6 +43,7 @@ protected function feedParserWithNodes(Parser $parser): void while (($shouldUseLexer ? Lexer::T_CLOSE_PARENTHESIS : TokenType::T_CLOSE_PARENTHESIS) !== $aheadType) { if (($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA) === $aheadType) { $parser->match($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA); + // @phpstan-ignore-next-line $this->nodes[] = $parser->{$this->commonNodeMapping}(); } diff --git a/src/MartinGeorgiev/Utils/DataStructure.php b/src/MartinGeorgiev/Utils/DataStructure.php index e1d86e33..034d59ec 100644 --- a/src/MartinGeorgiev/Utils/DataStructure.php +++ b/src/MartinGeorgiev/Utils/DataStructure.php @@ -48,12 +48,6 @@ public static function transformPostgresTextArrayToPHPArray(string $postgresArra continue; } - if (!\is_string($text)) { - $exceptionMessage = 'Unsupported data type encountered. Expected null, integer, float or string value. Instead it is "%s".'; - - throw new \InvalidArgumentException(\sprintf($exceptionMessage, \gettype($text))); - } - $phpArray[$i] = \stripslashes(\str_replace('\"', '"', $text)); } @@ -78,7 +72,13 @@ public static function transformPHPArrayToPostgresTextArray(array $phpArray): st throw new \InvalidArgumentException('Only single-dimensioned arrays are supported'); } - $escapedText = \is_numeric($text) || \ctype_digit($text) ? $text : \sprintf('"%s"', \addcslashes($text, '"\\')); + if (\is_numeric($text) || \ctype_digit($text)) { + $escapedText = $text; + } else { + \assert(\is_string($text)); + $escapedText = \sprintf('"%s"', \addcslashes($text, '"\\')); + } + $result[] = $escapedText; } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php index 5484ab4b..505f968a 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php @@ -14,6 +14,9 @@ abstract class TestCase extends BaseTestCase { + /** + * @var string + */ protected const FIXTURES_DIRECTORY = __DIR__.'/../../../../../../fixtures/MartinGeorgiev/Doctrine/Entity'; private Configuration $configuration; @@ -34,6 +37,7 @@ protected function setUp(): void private function setConfigurationCache(Configuration $configuration): void { $symfonyArrayAdapterClass = '\\'.ArrayAdapter::class; + // @phpstan-ignore-next-line $useDbalV3 = \class_exists($symfonyArrayAdapterClass) && \method_exists($configuration, 'setMetadataCache') && \method_exists($configuration, 'setQueryCache'); if ($useDbalV3) { // @phpstan-ignore-next-line @@ -45,6 +49,7 @@ private function setConfigurationCache(Configuration $configuration): void } $doctrineArrayCacheClass = '\Doctrine\Common\Cache\ArrayCache'; + // @phpstan-ignore-next-line $useDbalV2 = \class_exists($doctrineArrayCacheClass) && \method_exists($configuration, 'setMetadataCacheImpl') && \method_exists($configuration, 'setQueryCacheImpl'); if ($useDbalV2) { // @phpstan-ignore-next-line