From 767698a41b3f00e05fbbdafa485d67b5ae7a85a7 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 14:42:19 +0200 Subject: [PATCH 01/39] Open 2.0.x --- .github/workflows/build.yml | 2 +- .github/workflows/platform-test.yml | 2 +- .github/workflows/test-projects.yml | 2 +- composer.json | 9 ++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 065346b2..bb82f08a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: pull_request: push: branches: - - "1.5.x" + - "2.0.x" jobs: lint: diff --git a/.github/workflows/platform-test.yml b/.github/workflows/platform-test.yml index fe88b6c9..38110353 100644 --- a/.github/workflows/platform-test.yml +++ b/.github/workflows/platform-test.yml @@ -6,7 +6,7 @@ on: pull_request: push: branches: - - "1.5.x" + - "2.0.x" jobs: tests: diff --git a/.github/workflows/test-projects.yml b/.github/workflows/test-projects.yml index d33dcf6f..2b85f70e 100644 --- a/.github/workflows/test-projects.yml +++ b/.github/workflows/test-projects.yml @@ -5,7 +5,7 @@ name: "Test projects" on: push: branches: - - "1.5.x" + - "2.0.x" jobs: test-projects: diff --git a/composer.json b/composer.json index 94c15b34..7c12d599 100644 --- a/composer.json +++ b/composer.json @@ -6,8 +6,8 @@ "MIT" ], "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.12" + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0" }, "conflict": { "doctrine/collections": "<1.0", @@ -30,10 +30,9 @@ "doctrine/persistence": "^2.2.1 || ^3.2", "gedmo/doctrine-extensions": "^3.8", "nesbot/carbon": "^2.49", - "nikic/php-parser": "^4.13.2", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^1.3.13", - "phpstan/phpstan-strict-rules": "^1.5.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9.6.20", "ramsey/uuid": "^4.2", "symfony/cache": "^5.4" From bf122092e27faf219adb723721c1dff95fda160e Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 14:52:12 +0200 Subject: [PATCH 02/39] Stop testing PHP 7.2 and 7.3 --- .github/workflows/build.yml | 20 ------------------- composer.json | 10 +++++----- .../MysqliResultRowCountReturnTypeTest.php | 4 +--- .../DBAL/PDOResultRowCountReturnTypeTest.php | 9 +-------- .../data/mysqli-result-row-count-dbal-2.php | 15 -------------- .../DBAL/data/pdo-result-row-count-dbal-2.php | 15 -------------- 6 files changed, 7 insertions(+), 66 deletions(-) delete mode 100644 tests/Type/Doctrine/DBAL/data/mysqli-result-row-count-dbal-2.php delete mode 100644 tests/Type/Doctrine/DBAL/data/pdo-result-row-count-dbal-2.php diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb82f08a..ebed3920 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,8 +17,6 @@ jobs: fail-fast: false matrix: php-version: - - "7.2" - - "7.3" - "7.4" - "8.0" - "8.1" @@ -45,10 +43,6 @@ jobs: if: matrix.php-version == '8.4' run: "composer config platform.php 8.3.99" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^8.5.31 --no-update --update-with-dependencies" - - name: "Install dependencies" run: "composer install --no-interaction --no-progress" @@ -103,8 +97,6 @@ jobs: fail-fast: false matrix: php-version: - - "7.2" - - "7.3" - "7.4" - "8.0" - "8.1" @@ -139,18 +131,10 @@ jobs: if: matrix.php-version == '8.4' run: "composer config platform.php 8.3.99" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^8.5.31 --no-update --update-with-dependencies" - - name: "Install lowest dependencies" if: ${{ matrix.dependencies == 'lowest' }} run: "composer update --prefer-lowest --no-interaction --no-progress" - - name: "Update Doctrine DBAl to ^3" - if: matrix.php-version != '7.2' && matrix.dependencies == 'lowest' - run: "composer require --dev doctrine/dbal:^3.3.8 --no-interaction --no-progress" - - name: "Install highest dependencies" if: ${{ matrix.dependencies == 'highest' }} run: "composer update --no-interaction --no-progress" @@ -198,10 +182,6 @@ jobs: if: matrix.php-version == '8.4' run: "composer config platform.php 8.3.99" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^8.5.31 --no-update --update-with-dependencies" - - name: "Install dependencies" run: "composer update --no-interaction --no-progress" diff --git a/composer.json b/composer.json index 7c12d599..1bad25c5 100644 --- a/composer.json +++ b/composer.json @@ -20,12 +20,12 @@ "cache/array-adapter": "^1.1", "composer/semver": "^3.3.2", "cweagans/composer-patches": "^1.7.3", - "doctrine/annotations": "^1.11 || ^2.0", - "doctrine/collections": "^1.6 || ^2.1", + "doctrine/annotations": "^2.0", + "doctrine/collections": "^2.1", "doctrine/common": "^2.7 || ^3.0", - "doctrine/dbal": "^2.13.8 || ^3.3.3", - "doctrine/lexer": "^2.0 || ^3.0", - "doctrine/mongodb-odm": "^1.3 || ^2.4.3", + "doctrine/dbal": "^3.3.8", + "doctrine/lexer": "^3.0", + "doctrine/mongodb-odm": "^2.4.3", "doctrine/orm": "^2.16.0", "doctrine/persistence": "^2.2.1 || ^3.2", "gedmo/doctrine-extensions": "^3.8", diff --git a/tests/Type/Doctrine/DBAL/MysqliResultRowCountReturnTypeTest.php b/tests/Type/Doctrine/DBAL/MysqliResultRowCountReturnTypeTest.php index cdfa8490..89ac5eb6 100644 --- a/tests/Type/Doctrine/DBAL/MysqliResultRowCountReturnTypeTest.php +++ b/tests/Type/Doctrine/DBAL/MysqliResultRowCountReturnTypeTest.php @@ -15,10 +15,8 @@ public function dataFileAsserts(): iterable $versionParser = new VersionParser(); if (InstalledVersions::satisfies($versionParser, 'doctrine/dbal', '>=4.0')) { yield from $this->gatherAssertTypes(__DIR__ . '/data/mysqli-result-row-count.php'); - } elseif (InstalledVersions::satisfies($versionParser, 'doctrine/dbal', '>=3.0')) { - yield from $this->gatherAssertTypes(__DIR__ . '/data/mysqli-result-row-count-dbal-3.php'); } else { - yield from $this->gatherAssertTypes(__DIR__ . '/data/mysqli-result-row-count-dbal-2.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/mysqli-result-row-count-dbal-3.php'); } } diff --git a/tests/Type/Doctrine/DBAL/PDOResultRowCountReturnTypeTest.php b/tests/Type/Doctrine/DBAL/PDOResultRowCountReturnTypeTest.php index d10ef8ab..0b6aa6bc 100644 --- a/tests/Type/Doctrine/DBAL/PDOResultRowCountReturnTypeTest.php +++ b/tests/Type/Doctrine/DBAL/PDOResultRowCountReturnTypeTest.php @@ -2,8 +2,6 @@ namespace PHPStan\Type\Doctrine\DBAL; -use Composer\InstalledVersions; -use Composer\Semver\VersionParser; use PHPStan\Testing\TypeInferenceTestCase; class PDOResultRowCountReturnTypeTest extends TypeInferenceTestCase @@ -12,12 +10,7 @@ class PDOResultRowCountReturnTypeTest extends TypeInferenceTestCase /** @return iterable */ public function dataFileAsserts(): iterable { - $versionParser = new VersionParser(); - if (InstalledVersions::satisfies($versionParser, 'doctrine/dbal', '<3')) { - yield from $this->gatherAssertTypes(__DIR__ . '/data/pdo-result-row-count-dbal-2.php'); - } else { - yield from $this->gatherAssertTypes(__DIR__ . '/data/pdo-result-row-count.php'); - } + yield from $this->gatherAssertTypes(__DIR__ . '/data/pdo-result-row-count.php'); } /** diff --git a/tests/Type/Doctrine/DBAL/data/mysqli-result-row-count-dbal-2.php b/tests/Type/Doctrine/DBAL/data/mysqli-result-row-count-dbal-2.php deleted file mode 100644 index 235e6142..00000000 --- a/tests/Type/Doctrine/DBAL/data/mysqli-result-row-count-dbal-2.php +++ /dev/null @@ -1,15 +0,0 @@ -rowCount()); -}; - -function (DriverResult $r): void { - assertType('int|string', $r->rowCount()); -}; diff --git a/tests/Type/Doctrine/DBAL/data/pdo-result-row-count-dbal-2.php b/tests/Type/Doctrine/DBAL/data/pdo-result-row-count-dbal-2.php deleted file mode 100644 index ff6a8cf8..00000000 --- a/tests/Type/Doctrine/DBAL/data/pdo-result-row-count-dbal-2.php +++ /dev/null @@ -1,15 +0,0 @@ -rowCount()); -}; - -function (DriverResult $r): void { - assertType('int|string', $r->rowCount()); -}; From df300b9b2e61c4db6e5f8b760fe697991b15d390 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 14:55:04 +0200 Subject: [PATCH 03/39] Update build-cs --- .github/workflows/build.yml | 2 +- Makefile | 2 +- ...trineProxyForbiddenClassNamesExtension.php | 3 +- src/Doctrine/DoctrineDiagnoseExtension.php | 10 +-- src/Doctrine/Mapping/ClassMetadataFactory.php | 3 +- src/Doctrine/Mapping/MappingDriverChain.php | 2 +- ...LiteralStringTypeNodeResolverExtension.php | 3 +- .../QueryTypeNodeResolverExtension.php | 5 +- ...rineSelectableClassReflectionExtension.php | 3 +- src/Reflection/Doctrine/DummyParameter.php | 18 ++-- ...tityRepositoryClassReflectionExtension.php | 3 +- .../MagicRepositoryMethodReflection.php | 11 +-- src/Rules/Doctrine/ORM/DqlRule.php | 3 +- src/Rules/Doctrine/ORM/EntityColumnRule.php | 36 ++++---- .../ORM/EntityConstructorNotFinalRule.php | 5 +- .../ORM/EntityMappingExceptionRule.php | 3 +- src/Rules/Doctrine/ORM/EntityNotFinalRule.php | 5 +- src/Rules/Doctrine/ORM/EntityRelationRule.php | 19 ++--- .../Doctrine/ORM/PropertiesExtension.php | 3 +- .../Doctrine/ORM/QueryBuilderDqlRule.php | 6 +- .../Doctrine/ORM/RepositoryMethodCallRule.php | 5 +- src/Rules/Gedmo/PropertiesExtension.php | 6 +- .../Doctrine/StubFilesExtensionLoader.php | 3 +- src/Type/Doctrine/ArgumentsProcessor.php | 3 +- .../IsEmptyTypeSpecifyingExtension.php | 9 +- .../CreateQueryDynamicReturnTypeExtension.php | 16 ++-- .../QueryBuilderExecuteMethodExtension.php | 3 +- ...wCountMethodDynamicReturnTypeExtension.php | 12 +-- .../Doctrine/DefaultDescriptorRegistry.php | 2 +- .../Doctrine/DescriptorRegistryFactory.php | 3 +- src/Type/Doctrine/Descriptors/BooleanType.php | 7 +- src/Type/Doctrine/Descriptors/DecimalType.php | 3 +- src/Type/Doctrine/Descriptors/FloatType.php | 5 +- .../Descriptors/Ramsey/UuidTypeDescriptor.php | 7 +- .../Descriptors/ReflectionDescriptor.php | 6 +- ...tityManagerInterfaceThrowTypeExtension.php | 4 +- ...etRepositoryDynamicReturnTypeExtension.php | 26 +++--- .../HydrationModeReturnTypeResolver.php | 6 +- src/Type/Doctrine/ObjectMetadataResolver.php | 13 ++- .../QueryResultDynamicReturnTypeExtension.php | 10 +-- .../Doctrine/Query/QueryResultTypeBuilder.php | 17 ++-- .../Doctrine/Query/QueryResultTypeWalker.php | 70 +++++++--------- src/Type/Doctrine/Query/QueryType.php | 9 +- ...QueryBuilderDynamicReturnTypeExtension.php | 8 +- ...seExpressionDynamicReturnTypeExtension.php | 3 +- .../Doctrine/QueryBuilder/Expr/ExprType.php | 3 +- ...ssionBuilderDynamicReturnTypeExtension.php | 6 +- .../NewExprDynamicReturnTypeExtension.php | 13 ++- .../OtherMethodQueryBuilderParser.php | 11 +-- ...uilderGetDqlDynamicReturnTypeExtension.php | 5 +- ...lderGetQueryDynamicReturnTypeExtension.php | 18 ++-- ...uilderMethodDynamicReturnTypeExtension.php | 5 +- .../QueryBuilder/QueryBuilderType.php | 2 +- .../QueryBuilderTypeSpecifyingExtension.php | 10 +-- ...BuilderExpressionTypeResolverExtension.php | 3 +- ...eProxyForbiddenClassNamesExtensionTest.php | 2 +- tests/Classes/entity-manager.php | 8 +- .../ODM/document-manager.php | 6 +- .../ORM/entity-manager.php | 6 +- tests/Platform/Entity/PlatformEntity.php | 83 ++++++------------- .../Platform/Entity/PlatformRelatedEntity.php | 3 +- ...eryResultTypeWalkerFetchTypeMatrixTest.php | 48 +++++------ ...SelectableClassReflectionExtensionTest.php | 6 +- tests/Rules/DeadCode/entity-manager.php | 6 +- .../Doctrine/ORM/EntityColumnRuleTest.php | 8 +- .../ORM/EntityConstructorNotFinalRuleTest.php | 5 +- .../ORM/EntityMappingExceptionRuleTest.php | 2 +- .../Doctrine/ORM/EntityNotFinalRuleTest.php | 5 +- .../Doctrine/ORM/EntityRelationRuleTest.php | 8 +- .../ORM/QueryBuilderDqlRuleSlowTest.php | 2 +- .../Doctrine/ORM/QueryBuilderDqlRuleTest.php | 2 +- tests/Rules/Doctrine/ORM/entity-manager.php | 8 +- tests/Rules/Properties/entity-manager.php | 6 +- tests/Type/Doctrine/DBAL/mysqli.php | 4 +- tests/Type/Doctrine/DBAL/pdo.php | 4 +- ...lectableDynamicReturnTypeExtensionTest.php | 9 +- ...QueryResultTypeWalkerHydrationModeTest.php | 10 +-- .../Query/QueryResultTypeWalkerTest.php | 60 +++++++------- 78 files changed, 311 insertions(+), 467 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ebed3920..3230e295 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,7 +63,7 @@ jobs: with: repository: "phpstan/build-cs" path: "build-cs" - ref: "1.x" + ref: "2.x" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/Makefile b/Makefile index c62886f9..efc169db 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ lint: .PHONY: cs-install cs-install: git clone https://github.com/phpstan/build-cs.git || true - git -C build-cs fetch origin && git -C build-cs reset --hard origin/1.x + git -C build-cs fetch origin && git -C build-cs reset --hard origin/2.x composer install --working-dir build-cs .PHONY: cs diff --git a/src/Classes/DoctrineProxyForbiddenClassNamesExtension.php b/src/Classes/DoctrineProxyForbiddenClassNamesExtension.php index 1ff7f4f6..dbca26af 100644 --- a/src/Classes/DoctrineProxyForbiddenClassNamesExtension.php +++ b/src/Classes/DoctrineProxyForbiddenClassNamesExtension.php @@ -8,8 +8,7 @@ class DoctrineProxyForbiddenClassNamesExtension implements ForbiddenClassNameExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Doctrine/DoctrineDiagnoseExtension.php b/src/Doctrine/DoctrineDiagnoseExtension.php index 58fda398..0502c736 100644 --- a/src/Doctrine/DoctrineDiagnoseExtension.php +++ b/src/Doctrine/DoctrineDiagnoseExtension.php @@ -15,11 +15,9 @@ class DoctrineDiagnoseExtension implements DiagnoseExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct( ObjectMetadataResolver $objectMetadataResolver, @@ -34,7 +32,7 @@ public function print(Output $output): void { $output->writeLineFormatted(sprintf( 'Doctrine\'s objectManagerLoader: %s', - $this->objectMetadataResolver->hasObjectManagerLoader() ? 'In use' : 'No' + $this->objectMetadataResolver->hasObjectManagerLoader() ? 'In use' : 'No', )); $objectManager = $this->objectMetadataResolver->getObjectManager(); @@ -44,7 +42,7 @@ public function print(Output $output): void $output->writeLineFormatted(sprintf( 'Detected driver: %s', - $driver === null ? 'None' : $driver + $driver === null ? 'None' : $driver, )); } diff --git a/src/Doctrine/Mapping/ClassMetadataFactory.php b/src/Doctrine/Mapping/ClassMetadataFactory.php index b2f82388..764268f1 100644 --- a/src/Doctrine/Mapping/ClassMetadataFactory.php +++ b/src/Doctrine/Mapping/ClassMetadataFactory.php @@ -18,8 +18,7 @@ class ClassMetadataFactory extends \Doctrine\ORM\Mapping\ClassMetadataFactory { - /** @var string */ - private $tmpDir; + private string $tmpDir; public function __construct(string $tmpDir) { diff --git a/src/Doctrine/Mapping/MappingDriverChain.php b/src/Doctrine/Mapping/MappingDriverChain.php index ebcdc423..532b208b 100644 --- a/src/Doctrine/Mapping/MappingDriverChain.php +++ b/src/Doctrine/Mapping/MappingDriverChain.php @@ -11,7 +11,7 @@ class MappingDriverChain implements MappingDriver { /** @var MappingDriver[] */ - private $drivers; + private array $drivers; /** * @param MappingDriver[] $drivers diff --git a/src/PhpDoc/Doctrine/DoctrineLiteralStringTypeNodeResolverExtension.php b/src/PhpDoc/Doctrine/DoctrineLiteralStringTypeNodeResolverExtension.php index 3aa371d5..b034f57a 100644 --- a/src/PhpDoc/Doctrine/DoctrineLiteralStringTypeNodeResolverExtension.php +++ b/src/PhpDoc/Doctrine/DoctrineLiteralStringTypeNodeResolverExtension.php @@ -14,8 +14,7 @@ class DoctrineLiteralStringTypeNodeResolverExtension implements TypeNodeResolverExtension { - /** @var bool */ - private $enabled; + private bool $enabled; public function __construct(bool $enabled) { diff --git a/src/PhpDoc/Doctrine/QueryTypeNodeResolverExtension.php b/src/PhpDoc/Doctrine/QueryTypeNodeResolverExtension.php index 39cd65d9..c8193892 100644 --- a/src/PhpDoc/Doctrine/QueryTypeNodeResolverExtension.php +++ b/src/PhpDoc/Doctrine/QueryTypeNodeResolverExtension.php @@ -18,8 +18,7 @@ class QueryTypeNodeResolverExtension implements TypeNodeResolverExtension, TypeNodeResolverAwareExtension { - /** @var TypeNodeResolver */ - private $typeNodeResolver; + private TypeNodeResolver $typeNodeResolver; public function setTypeNodeResolver(TypeNodeResolver $typeNodeResolver): void { @@ -47,7 +46,7 @@ public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type [ new NullType(), $this->typeNodeResolver->resolve($typeNode->genericTypes[0], $nameScope), - ] + ], ); } diff --git a/src/Reflection/Doctrine/DoctrineSelectableClassReflectionExtension.php b/src/Reflection/Doctrine/DoctrineSelectableClassReflectionExtension.php index 16970a60..ca726d8c 100644 --- a/src/Reflection/Doctrine/DoctrineSelectableClassReflectionExtension.php +++ b/src/Reflection/Doctrine/DoctrineSelectableClassReflectionExtension.php @@ -10,8 +10,7 @@ class DoctrineSelectableClassReflectionExtension implements MethodsClassReflectionExtension { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { diff --git a/src/Reflection/Doctrine/DummyParameter.php b/src/Reflection/Doctrine/DummyParameter.php index 725f29f6..00eefa2c 100644 --- a/src/Reflection/Doctrine/DummyParameter.php +++ b/src/Reflection/Doctrine/DummyParameter.php @@ -9,23 +9,17 @@ class DummyParameter implements ParameterReflection { - /** @var string */ - private $name; + private string $name; - /** @var Type */ - private $type; + private Type $type; - /** @var bool */ - private $optional; + private bool $optional; - /** @var PassedByReference */ - private $passedByReference; + private PassedByReference $passedByReference; - /** @var bool */ - private $variadic; + private bool $variadic; - /** @var Type|null */ - private $defaultValue; + private ?Type $defaultValue = null; public function __construct(string $name, Type $type, bool $optional, ?PassedByReference $passedByReference, bool $variadic, ?Type $defaultValue) { diff --git a/src/Reflection/Doctrine/EntityRepositoryClassReflectionExtension.php b/src/Reflection/Doctrine/EntityRepositoryClassReflectionExtension.php index 799349da..52a8dcff 100644 --- a/src/Reflection/Doctrine/EntityRepositoryClassReflectionExtension.php +++ b/src/Reflection/Doctrine/EntityRepositoryClassReflectionExtension.php @@ -22,8 +22,7 @@ class EntityRepositoryClassReflectionExtension implements MethodsClassReflectionExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Reflection/Doctrine/MagicRepositoryMethodReflection.php b/src/Reflection/Doctrine/MagicRepositoryMethodReflection.php index 125f1440..94dc6011 100644 --- a/src/Reflection/Doctrine/MagicRepositoryMethodReflection.php +++ b/src/Reflection/Doctrine/MagicRepositoryMethodReflection.php @@ -21,14 +21,11 @@ class MagicRepositoryMethodReflection implements MethodReflection { - /** @var ClassReflection */ - private $declaringClass; + private ClassReflection $declaringClass; - /** @var string */ - private $name; + private string $name; - /** @var Type */ - private $type; + private Type $type; public function __construct( ClassReflection $declaringClass, @@ -104,7 +101,7 @@ public function getVariants(): array null, $arguments, false, - $this->type + $this->type, ), ]; } diff --git a/src/Rules/Doctrine/ORM/DqlRule.php b/src/Rules/Doctrine/ORM/DqlRule.php index 7a121525..77cd3664 100644 --- a/src/Rules/Doctrine/ORM/DqlRule.php +++ b/src/Rules/Doctrine/ORM/DqlRule.php @@ -21,8 +21,7 @@ class DqlRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Rules/Doctrine/ORM/EntityColumnRule.php b/src/Rules/Doctrine/ORM/EntityColumnRule.php index 70c1fcea..c2ee7a15 100644 --- a/src/Rules/Doctrine/ORM/EntityColumnRule.php +++ b/src/Rules/Doctrine/ORM/EntityColumnRule.php @@ -34,23 +34,17 @@ class EntityColumnRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var DescriptorRegistry */ - private $descriptorRegistry; + private DescriptorRegistry $descriptorRegistry; - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; - /** @var bool */ - private $reportUnknownTypes; + private bool $reportUnknownTypes; - /** @var bool */ - private $allowNullablePropertyForRequiredField; + private bool $allowNullablePropertyForRequiredField; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct( ObjectMetadataResolver $objectMetadataResolver, @@ -106,7 +100,7 @@ public function processNode(Node $node, Scope $scope): array 'Property %s::$%s: Doctrine type "%s" does not have any registered descriptor.', $className, $propertyName, - $fieldMapping['type'] + $fieldMapping['type'], ))->identifier('doctrine.descriptorNotFound')->build(), ] : []; } @@ -128,7 +122,7 @@ public function processNode(Node $node, Scope $scope): array $propertyName, $backedEnumType->describe(VerbosityLevel::typeOnly()), $enumReflection->getDisplayName(), - $writableToDatabaseType->describe(VerbosityLevel::typeOnly()) + $writableToDatabaseType->describe(VerbosityLevel::typeOnly()), ))->identifier('doctrine.enumType')->build(); } } @@ -151,8 +145,8 @@ public function processNode(Node $node, Scope $scope): array $backedEnumType->describe(VerbosityLevel::typeOnly()), $enumReflection->getDisplayName(), $writableToDatabaseType->getIterableValueType()->describe(VerbosityLevel::typeOnly()), - $writableToDatabaseType->describe(VerbosityLevel::typeOnly()) - ) + $writableToDatabaseType->describe(VerbosityLevel::typeOnly()), + ), )->identifier('doctrine.enumType')->build(); } } @@ -160,11 +154,11 @@ public function processNode(Node $node, Scope $scope): array $writableToPropertyType = TypeCombinator::intersect(new ArrayType( $writableToPropertyType->getIterableKeyType(), - $enumType + $enumType, ), ...TypeUtils::getAccessoryTypes($writableToPropertyType)); $writableToDatabaseType = TypeCombinator::intersect(new ArrayType( $writableToDatabaseType->getIterableKeyType(), - $enumType + $enumType, ), ...TypeUtils::getAccessoryTypes($writableToDatabaseType)); } @@ -211,7 +205,7 @@ public function processNode(Node $node, Scope $scope): array $className, $propertyName, $writableToPropertyType->describe(VerbosityLevel::getRecommendedLevelByType($propertyTransformedType, $writableToPropertyType)), - $propertyType->describe(VerbosityLevel::getRecommendedLevelByType($propertyTransformedType, $writableToPropertyType)) + $propertyType->describe(VerbosityLevel::getRecommendedLevelByType($propertyTransformedType, $writableToPropertyType)), ))->identifier('doctrine.columnType')->build(); } @@ -219,7 +213,7 @@ public function processNode(Node $node, Scope $scope): array !$writableToDatabaseType->isSuperTypeOf( $this->allowNullablePropertyForRequiredField || (in_array($propertyName, $identifiers, true) && !$nullable) ? TypeCombinator::removeNull($propertyType) - : $propertyType + : $propertyType, )->yes() ) { $errors[] = RuleErrorBuilder::message(sprintf( @@ -227,7 +221,7 @@ public function processNode(Node $node, Scope $scope): array $className, $propertyName, $propertyTransformedType->describe(VerbosityLevel::getRecommendedLevelByType($writableToDatabaseType, $propertyType)), - $writableToDatabaseType->describe(VerbosityLevel::getRecommendedLevelByType($writableToDatabaseType, $propertyType)) + $writableToDatabaseType->describe(VerbosityLevel::getRecommendedLevelByType($writableToDatabaseType, $propertyType)), ))->identifier('doctrine.columnType')->build(); } return $errors; diff --git a/src/Rules/Doctrine/ORM/EntityConstructorNotFinalRule.php b/src/Rules/Doctrine/ORM/EntityConstructorNotFinalRule.php index 5fd01213..24876b38 100644 --- a/src/Rules/Doctrine/ORM/EntityConstructorNotFinalRule.php +++ b/src/Rules/Doctrine/ORM/EntityConstructorNotFinalRule.php @@ -17,8 +17,7 @@ class EntityConstructorNotFinalRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { @@ -57,7 +56,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Constructor of class %s is final which can cause problems with proxies.', - $classReflection->getDisplayName() + $classReflection->getDisplayName(), ))->identifier('doctrine.finalConstructor')->build(), ]; } diff --git a/src/Rules/Doctrine/ORM/EntityMappingExceptionRule.php b/src/Rules/Doctrine/ORM/EntityMappingExceptionRule.php index d74019ba..d0ce97f7 100644 --- a/src/Rules/Doctrine/ORM/EntityMappingExceptionRule.php +++ b/src/Rules/Doctrine/ORM/EntityMappingExceptionRule.php @@ -18,8 +18,7 @@ class EntityMappingExceptionRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct( ObjectMetadataResolver $objectMetadataResolver diff --git a/src/Rules/Doctrine/ORM/EntityNotFinalRule.php b/src/Rules/Doctrine/ORM/EntityNotFinalRule.php index b4dfe4c7..9dd39ff3 100644 --- a/src/Rules/Doctrine/ORM/EntityNotFinalRule.php +++ b/src/Rules/Doctrine/ORM/EntityNotFinalRule.php @@ -17,8 +17,7 @@ class EntityNotFinalRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { @@ -52,7 +51,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Entity class %s is final which can cause problems with proxies.', - $classReflection->getDisplayName() + $classReflection->getDisplayName(), ))->identifier('doctrine.finalEntity')->build(), ]; } diff --git a/src/Rules/Doctrine/ORM/EntityRelationRule.php b/src/Rules/Doctrine/ORM/EntityRelationRule.php index 69e0c2a5..97e3ae2f 100644 --- a/src/Rules/Doctrine/ORM/EntityRelationRule.php +++ b/src/Rules/Doctrine/ORM/EntityRelationRule.php @@ -28,14 +28,11 @@ class EntityRelationRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var bool */ - private $allowNullablePropertyForRequiredField; + private bool $allowNullablePropertyForRequiredField; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct( ObjectMetadataResolver $objectMetadataResolver, @@ -102,7 +99,7 @@ public function processNode(Node $node, Scope $scope): array $toMany = true; $columnType = TypeCombinator::intersect( new ObjectType('Doctrine\Common\Collections\Collection'), - new IterableType(new MixedType(), new ObjectType($associationMapping['targetEntity'])) + new IterableType(new MixedType(), new ObjectType($associationMapping['targetEntity'])), ); } @@ -125,7 +122,7 @@ public function processNode(Node $node, Scope $scope): array ) { $propertyTypeToCheckAgainst = TypeCombinator::intersect( $collectionObjectType, - new IterableType(new MixedType(true), $propertyType->getIterableValueType()) + new IterableType(new MixedType(true), $propertyType->getIterableValueType()), ); } if (!$propertyTypeToCheckAgainst->isSuperTypeOf($columnType)->yes()) { @@ -134,14 +131,14 @@ public function processNode(Node $node, Scope $scope): array $className, $propertyName, $columnType->describe(VerbosityLevel::typeOnly()), - $propertyType->describe(VerbosityLevel::typeOnly()) + $propertyType->describe(VerbosityLevel::typeOnly()), ))->identifier('doctrine.associationType')->build(); } if ( !$columnType->isSuperTypeOf( $this->allowNullablePropertyForRequiredField ? TypeCombinator::removeNull($propertyType) - : $propertyType + : $propertyType, )->yes() ) { $errors[] = RuleErrorBuilder::message(sprintf( @@ -149,7 +146,7 @@ public function processNode(Node $node, Scope $scope): array $className, $propertyName, $propertyType->describe(VerbosityLevel::typeOnly()), - $columnType->describe(VerbosityLevel::typeOnly()) + $columnType->describe(VerbosityLevel::typeOnly()), ))->identifier('doctrine.associationType')->build(); } } diff --git a/src/Rules/Doctrine/ORM/PropertiesExtension.php b/src/Rules/Doctrine/ORM/PropertiesExtension.php index 4fdbf57d..9eab7dd7 100644 --- a/src/Rules/Doctrine/ORM/PropertiesExtension.php +++ b/src/Rules/Doctrine/ORM/PropertiesExtension.php @@ -12,8 +12,7 @@ class PropertiesExtension implements ReadWritePropertiesExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php b/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php index 8596810d..62155d01 100644 --- a/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php +++ b/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php @@ -26,11 +26,9 @@ class QueryBuilderDqlRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var bool */ - private $reportDynamicQueryBuilders; + private bool $reportDynamicQueryBuilders; public function __construct( ObjectMetadataResolver $objectMetadataResolver, diff --git a/src/Rules/Doctrine/ORM/RepositoryMethodCallRule.php b/src/Rules/Doctrine/ORM/RepositoryMethodCallRule.php index 9061d6c4..9f5231fe 100644 --- a/src/Rules/Doctrine/ORM/RepositoryMethodCallRule.php +++ b/src/Rules/Doctrine/ORM/RepositoryMethodCallRule.php @@ -19,8 +19,7 @@ class RepositoryMethodCallRule implements Rule { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { @@ -82,7 +81,7 @@ public function processNode(Node $node, Scope $scope): array $calledOnType->describe(VerbosityLevel::typeOnly()), $methodName, $entityClassNames[0], - $fieldName->getValue() + $fieldName->getValue(), ))->identifier(sprintf('doctrine.%sArgument', $methodName))->build(); } } diff --git a/src/Rules/Gedmo/PropertiesExtension.php b/src/Rules/Gedmo/PropertiesExtension.php index d43b4308..e82f3bc5 100644 --- a/src/Rules/Gedmo/PropertiesExtension.php +++ b/src/Rules/Gedmo/PropertiesExtension.php @@ -41,11 +41,9 @@ class PropertiesExtension implements ReadWritePropertiesExtension Gedmo\Language::class, ]; - /** @var AnnotationReader|null */ - private $annotationReader; + private ?AnnotationReader $annotationReader = null; - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Stubs/Doctrine/StubFilesExtensionLoader.php b/src/Stubs/Doctrine/StubFilesExtensionLoader.php index 0b3a69d8..cb93222d 100644 --- a/src/Stubs/Doctrine/StubFilesExtensionLoader.php +++ b/src/Stubs/Doctrine/StubFilesExtensionLoader.php @@ -14,8 +14,7 @@ class StubFilesExtensionLoader implements StubFilesExtension { - /** @var Reflector */ - private $reflector; + private Reflector $reflector; public function __construct( Reflector $reflector diff --git a/src/Type/Doctrine/ArgumentsProcessor.php b/src/Type/Doctrine/ArgumentsProcessor.php index 4ace7f16..77eeb5d7 100644 --- a/src/Type/Doctrine/ArgumentsProcessor.php +++ b/src/Type/Doctrine/ArgumentsProcessor.php @@ -13,8 +13,7 @@ class ArgumentsProcessor { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; public function __construct(ObjectMetadataResolver $objectMetadataResolver) { diff --git a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php index 0d440940..d94a455a 100644 --- a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php @@ -19,11 +19,10 @@ final class IsEmptyTypeSpecifyingExtension implements MethodTypeSpecifyingExtens private const FIRST_METHOD_NAME = 'first'; private const LAST_METHOD_NAME = 'last'; - /** @var TypeSpecifier */ - private $typeSpecifier; + private TypeSpecifier $typeSpecifier; /** @var class-string */ - private $collectionClass; + private string $collectionClass; /** * @param class-string $collectionClass @@ -61,13 +60,13 @@ public function specifyTypes( $first = $this->typeSpecifier->create( new MethodCall($node->var, self::FIRST_METHOD_NAME), new ConstantBooleanType(false), - $context + $context, ); $last = $this->typeSpecifier->create( new MethodCall($node->var, self::LAST_METHOD_NAME), new ConstantBooleanType(false), - $context + $context, ); return $first->unionWith($last); diff --git a/src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php b/src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php index 1cf5d50a..b78f8467 100644 --- a/src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php @@ -33,17 +33,13 @@ final class CreateQueryDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var DescriptorRegistry */ - private $descriptorRegistry; + private DescriptorRegistry $descriptorRegistry; - /** @var PhpVersion */ - private $phpVersion; + private PhpVersion $phpVersion; - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct( ObjectMetadataResolver $objectMetadataResolver, @@ -80,7 +76,7 @@ public function getTypeFromMethodCall( if (!isset($args[$queryStringArgIndex])) { return new GenericObjectType( Query::class, - [new MixedType(), new MixedType()] + [new MixedType(), new MixedType()], ); } @@ -113,7 +109,7 @@ public function getTypeFromMethodCall( } return new GenericObjectType( Query::class, - [new MixedType(), new MixedType()] + [new MixedType(), new MixedType()], ); }); } diff --git a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php index 31170cfc..a997c2da 100644 --- a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php +++ b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php @@ -19,8 +19,7 @@ class QueryBuilderExecuteMethodExtension implements DynamicMethodReturnTypeExtension { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { diff --git a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php index 8fe17348..03a988e1 100644 --- a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php @@ -17,17 +17,13 @@ class RowCountMethodDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var string */ - private $class; + private string $class; - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; public function __construct( string $class, diff --git a/src/Type/Doctrine/DefaultDescriptorRegistry.php b/src/Type/Doctrine/DefaultDescriptorRegistry.php index 83647e3b..74ea184d 100644 --- a/src/Type/Doctrine/DefaultDescriptorRegistry.php +++ b/src/Type/Doctrine/DefaultDescriptorRegistry.php @@ -9,7 +9,7 @@ class DefaultDescriptorRegistry implements DescriptorRegistry { /** @var array, DoctrineTypeDescriptor> */ - private $descriptors = []; + private array $descriptors = []; /** * @param DoctrineTypeDescriptor[] $descriptors diff --git a/src/Type/Doctrine/DescriptorRegistryFactory.php b/src/Type/Doctrine/DescriptorRegistryFactory.php index 3e7dd190..2dbf70aa 100644 --- a/src/Type/Doctrine/DescriptorRegistryFactory.php +++ b/src/Type/Doctrine/DescriptorRegistryFactory.php @@ -9,8 +9,7 @@ class DescriptorRegistryFactory public const TYPE_DESCRIPTOR_TAG = 'phpstan.doctrine.typeDescriptor'; - /** @var Container */ - private $container; + private Container $container; public function __construct(Container $container) { diff --git a/src/Type/Doctrine/Descriptors/BooleanType.php b/src/Type/Doctrine/Descriptors/BooleanType.php index b9e59574..54e7f662 100644 --- a/src/Type/Doctrine/Descriptors/BooleanType.php +++ b/src/Type/Doctrine/Descriptors/BooleanType.php @@ -12,8 +12,7 @@ class BooleanType implements DoctrineTypeDescriptor, DoctrineTypeDriverAwareDescriptor { - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct(DriverDetector $driverDetector) { @@ -40,7 +39,7 @@ public function getDatabaseInternalType(): Type return TypeCombinator::union( new ConstantIntegerType(0), new ConstantIntegerType(1), - new \PHPStan\Type\BooleanType() + new \PHPStan\Type\BooleanType(), ); } @@ -60,7 +59,7 @@ public function getDatabaseInternalTypeForDriver(Connection $connection): Type ], true)) { return TypeCombinator::union( new ConstantIntegerType(0), - new ConstantIntegerType(1) + new ConstantIntegerType(1), ); } diff --git a/src/Type/Doctrine/Descriptors/DecimalType.php b/src/Type/Doctrine/Descriptors/DecimalType.php index 64184c45..08773fdc 100644 --- a/src/Type/Doctrine/Descriptors/DecimalType.php +++ b/src/Type/Doctrine/Descriptors/DecimalType.php @@ -16,8 +16,7 @@ class DecimalType implements DoctrineTypeDescriptor, DoctrineTypeDriverAwareDescriptor { - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct(DriverDetector $driverDetector) { diff --git a/src/Type/Doctrine/Descriptors/FloatType.php b/src/Type/Doctrine/Descriptors/FloatType.php index 2518e72d..f435293b 100644 --- a/src/Type/Doctrine/Descriptors/FloatType.php +++ b/src/Type/Doctrine/Descriptors/FloatType.php @@ -15,8 +15,7 @@ class FloatType implements DoctrineTypeDescriptor, DoctrineTypeDriverAwareDescriptor { - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct(DriverDetector $driverDetector) { @@ -45,7 +44,7 @@ public function getDatabaseInternalType(): Type new IntersectionType([ new StringType(), new AccessoryNumericStringType(), - ]) + ]), ); } diff --git a/src/Type/Doctrine/Descriptors/Ramsey/UuidTypeDescriptor.php b/src/Type/Doctrine/Descriptors/Ramsey/UuidTypeDescriptor.php index 78501f2c..549b14c4 100644 --- a/src/Type/Doctrine/Descriptors/Ramsey/UuidTypeDescriptor.php +++ b/src/Type/Doctrine/Descriptors/Ramsey/UuidTypeDescriptor.php @@ -23,8 +23,7 @@ class UuidTypeDescriptor implements DoctrineTypeDescriptor FakeTestingUuidType::class, ]; - /** @var string */ - private $uuidTypeName; + private string $uuidTypeName; public function __construct( string $uuidTypeName @@ -33,7 +32,7 @@ public function __construct( if (!in_array($uuidTypeName, self::SUPPORTED_UUID_TYPES, true)) { throw new ShouldNotHappenException(sprintf( 'Unexpected UUID column type "%s" provided', - $uuidTypeName + $uuidTypeName, )); } @@ -55,7 +54,7 @@ public function getWritableToDatabaseType(): Type { return TypeCombinator::union( new StringType(), - new ObjectType(UuidInterface::class) + new ObjectType(UuidInterface::class), ); } diff --git a/src/Type/Doctrine/Descriptors/ReflectionDescriptor.php b/src/Type/Doctrine/Descriptors/ReflectionDescriptor.php index 7d7cb778..f4b5dba0 100644 --- a/src/Type/Doctrine/Descriptors/ReflectionDescriptor.php +++ b/src/Type/Doctrine/Descriptors/ReflectionDescriptor.php @@ -21,11 +21,9 @@ class ReflectionDescriptor implements DoctrineTypeDescriptor, DoctrineTypeDriver /** @var class-string */ private $type; - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; - /** @var Container */ - private $container; + private Container $container; /** * @param class-string $type diff --git a/src/Type/Doctrine/EntityManagerInterfaceThrowTypeExtension.php b/src/Type/Doctrine/EntityManagerInterfaceThrowTypeExtension.php index 0070af9f..be3407c3 100644 --- a/src/Type/Doctrine/EntityManagerInterfaceThrowTypeExtension.php +++ b/src/Type/Doctrine/EntityManagerInterfaceThrowTypeExtension.php @@ -37,9 +37,7 @@ public function getThrowTypeFromMethodCall(MethodReflection $methodReflection, M if ((new ObjectType(EntityManagerInterface::class))->isSuperTypeOf($type)->yes()) { return TypeCombinator::union( - ...array_map(static function ($class): Type { - return new ObjectType($class); - }, self::SUPPORTED_METHOD[$methodReflection->getName()]) + ...array_map(static fn ($class): Type => new ObjectType($class), self::SUPPORTED_METHOD[$methodReflection->getName()]), ); } diff --git a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php index fd90fdd5..d514a12b 100644 --- a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php @@ -27,23 +27,17 @@ class GetRepositoryDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; - /** @var string|null */ - private $repositoryClass; + private ?string $repositoryClass = null; - /** @var string|null */ - private $ormRepositoryClass; + private ?string $ormRepositoryClass = null; - /** @var string|null */ - private $odmRepositoryClass; + private ?string $odmRepositoryClass = null; - /** @var string */ - private $managerClass; + private string $managerClass; - /** @var ObjectMetadataResolver */ - private $metadataResolver; + private ObjectMetadataResolver $metadataResolver; public function __construct( ReflectionProvider $reflectionProvider, @@ -87,7 +81,7 @@ public function getTypeFromMethodCall( if (count($methodCall->getArgs()) === 0) { return new GenericObjectType( $defaultRepositoryClass, - [new ObjectWithoutClassType()] + [new ObjectWithoutClassType()], ); } $argType = $scope->getType($methodCall->getArgs()[0]->value); @@ -101,7 +95,7 @@ public function getTypeFromMethodCall( if (count($objectNames) === 0) { return new GenericObjectType( $defaultRepositoryClass, - [$classType] + [$classType], ); } @@ -127,13 +121,13 @@ private function getDefaultReturnType(Scope $scope, array $args, MethodReflectio $defaultType = ParametersAcceptorSelector::selectFromArgs( $scope, $args, - $methodReflection->getVariants() + $methodReflection->getVariants(), )->getReturnType(); $entity = $defaultType->getTemplateType(ObjectRepository::class, 'TEntityClass'); if (!$entity instanceof ErrorType) { return new GenericObjectType( $defaultRepositoryClass, - [$entity] + [$entity], ); } diff --git a/src/Type/Doctrine/HydrationModeReturnTypeResolver.php b/src/Type/Doctrine/HydrationModeReturnTypeResolver.php index 2f1c8e36..c0522e7f 100644 --- a/src/Type/Doctrine/HydrationModeReturnTypeResolver.php +++ b/src/Type/Doctrine/HydrationModeReturnTypeResolver.php @@ -73,18 +73,18 @@ public function getMethodReturnTypeForHydrationMode( case 'toIterable': return new IterableType( $queryKeyType->isNull()->yes() ? new IntegerType() : $queryKeyType, - $queryResultType + $queryResultType, ); default: if ($queryKeyType->isNull()->yes()) { return AccessoryArrayListType::intersectWith(new ArrayType( new IntegerType(), - $queryResultType + $queryResultType, )); } return new ArrayType( $queryKeyType, - $queryResultType + $queryResultType, ); } } diff --git a/src/Type/Doctrine/ObjectMetadataResolver.php b/src/Type/Doctrine/ObjectMetadataResolver.php index 6a8b4fd2..e1d97106 100644 --- a/src/Type/Doctrine/ObjectMetadataResolver.php +++ b/src/Type/Doctrine/ObjectMetadataResolver.php @@ -17,17 +17,14 @@ final class ObjectMetadataResolver { - /** @var string|null */ - private $objectManagerLoader; + private ?string $objectManagerLoader = null; /** @var ObjectManager|false|null */ private $objectManager; - /** @var ClassMetadataFactory|null */ - private $metadataFactory; + private ?ClassMetadataFactory $metadataFactory = null; - /** @var string */ - private $tmpDir; + private string $tmpDir; public function __construct( ?string $objectManagerLoader, @@ -150,14 +147,14 @@ private function loadObjectManager(string $objectManagerLoader): ?ObjectManager if (!is_file($objectManagerLoader)) { throw new ShouldNotHappenException(sprintf( 'Object manager could not be loaded: file "%s" does not exist', - $objectManagerLoader + $objectManagerLoader, )); } if (!is_readable($objectManagerLoader)) { throw new ShouldNotHappenException(sprintf( 'Object manager could not be loaded: file "%s" is not readable', - $objectManagerLoader + $objectManagerLoader, )); } diff --git a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php index 091e3716..24aecb38 100644 --- a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php @@ -27,11 +27,9 @@ final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturn 'getSingleResult' => 0, ]; - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var HydrationModeReturnTypeResolver */ - private $hydrationModeReturnTypeResolver; + private HydrationModeReturnTypeResolver $hydrationModeReturnTypeResolver; public function __construct( ObjectMetadataResolver $objectMetadataResolver, @@ -71,7 +69,7 @@ public function getTypeFromMethodCall( $hydrationMode = $scope->getType($args[$argIndex]->value); } else { $parametersAcceptor = ParametersAcceptorSelector::selectSingle( - $methodReflection->getVariants() + $methodReflection->getVariants(), ); $parameter = $parametersAcceptor->getParameters()[$argIndex]; $hydrationMode = $parameter->getDefaultValue() ?? new NullType(); @@ -84,7 +82,7 @@ public function getTypeFromMethodCall( $hydrationMode, $queryType->getTemplateType(AbstractQuery::class, 'TKey'), $queryType->getTemplateType(AbstractQuery::class, 'TResult'), - $this->objectMetadataResolver->getObjectManager() + $this->objectMetadataResolver->getObjectManager(), ); } diff --git a/src/Type/Doctrine/Query/QueryResultTypeBuilder.php b/src/Type/Doctrine/Query/QueryResultTypeBuilder.php index 30941cb3..2f6fae11 100644 --- a/src/Type/Doctrine/Query/QueryResultTypeBuilder.php +++ b/src/Type/Doctrine/Query/QueryResultTypeBuilder.php @@ -21,15 +21,13 @@ final class QueryResultTypeBuilder { - /** @var bool */ - private $selectQuery = false; + private bool $selectQuery = false; /** * Whether the result is an array shape or a single entity or NEW object * - * @var bool */ - private $isShape = false; + private bool $isShape = false; /** * Map from selected entity aliases to entity types @@ -38,7 +36,7 @@ final class QueryResultTypeBuilder * * @var array */ - private $entities = []; + private array $entities = []; /** * Map from selected entity alias to result alias @@ -47,24 +45,23 @@ final class QueryResultTypeBuilder * * @var array */ - private $entityResultAliases = []; + private array $entityResultAliases = []; /** * Map from selected scalar result alias to scalar type * * @var array */ - private $scalars = []; + private array $scalars = []; /** * Map from selected NEW objcet result alias to NEW object type * * @var array */ - private $newObjects = []; + private array $newObjects = []; - /** @var Type */ - private $indexedBy; + private Type $indexedBy; public function __construct() { diff --git a/src/Type/Doctrine/Query/QueryResultTypeWalker.php b/src/Type/Doctrine/Query/QueryResultTypeWalker.php index 4ef105d9..9e5c475f 100644 --- a/src/Type/Doctrine/Query/QueryResultTypeWalker.php +++ b/src/Type/Doctrine/Query/QueryResultTypeWalker.php @@ -84,53 +84,45 @@ class QueryResultTypeWalker extends SqlWalker /** * Counter for generating unique scalar result. * - * @var int */ - private $scalarResultCounter = 1; + private int $scalarResultCounter = 1; /** * Counter for generating indexes. * - * @var int */ - private $newObjectCounter = 0; + private int $newObjectCounter = 0; /** @var Query */ - private $query; + private Query $query; - /** @var EntityManagerInterface */ - private $em; + private EntityManagerInterface $em; - /** @var PhpVersion */ - private $phpVersion; + private PhpVersion $phpVersion; /** @var DriverDetector::*|null */ private $driverType; /** @var array */ - private $driverOptions; + private array $driverOptions; /** * Map of all components/classes that appear in the DQL query. * * @var array $queryComponents */ - private $queryComponents; + private array $queryComponents; /** @var array */ - private $nullableQueryComponents; + private array $nullableQueryComponents; - /** @var QueryResultTypeBuilder */ - private $typeBuilder; + private QueryResultTypeBuilder $typeBuilder; - /** @var DescriptorRegistry */ - private $descriptorRegistry; + private DescriptorRegistry $descriptorRegistry; - /** @var bool */ - private $hasAggregateFunction; + private bool $hasAggregateFunction; - /** @var bool */ - private $hasGroupByClause; + private bool $hasGroupByClause; /** @@ -182,7 +174,7 @@ public function __construct($query, $parserResult, array $queryComponents) 'Expected the query hint %s to contain a %s, but got a %s', self::HINT_TYPE_MAPPING, QueryResultTypeBuilder::class, - is_object($typeBuilder) ? get_class($typeBuilder) : gettype($typeBuilder) + is_object($typeBuilder) ? get_class($typeBuilder) : gettype($typeBuilder), )); } @@ -195,7 +187,7 @@ public function __construct($query, $parserResult, array $queryComponents) 'Expected the query hint %s to contain a %s, but got a %s', self::HINT_DESCRIPTOR_REGISTRY, DescriptorRegistry::class, - is_object($descriptorRegistry) ? get_class($descriptorRegistry) : gettype($descriptorRegistry) + is_object($descriptorRegistry) ? get_class($descriptorRegistry) : gettype($descriptorRegistry), )); } @@ -208,7 +200,7 @@ public function __construct($query, $parserResult, array $queryComponents) 'Expected the query hint %s to contain a %s, but got a %s', self::HINT_PHP_VERSION, PhpVersion::class, - is_object($phpVersion) ? get_class($phpVersion) : gettype($phpVersion) + is_object($phpVersion) ? get_class($phpVersion) : gettype($phpVersion), )); } @@ -221,7 +213,7 @@ public function __construct($query, $parserResult, array $queryComponents) 'Expected the query hint %s to contain a %s, but got a %s', self::HINT_DRIVER_DETECTOR, DriverDetector::class, - is_object($driverDetector) ? get_class($driverDetector) : gettype($driverDetector) + is_object($driverDetector) ? get_class($driverDetector) : gettype($driverDetector), )); } $connection = $this->em->getConnection(); @@ -818,7 +810,7 @@ private function inferSumFunction(AST\Functions\SumFunction $function): Type if ($exprTypeNoNull->isInteger()->yes()) { return TypeCombinator::union( $this->createInteger($nullable), - $this->createNumericString($nullable) + $this->createNumericString($nullable), ); } @@ -838,7 +830,7 @@ private function createFloatOrInt(bool $nullable): Type { $union = TypeCombinator::union( new FloatType(), - new IntegerType() + new IntegerType(), ); return $nullable ? TypeCombinator::addNull($union) : $union; } @@ -859,7 +851,7 @@ private function createNumericString(bool $nullable): Type { $numericString = TypeCombinator::intersect( new StringType(), - new AccessoryNumericStringType() + new AccessoryNumericStringType(), ); return $nullable ? TypeCombinator::addNull($numericString) : $numericString; @@ -1009,7 +1001,7 @@ public function walkCoalesceExpression($coalesceExpression): string if ($this->driverType === DriverDetector::MYSQLI || $this->driverType === DriverDetector::PDO_MYSQL) { return $this->marshalType( - $this->inferCoalesceForMySql($rawTypes, $generalizedUnion) + $this->inferCoalesceForMySql($rawTypes, $generalizedUnion), ); } @@ -1091,13 +1083,13 @@ public function walkGeneralCaseExpression(AST\GeneralCaseExpression $generalCase } $types[] = $this->unmarshalType( - $thenScalarExpression->dispatch($this) + $thenScalarExpression->dispatch($this), ); } if ($elseScalarExpression instanceof AST\Node) { $types[] = $this->unmarshalType( - $elseScalarExpression->dispatch($this) + $elseScalarExpression->dispatch($this), ); } @@ -1128,13 +1120,13 @@ public function walkSimpleCaseExpression($simpleCaseExpression): string } $types[] = $this->unmarshalType( - $thenScalarExpression->dispatch($this) + $thenScalarExpression->dispatch($this), ); } if ($elseScalarExpression instanceof AST\Node) { $types[] = $this->unmarshalType( - $elseScalarExpression->dispatch($this) + $elseScalarExpression->dispatch($this), ); } @@ -1225,7 +1217,7 @@ public function walkSelectExpression($selectExpression): string $dbalTypeName = DbalType::getTypeRegistry()->lookupName($expr->getReturnType()); $type = TypeCombinator::intersect( // e.g. count is typed as int, but we infer int<0, max> $type, - $this->resolveDoctrineType($dbalTypeName, null, TypeCombinator::containsNull($type)) + $this->resolveDoctrineType($dbalTypeName, null, TypeCombinator::containsNull($type)), ); if ($this->hasAggregateWithoutGroupBy() && !$expr instanceof AST\Functions\CountFunction) { @@ -1689,7 +1681,7 @@ public function walkSimpleArithmeticExpression($simpleArithmeticExpr): string } $types[] = $this->castStringLiteralForNumericExpression( - $this->unmarshalType($this->walkArithmeticPrimary($term)) + $this->unmarshalType($this->walkArithmeticPrimary($term)), ); } @@ -1716,7 +1708,7 @@ public function walkArithmeticTerm($term): string } $types[] = $this->castStringLiteralForNumericExpression( - $this->unmarshalType($this->walkArithmeticPrimary($factor)) + $this->unmarshalType($this->walkArithmeticPrimary($factor)), ); } @@ -1917,7 +1909,7 @@ public function walkArithmeticFactor($factor): string } elseif ($type instanceof IntegerRangeType && $factor->sign === false) { $type = IntegerRangeType::fromInterval( $type->getMax() === null ? null : $type->getMax() * -1, - $type->getMin() === null ? null : $type->getMin() * -1 + $type->getMin() === null ? null : $type->getMin() * -1, ); } elseif ($type instanceof ConstantFloatType && $factor->sign === false) { @@ -2022,7 +2014,7 @@ private function resolveDoctrineType(string $typeName, ?string $enumType = null, } else { $type = TypeCombinator::intersect(new ArrayType( $type->getIterableKeyType(), - new ObjectType($enumType) + new ObjectType($enumType), ), ...TypeUtils::getAccessoryTypes($type)); } } @@ -2058,9 +2050,7 @@ private function resolveDatabaseInternalType(string $typeName, ?string $enumType } if ($enumType !== null) { - $enumTypes = array_map(static function ($enumType) { - return ConstantTypeHelper::getTypeFromValue($enumType->value); - }, $enumType::cases()); + $enumTypes = array_map(static fn ($enumType) => ConstantTypeHelper::getTypeFromValue($enumType->value), $enumType::cases()); $enumType = TypeCombinator::union(...$enumTypes); $enumType = TypeCombinator::union($enumType, $enumType->toString()); $type = TypeCombinator::intersect($enumType, $type); diff --git a/src/Type/Doctrine/Query/QueryType.php b/src/Type/Doctrine/Query/QueryType.php index b0cb7968..ead7ef2b 100644 --- a/src/Type/Doctrine/Query/QueryType.php +++ b/src/Type/Doctrine/Query/QueryType.php @@ -11,14 +11,11 @@ class QueryType extends GenericObjectType { - /** @var Type */ - private $indexType; + private Type $indexType; - /** @var Type */ - private $resultType; + private Type $resultType; - /** @var string */ - private $dql; + private string $dql; public function __construct(string $dql, ?Type $indexType = null, ?Type $resultType = null, ?Type $subtractedType = null) { diff --git a/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php index 263f2284..8389395a 100644 --- a/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php @@ -11,11 +11,9 @@ class CreateQueryBuilderDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var string|null */ - private $queryBuilderClass; + private ?string $queryBuilderClass = null; - /** @var bool */ - private $fasterVersion; + private bool $fasterVersion; public function __construct( ?string $queryBuilderClass, @@ -48,7 +46,7 @@ public function getTypeFromMethodCall( } return new $class( - $this->queryBuilderClass ?? 'Doctrine\ORM\QueryBuilder' + $this->queryBuilderClass ?? 'Doctrine\ORM\QueryBuilder', ); } diff --git a/src/Type/Doctrine/QueryBuilder/Expr/BaseExpressionDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/Expr/BaseExpressionDynamicReturnTypeExtension.php index d797b45f..7dd9729e 100644 --- a/src/Type/Doctrine/QueryBuilder/Expr/BaseExpressionDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/Expr/BaseExpressionDynamicReturnTypeExtension.php @@ -17,8 +17,7 @@ class BaseExpressionDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var ArgumentsProcessor */ - private $argumentsProcessor; + private ArgumentsProcessor $argumentsProcessor; public function __construct( ArgumentsProcessor $argumentsProcessor diff --git a/src/Type/Doctrine/QueryBuilder/Expr/ExprType.php b/src/Type/Doctrine/QueryBuilder/Expr/ExprType.php index 00610d03..30a97a59 100644 --- a/src/Type/Doctrine/QueryBuilder/Expr/ExprType.php +++ b/src/Type/Doctrine/QueryBuilder/Expr/ExprType.php @@ -8,8 +8,7 @@ class ExprType extends ObjectType { - /** @var object */ - private $exprObject; + private object $exprObject; /** * @param object $exprObject diff --git a/src/Type/Doctrine/QueryBuilder/Expr/ExpressionBuilderDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/Expr/ExpressionBuilderDynamicReturnTypeExtension.php index fae7cd28..a6a6896a 100644 --- a/src/Type/Doctrine/QueryBuilder/Expr/ExpressionBuilderDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/Expr/ExpressionBuilderDynamicReturnTypeExtension.php @@ -18,11 +18,9 @@ class ExpressionBuilderDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var ArgumentsProcessor */ - private $argumentsProcessor; + private ArgumentsProcessor $argumentsProcessor; public function __construct( ObjectMetadataResolver $objectMetadataResolver, diff --git a/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php index 1690c63c..6f9a69c8 100644 --- a/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php @@ -18,14 +18,11 @@ class NewExprDynamicReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension { - /** @var ArgumentsProcessor */ - private $argumentsProcessor; + private ArgumentsProcessor $argumentsProcessor; - /** @var string */ - private $class; + private string $class; - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; public function __construct( ArgumentsProcessor $argumentsProcessor, @@ -68,8 +65,8 @@ public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, ...$this->argumentsProcessor->processArgs( $scope, $methodReflection->getName(), - $methodCall->getArgs() - ) + $methodCall->getArgs(), + ), ); } catch (DynamicQueryBuilderArgumentException $e) { return new ObjectType($this->reflectionProvider->getClassName($className)); diff --git a/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php b/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php index 4375c17a..cddd3a93 100644 --- a/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php +++ b/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php @@ -28,21 +28,18 @@ class OtherMethodQueryBuilderParser { - /** @var bool */ - private $descendIntoOtherMethods; + private bool $descendIntoOtherMethods; - /** @var Parser */ - private $parser; + private Parser $parser; - /** @var Container */ - private $container; + private Container $container; /** * Null if the method is currently being processed * * @var array|null> */ - private $cache = []; + private array $cache = []; public function __construct(bool $descendIntoOtherMethods, Parser $parser, Container $container) { diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php index 3b7dfb19..c6f4a5a7 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php @@ -13,8 +13,7 @@ class QueryBuilderGetDqlDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var string|null */ - private $queryBuilderClass; + private ?string $queryBuilderClass = null; public function __construct( ?string $queryBuilderClass @@ -41,7 +40,7 @@ public function getTypeFromMethodCall( { $type = $scope->getType(new MethodCall( new MethodCall($methodCall->var, new Identifier('getQuery')), - new Identifier('getDQL') + new Identifier('getDQL'), )); return TypeCombinator::removeNull($type); diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php index 366eaa60..b02018be 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php @@ -55,23 +55,17 @@ class QueryBuilderGetQueryDynamicReturnTypeExtension implements DynamicMethodRet 'orhaving', ]; - /** @var ObjectMetadataResolver */ - private $objectMetadataResolver; + private ObjectMetadataResolver $objectMetadataResolver; - /** @var ArgumentsProcessor */ - private $argumentsProcessor; + private ArgumentsProcessor $argumentsProcessor; - /** @var string|null */ - private $queryBuilderClass; + private ?string $queryBuilderClass = null; - /** @var DescriptorRegistry */ - private $descriptorRegistry; + private DescriptorRegistry $descriptorRegistry; - /** @var PhpVersion */ - private $phpVersion; + private PhpVersion $phpVersion; - /** @var DriverDetector */ - private $driverDetector; + private DriverDetector $driverDetector; public function __construct( ObjectMetadataResolver $objectMetadataResolver, diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php index cb76ba29..4e9ea601 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php @@ -23,8 +23,7 @@ class QueryBuilderMethodDynamicReturnTypeExtension implements DynamicMethodRetur private const MAX_COMBINATIONS = 16; - /** @var string|null */ - private $queryBuilderClass; + private ?string $queryBuilderClass = null; public function __construct( ?string $queryBuilderClass @@ -41,7 +40,7 @@ public function getClass(): string public function isMethodSupported(MethodReflection $methodReflection): bool { $returnType = ParametersAcceptorSelector::selectSingle( - $methodReflection->getVariants() + $methodReflection->getVariants(), )->getReturnType(); if ($returnType instanceof MixedType) { return false; diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderType.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderType.php index 729cda17..f707888c 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderType.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderType.php @@ -14,7 +14,7 @@ abstract class QueryBuilderType extends ObjectType { /** @var array */ - private $methodCalls = []; + private array $methodCalls = []; final public function __construct( string $className, diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php index 4b72f650..83966118 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php @@ -24,11 +24,9 @@ class QueryBuilderTypeSpecifyingExtension implements MethodTypeSpecifyingExtensi private const MAX_COMBINATIONS = 16; - /** @var string|null */ - private $queryBuilderClass; + private ?string $queryBuilderClass = null; - /** @var TypeSpecifier */ - private $typeSpecifier; + private TypeSpecifier $typeSpecifier; public function __construct(?string $queryBuilderClass) { @@ -62,7 +60,7 @@ public function specifyTypes(MethodReflection $methodReflection, MethodCall $nod $returnType = ParametersAcceptorSelector::selectFromArgs( $scope, $node->getArgs(), - $methodReflection->getVariants() + $methodReflection->getVariants(), )->getReturnType(); if ($returnType instanceof MixedType) { return new SpecifiedTypes([]); @@ -100,7 +98,7 @@ public function specifyTypes(MethodReflection $methodReflection, MethodCall $nod $queryBuilderNode, TypeCombinator::union(...$resultTypes), TypeSpecifierContext::createTruthy(), - true + true, ); } diff --git a/src/Type/Doctrine/QueryBuilder/ReturnQueryBuilderExpressionTypeResolverExtension.php b/src/Type/Doctrine/QueryBuilder/ReturnQueryBuilderExpressionTypeResolverExtension.php index 2f780f22..5f308ba1 100644 --- a/src/Type/Doctrine/QueryBuilder/ReturnQueryBuilderExpressionTypeResolverExtension.php +++ b/src/Type/Doctrine/QueryBuilder/ReturnQueryBuilderExpressionTypeResolverExtension.php @@ -23,8 +23,7 @@ class ReturnQueryBuilderExpressionTypeResolverExtension implements ExpressionTypeResolverExtension { - /** @var OtherMethodQueryBuilderParser */ - private $otherMethodQueryBuilderParser; + private OtherMethodQueryBuilderParser $otherMethodQueryBuilderParser; public function __construct( OtherMethodQueryBuilderParser $otherMethodQueryBuilderParser diff --git a/tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php b/tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php index f1f7dd32..7c92d905 100644 --- a/tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php +++ b/tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php @@ -33,7 +33,7 @@ public function testForbiddenClassNameExtension(): void 20, 'This is most likely unintentional. Did you mean to type \TestPhpStanEntity?', ], - ] + ], ); } diff --git a/tests/Classes/entity-manager.php b/tests/Classes/entity-manager.php index a84bdc54..9c0301d1 100644 --- a/tests/Classes/entity-manager.php +++ b/tests/Classes/entity-manager.php @@ -19,13 +19,13 @@ $metadataDriver = new MappingDriverChain(); $metadataDriver->addDriver(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], ), 'PHPStan\\Rules\\Doctrine\\ORM\\'); if (PHP_VERSION_ID >= 80100) { $metadataDriver->addDriver( new AttributeDriver([__DIR__ . '/data-attributes']), - 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\' + 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\', ); } @@ -33,7 +33,7 @@ Type::overrideType( 'date', - DateTimeImmutableType::class + DateTimeImmutableType::class, ); return new EntityManager( @@ -41,5 +41,5 @@ 'driver' => 'pdo_sqlite', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/DoctrineIntegration/ODM/document-manager.php b/tests/DoctrineIntegration/ODM/document-manager.php index bfdb4141..d104e205 100644 --- a/tests/DoctrineIntegration/ODM/document-manager.php +++ b/tests/DoctrineIntegration/ODM/document-manager.php @@ -16,11 +16,11 @@ $config->setMetadataDriverImpl( new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] - ) + [__DIR__ . '/data'], + ), ); return DocumentManager::create( null, - $config + $config, ); diff --git a/tests/DoctrineIntegration/ORM/entity-manager.php b/tests/DoctrineIntegration/ORM/entity-manager.php index 23f27436..fb21532a 100644 --- a/tests/DoctrineIntegration/ORM/entity-manager.php +++ b/tests/DoctrineIntegration/ORM/entity-manager.php @@ -15,8 +15,8 @@ $config->setMetadataDriverImpl( new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] - ) + [__DIR__ . '/data'], + ), ); return new EntityManager( @@ -24,5 +24,5 @@ 'driver' => 'pdo_sqlite', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Platform/Entity/PlatformEntity.php b/tests/Platform/Entity/PlatformEntity.php index 6da280e9..efc1f68d 100644 --- a/tests/Platform/Entity/PlatformEntity.php +++ b/tests/Platform/Entity/PlatformEntity.php @@ -17,90 +17,58 @@ class PlatformEntity /** * @ORM\Id * @ORM\Column(type="string",nullable=false) - * @var string */ #[ORM\Id] #[ORM\Column(type: 'string', nullable: false)] - public $id; + public string $id; /** * @ORM\ManyToOne(targetEntity=PlatformRelatedEntity::class) * @ORM\JoinColumn(name="related_entity_id", referencedColumnName="id", nullable=false) - * @var PlatformRelatedEntity */ #[ORM\ManyToOne(targetEntity: PlatformRelatedEntity::class)] #[ORM\JoinColumn(name: 'related_entity_id', referencedColumnName: 'id', nullable: false)] - public $related_entity; + public PlatformRelatedEntity $related_entity; - /** - * @ORM\Column(type="string", name="col_string", nullable=false) - * @var string - */ + /** @ORM\Column(type="string", name="col_string", nullable=false) */ #[ORM\Column(type: 'string', name: 'col_string', nullable: false)] - public $col_string; + public string $col_string; - /** - * @ORM\Column(type="string", name="col_string_nullable", nullable=true) - * @var string|null - */ + /** @ORM\Column(type="string", name="col_string_nullable", nullable=true) */ #[ORM\Column(type: 'string', name: 'col_string_nullable', nullable: true)] - public $col_string_nullable; + public ?string $col_string_nullable = null; - /** - * @ORM\Column(type="boolean", name="col_bool", nullable=false) - * @var bool - */ + /** @ORM\Column(type="boolean", name="col_bool", nullable=false) */ #[ORM\Column(type: 'boolean', name: 'col_bool', nullable: false)] - public $col_bool; + public bool $col_bool; - /** - * @ORM\Column(type="boolean", name="col_bool_nullable", nullable=true) - * @var bool|null - */ + /** @ORM\Column(type="boolean", name="col_bool_nullable", nullable=true) */ #[ORM\Column(type: 'boolean', name: 'col_bool_nullable', nullable: true)] - public $col_bool_nullable; + public ?bool $col_bool_nullable = null; - /** - * @ORM\Column(type="float", name="col_float", nullable=false) - * @var float - */ + /** @ORM\Column(type="float", name="col_float", nullable=false) */ #[ORM\Column(type: 'float', name: 'col_float', nullable: false)] - public $col_float; + public float $col_float; - /** - * @ORM\Column(type="float", name="col_float_nullable", nullable=true) - * @var float|null - */ + /** @ORM\Column(type="float", name="col_float_nullable", nullable=true) */ #[ORM\Column(type: 'float', name: 'col_float_nullable', nullable: true)] - public $col_float_nullable; + public ?float $col_float_nullable = null; - /** - * @ORM\Column(type="decimal", name="col_decimal", nullable=false, scale=1, precision=2) - * @var string - */ + /** @ORM\Column(type="decimal", name="col_decimal", nullable=false, scale=1, precision=2) */ #[ORM\Column(type: 'decimal', name: 'col_decimal', nullable: false, scale: 1, precision: 2)] - public $col_decimal; + public string $col_decimal; - /** - * @ORM\Column(type="decimal", name="col_decimal_nullable", nullable=true, scale=1, precision=2) - * @var string|null - */ + /** @ORM\Column(type="decimal", name="col_decimal_nullable", nullable=true, scale=1, precision=2) */ #[ORM\Column(type: 'decimal', name: 'col_decimal_nullable', nullable: true, scale: 1, precision: 2)] - public $col_decimal_nullable; + public ?string $col_decimal_nullable = null; - /** - * @ORM\Column(type="integer", name="col_int", nullable=false) - * @var int - */ + /** @ORM\Column(type="integer", name="col_int", nullable=false) */ #[ORM\Column(type: 'integer', name: 'col_int', nullable: false)] - public $col_int; + public int $col_int; - /** - * @ORM\Column(type="integer", name="col_int_nullable", nullable=true) - * @var int|null - */ + /** @ORM\Column(type="integer", name="col_int_nullable", nullable=true) */ #[ORM\Column(type: 'integer', name: 'col_int_nullable', nullable: true)] - public $col_int_nullable; + public ?int $col_int_nullable = null; /** * @ORM\Column(type="bigint", name="col_bigint", nullable=false) @@ -123,11 +91,8 @@ class PlatformEntity #[ORM\Column(type: 'mixed', name: 'col_mixed', nullable: false)] public $col_mixed; - /** - * @ORM\Column(type="datetime", name="col_datetime", nullable=false) - * @var DateTimeInterface - */ + /** @ORM\Column(type="datetime", name="col_datetime", nullable=false) */ #[ORM\Column(type: 'datetime', name: 'col_datetime', nullable: false)] - public $col_datetime; + public DateTimeInterface $col_datetime; } diff --git a/tests/Platform/Entity/PlatformRelatedEntity.php b/tests/Platform/Entity/PlatformRelatedEntity.php index 86c4b00a..fec1a0a5 100644 --- a/tests/Platform/Entity/PlatformRelatedEntity.php +++ b/tests/Platform/Entity/PlatformRelatedEntity.php @@ -16,10 +16,9 @@ class PlatformRelatedEntity /** * @ORM\Id * @ORM\Column(type="integer", nullable=false) - * @var int */ #[ORM\Id] #[ORM\Column(type: 'integer', nullable: false)] - public $id; + public int $id; } diff --git a/tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php b/tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php index 04fdcba8..97df9e20 100644 --- a/tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php +++ b/tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php @@ -134,7 +134,7 @@ public function testPdoMysqlDefault( PHP_VERSION_ID, $mysqlExpectedType, $mysqlExpectedResult, - $stringify + $stringify, ); } @@ -174,7 +174,7 @@ public function testPdoMysqlStringify( PHP_VERSION_ID, $mysqlExpectedType, $mysqlExpectedResult, - $stringify + $stringify, ); } @@ -214,7 +214,7 @@ public function testPdoMysqlNoEmulate( PHP_VERSION_ID, $mysqlExpectedType, $mysqlExpectedResult, - $stringify + $stringify, ); } @@ -254,7 +254,7 @@ public function testPdoMysqlStringifyNoEmulate( PHP_VERSION_ID, $mysqlExpectedType, $mysqlExpectedResult, - $stringify + $stringify, ); } @@ -294,7 +294,7 @@ public function testPdoMysqliDefault( PHP_VERSION_ID, $mysqlExpectedType, $mysqlExpectedResult, - $stringify + $stringify, ); } @@ -334,7 +334,7 @@ public function testPdoSqliteDefault( PHP_VERSION_ID, $sqliteExpectedType, $sqliteExpectedResult, - $stringify + $stringify, ); } @@ -374,7 +374,7 @@ public function testPdoSqliteStringify( PHP_VERSION_ID, $sqliteExpectedType, $sqliteExpectedResult, - $stringify + $stringify, ); } @@ -414,7 +414,7 @@ public function testPdoSqlite3( PHP_VERSION_ID, $sqliteExpectedType, $sqliteExpectedResult, - $stringify + $stringify, ); } @@ -454,7 +454,7 @@ public function testPdoPgsqlDefault( PHP_VERSION_ID, $pdoPgsqlExpectedType, $pdoPgsqlExpectedResult, - $stringify + $stringify, ); } @@ -494,7 +494,7 @@ public function testPdoPgsqlStringify( PHP_VERSION_ID, $pdoPgsqlExpectedType, $pdoPgsqlExpectedResult, - $stringify + $stringify, ); } @@ -534,7 +534,7 @@ public function testPgsql( PHP_VERSION_ID, $pgsqlExpectedType, $pgsqlExpectedResult, - $stringify + $stringify, ); } @@ -574,7 +574,7 @@ public function testUnsupportedDriver( PHP_VERSION_ID, $mssqlExpectedType, $mssqlExpectedResult, - $stringify + $stringify, ); } @@ -615,7 +615,7 @@ public function testUnknownDriver( $this->determineTypeForUnknownDriverUnknownSetup($mysqlExpectedType, $stringify), $mysqlExpectedResult, $stringify, - true + true, ); } @@ -656,7 +656,7 @@ public function testUnknownDriverStringify( $this->determineTypeForUnknownDriverUnknownSetup($mysqlExpectedType, $stringify), $mysqlExpectedResult, $stringify, - true + true, ); } @@ -4469,7 +4469,7 @@ private function performDriverTest( $dql, $sql, $realResultType->describe(VerbosityLevel::precise()), - $inferredType->describe(VerbosityLevel::precise()) + $inferredType->describe(VerbosityLevel::precise()), )); } @@ -4575,7 +4575,7 @@ private function getInferredType(Query $query): Type $typeBuilder, self::getContainer()->getByType(DescriptorRegistry::class), $phpVersion, - new DriverDetector() + new DriverDetector(), ); return $typeBuilder->getResultType(); @@ -4617,8 +4617,8 @@ private function assertRealResultMatchesExpected( $dataset, $dql, $humanReadablePhpVersion, - $realFirstResult - ) + $realFirstResult, + ), ); } @@ -4634,8 +4634,8 @@ private function assertRealResultMatchesExpected( $sql, $humanReadablePhpVersion, $realFirstResult, - $expectedFirstResultExported - ) + $expectedFirstResultExported, + ), ); } @@ -4669,8 +4669,8 @@ private function assertRealResultMatchesInferred( $this->getHumanReadablePhpVersion($phpVersion), $realFirstResult, $inferredType->describe(VerbosityLevel::precise()), - $realType->describe(VerbosityLevel::precise()) - ) + $realType->describe(VerbosityLevel::precise()), + ), ); } @@ -4707,8 +4707,8 @@ private function assertInferredResultMatchesExpected( $this->getHumanReadablePhpVersion($phpVersion), $realFirstResult, $inferredFirstItemType->describe(VerbosityLevel::precise()), - $expectedFirstItemType->describe(VerbosityLevel::precise()) - ) + $expectedFirstItemType->describe(VerbosityLevel::precise()), + ), ); } diff --git a/tests/Reflection/Doctrine/DoctrineSelectableClassReflectionExtensionTest.php b/tests/Reflection/Doctrine/DoctrineSelectableClassReflectionExtensionTest.php index 1debe15e..61c90e4f 100644 --- a/tests/Reflection/Doctrine/DoctrineSelectableClassReflectionExtensionTest.php +++ b/tests/Reflection/Doctrine/DoctrineSelectableClassReflectionExtensionTest.php @@ -9,11 +9,9 @@ final class DoctrineSelectableClassReflectionExtensionTest extends PHPStanTestCase { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; - /** @var DoctrineSelectableClassReflectionExtension */ - private $extension; + private DoctrineSelectableClassReflectionExtension $extension; protected function setUp(): void { diff --git a/tests/Rules/DeadCode/entity-manager.php b/tests/Rules/DeadCode/entity-manager.php index bc0d5ccb..30eeec97 100644 --- a/tests/Rules/DeadCode/entity-manager.php +++ b/tests/Rules/DeadCode/entity-manager.php @@ -17,12 +17,12 @@ $metadataDriver = new MappingDriverChain(); $metadataDriver->addDriver(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], ), 'PHPStan\\Rules\\Doctrine\\ORM\\'); if (PHP_VERSION_ID >= 80100) { $metadataDriver->addDriver( new AttributeDriver([__DIR__ . '/data']), - 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\' + 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\', ); } @@ -33,5 +33,5 @@ 'driver' => 'pdo_sqlite', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php index c7de7957..091ef9c3 100644 --- a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php @@ -35,11 +35,9 @@ class EntityColumnRuleTest extends RuleTestCase { - /** @var bool */ - private $allowNullablePropertyForRequiredField; + private bool $allowNullablePropertyForRequiredField; - /** @var string|null */ - private $objectManagerLoader; + private ?string $objectManagerLoader = null; protected function getRule(): Rule { @@ -85,7 +83,7 @@ protected function getRule(): Rule $this->createReflectionProvider(), true, $this->allowNullablePropertyForRequiredField, - true + true, ); } diff --git a/tests/Rules/Doctrine/ORM/EntityConstructorNotFinalRuleTest.php b/tests/Rules/Doctrine/ORM/EntityConstructorNotFinalRuleTest.php index 7647704b..a94fdfde 100644 --- a/tests/Rules/Doctrine/ORM/EntityConstructorNotFinalRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityConstructorNotFinalRuleTest.php @@ -13,13 +13,12 @@ class EntityConstructorNotFinalRuleTest extends RuleTestCase { - /** @var string|null */ - private $objectManagerLoader; + private ?string $objectManagerLoader = null; protected function getRule(): Rule { return new EntityConstructorNotFinalRule( - new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp') + new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp'), ); } diff --git a/tests/Rules/Doctrine/ORM/EntityMappingExceptionRuleTest.php b/tests/Rules/Doctrine/ORM/EntityMappingExceptionRuleTest.php index 26a4e744..65b8f209 100644 --- a/tests/Rules/Doctrine/ORM/EntityMappingExceptionRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityMappingExceptionRuleTest.php @@ -16,7 +16,7 @@ class EntityMappingExceptionRuleTest extends RuleTestCase protected function getRule(): Rule { return new EntityMappingExceptionRule( - new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', __DIR__ . '/../../../../tmp') + new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', __DIR__ . '/../../../../tmp'), ); } diff --git a/tests/Rules/Doctrine/ORM/EntityNotFinalRuleTest.php b/tests/Rules/Doctrine/ORM/EntityNotFinalRuleTest.php index 9f1494a7..d3f05395 100644 --- a/tests/Rules/Doctrine/ORM/EntityNotFinalRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityNotFinalRuleTest.php @@ -13,13 +13,12 @@ class EntityNotFinalRuleTest extends RuleTestCase { - /** @var string|null */ - private $objectManagerLoader; + private ?string $objectManagerLoader = null; protected function getRule(): Rule { return new EntityNotFinalRule( - new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp') + new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp'), ); } diff --git a/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php b/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php index cd83bebe..5222b65f 100644 --- a/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php @@ -14,18 +14,16 @@ class EntityRelationRuleTest extends RuleTestCase { - /** @var bool */ - private $allowNullablePropertyForRequiredField; + private bool $allowNullablePropertyForRequiredField; - /** @var string|null */ - private $objectManagerLoader; + private ?string $objectManagerLoader = null; protected function getRule(): Rule { return new EntityRelationRule( new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp'), $this->allowNullablePropertyForRequiredField, - true + true, ); } diff --git a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php index adad87ee..49cec42d 100644 --- a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php +++ b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php @@ -17,7 +17,7 @@ protected function getRule(): Rule { return new QueryBuilderDqlRule( new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', __DIR__ . '/../../../../tmp'), - true + true, ); } diff --git a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php index ec3dafb7..bb7f6b87 100644 --- a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php +++ b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php @@ -17,7 +17,7 @@ protected function getRule(): Rule { return new QueryBuilderDqlRule( new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', __DIR__ . '/../../../../tmp'), - true + true, ); } diff --git a/tests/Rules/Doctrine/ORM/entity-manager.php b/tests/Rules/Doctrine/ORM/entity-manager.php index 9181f8b8..500a2029 100644 --- a/tests/Rules/Doctrine/ORM/entity-manager.php +++ b/tests/Rules/Doctrine/ORM/entity-manager.php @@ -19,13 +19,13 @@ $metadataDriver = new MappingDriverChain(); $metadataDriver->addDriver(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], ), 'PHPStan\\Rules\\Doctrine\\ORM\\'); if (PHP_VERSION_ID >= 80100) { $metadataDriver->addDriver( new AttributeDriver([__DIR__ . '/data-attributes']), - 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\' + 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\', ); } @@ -33,7 +33,7 @@ Type::overrideType( 'date', - DateTimeImmutableType::class + DateTimeImmutableType::class, ); return new EntityManager( @@ -41,5 +41,5 @@ 'driver' => 'pdo_sqlite', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Rules/Properties/entity-manager.php b/tests/Rules/Properties/entity-manager.php index 99f7a07e..f36730f8 100644 --- a/tests/Rules/Properties/entity-manager.php +++ b/tests/Rules/Properties/entity-manager.php @@ -17,13 +17,13 @@ $metadataDriver = new MappingDriverChain(); $metadataDriver->addDriver(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], ), 'PHPStan\\Rules\\Doctrine\\ORM\\'); if (PHP_VERSION_ID >= 80100) { $metadataDriver->addDriver( new AttributeDriver([__DIR__ . '/data']), - 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\' + 'PHPStan\\Rules\\Doctrine\\ORMAttributes\\', ); } @@ -34,5 +34,5 @@ 'driver' => 'pdo_sqlite', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Type/Doctrine/DBAL/mysqli.php b/tests/Type/Doctrine/DBAL/mysqli.php index 2bc11294..ce3859e5 100644 --- a/tests/Type/Doctrine/DBAL/mysqli.php +++ b/tests/Type/Doctrine/DBAL/mysqli.php @@ -13,7 +13,7 @@ $config->setMetadataCache(new ArrayCachePool()); $config->setMetadataDriverImpl(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], )); return new EntityManager( @@ -21,5 +21,5 @@ 'driver' => 'mysqli', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Type/Doctrine/DBAL/pdo.php b/tests/Type/Doctrine/DBAL/pdo.php index c7e48751..7b6b0da3 100644 --- a/tests/Type/Doctrine/DBAL/pdo.php +++ b/tests/Type/Doctrine/DBAL/pdo.php @@ -13,7 +13,7 @@ $config->setMetadataCache(new ArrayCachePool()); $config->setMetadataDriverImpl(new AnnotationDriver( new AnnotationReader(), - [__DIR__ . '/data'] + [__DIR__ . '/data'], )); return new EntityManager( @@ -21,5 +21,5 @@ 'driver' => 'pdo_pgsql', 'memory' => true, ]), - $config + $config, ); diff --git a/tests/Type/Doctrine/DoctrineSelectableDynamicReturnTypeExtensionTest.php b/tests/Type/Doctrine/DoctrineSelectableDynamicReturnTypeExtensionTest.php index a34c7b22..01b66d7b 100644 --- a/tests/Type/Doctrine/DoctrineSelectableDynamicReturnTypeExtensionTest.php +++ b/tests/Type/Doctrine/DoctrineSelectableDynamicReturnTypeExtensionTest.php @@ -15,8 +15,7 @@ final class DoctrineSelectableDynamicReturnTypeExtensionTest extends TestCase { - /** @var DoctrineSelectableDynamicReturnTypeExtension */ - private $extension; + private DoctrineSelectableDynamicReturnTypeExtension $extension; protected function setUp(): void { @@ -52,10 +51,8 @@ public function testGetTypeFromMethodCall(): void $scope = $this->createMock(Scope::class); $scope->method('getType')->will( self::returnCallback( - static function (): Type { - return new ObjectType(Collection::class); - } - ) + static fn (): Type => new ObjectType(Collection::class), + ), ); $var = $this->createMock(Expr::class); diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php index b9d02c85..52e08911 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php @@ -79,7 +79,7 @@ public function test(Type $expectedType, string $dql, string $methodName, ?int $ $typeBuilder, self::getContainer()->getByType(DescriptorRegistry::class), self::getContainer()->getByType(PhpVersion::class), - self::getContainer()->getByType(DriverDetector::class) + self::getContainer()->getByType(DriverDetector::class), ); $resolver = self::getContainer()->getByType(HydrationModeReturnTypeResolver::class); @@ -89,12 +89,12 @@ public function test(Type $expectedType, string $dql, string $methodName, ?int $ new ConstantIntegerType($this->getRealHydrationMode($methodName, $hydrationMode)), $typeBuilder->getIndexType(), $typeBuilder->getResultType(), - $entityManager + $entityManager, ) ?? new MixedType(); self::assertSame( $expectedType->describe(VerbosityLevel::precise()), - $type->describe(VerbosityLevel::precise()) + $type->describe(VerbosityLevel::precise()), ); $query = $entityManager->createQuery($dql); @@ -106,8 +106,8 @@ public function test(Type $expectedType, string $dql, string $methodName, ?int $ sprintf( "The inferred type\n%s\nshould accept actual type\n%s", $type->describe(VerbosityLevel::precise()), - $resultType->describe(VerbosityLevel::precise()) - ) + $resultType->describe(VerbosityLevel::precise()), + ), ); } diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index fd6fee74..d7d42b14 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -61,11 +61,9 @@ final class QueryResultTypeWalkerTest extends PHPStanTestCase { - /** @var EntityManagerInterface */ - private static $em; + private static EntityManagerInterface $em; - /** @var DescriptorRegistry */ - private $descriptorRegistry; + private DescriptorRegistry $descriptorRegistry; public static function getAdditionalConfigFiles(): array { @@ -222,14 +220,14 @@ public function test(Type $expectedType, string $dql, ?string $expectedException $typeBuilder, $this->descriptorRegistry, self::getContainer()->getByType(PhpVersion::class), - self::getContainer()->getByType(DriverDetector::class) + self::getContainer()->getByType(DriverDetector::class), ); $type = $typeBuilder->getResultType(); self::assertSame( $expectedType->describe(VerbosityLevel::precise()), - $type->describe(VerbosityLevel::precise()) + $type->describe(VerbosityLevel::precise()), ); // Double-check our expectations @@ -246,8 +244,8 @@ public function test(Type $expectedType, string $dql, ?string $expectedException sprintf( "The inferred type\n%s\nshould accept actual type\n%s", $type->describe(VerbosityLevel::precise()), - $rowType->describe(VerbosityLevel::precise()) - ) + $rowType->describe(VerbosityLevel::precise()), + ), ); } } @@ -293,7 +291,7 @@ public function getTestData(): iterable yield 'arbitrary left join, selected' => [ TypeCombinator::union( new ObjectType(Many::class), - TypeCombinator::addNull(new ObjectType(One::class)) + TypeCombinator::addNull(new ObjectType(One::class)), ), ' SELECT m, o @@ -306,7 +304,7 @@ public function getTestData(): iterable yield 'arbitrary inner join, selected' => [ TypeCombinator::union( new ObjectType(Many::class), - new ObjectType(One::class) + new ObjectType(One::class), ), ' SELECT m, o @@ -323,7 +321,7 @@ public function getTestData(): iterable ]), $this->constantArray([ [new ConstantIntegerType(0), TypeCombinator::addNull(new ObjectType(One::class))], - ]) + ]), ), ' SELECT m AS many, o @@ -340,7 +338,7 @@ public function getTestData(): iterable ]), $this->constantArray([ [new ConstantStringType('one'), TypeCombinator::addNull(new ObjectType(One::class))], - ]) + ]), ), ' SELECT m AS many, o AS one @@ -357,7 +355,7 @@ public function getTestData(): iterable ]), $this->constantArray([ [new ConstantStringType('one'), new ObjectType(One::class)], - ]) + ]), ), ' SELECT m AS many, o AS one @@ -378,7 +376,7 @@ public function getTestData(): iterable [new ConstantIntegerType(0), new ObjectType(One::class)], [new ConstantStringType('id'), $hasDbal4 ? new IntegerType() : $this->numericString()], [new ConstantStringType('intColumn'), new IntegerType()], - ]) + ]), ), ' SELECT m, o, m.id, o.intColumn @@ -400,7 +398,7 @@ public function getTestData(): iterable [new ConstantIntegerType(0), new ObjectType(Many::class)], [new ConstantStringType('id'), $hasDbal4 ? new IntegerType() : $this->numericString()], [new ConstantStringType('intColumn'), new IntegerType()], - ]) + ]), ), ' SELECT o, m2, m, m.id, o.intColumn @@ -421,7 +419,7 @@ public function getTestData(): iterable [new ConstantStringType('one'), new ObjectType(One::class)], [new ConstantStringType('id'), $hasDbal4 ? new IntegerType() : $this->numericString()], [new ConstantStringType('intColumn'), new IntegerType()], - ]) + ]), ), ' SELECT m AS many, o AS one, m.id, o.intColumn @@ -674,42 +672,42 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( $this->intOrStringified(), - new NullType() + new NullType(), ), ], [ new ConstantIntegerType(2), TypeCombinator::union( $this->intOrStringified(), - new NullType() + new NullType(), ), ], [ new ConstantIntegerType(3), TypeCombinator::union( $this->intOrStringified(), - new NullType() + new NullType(), ), ], [ new ConstantIntegerType(4), TypeCombinator::union( $this->intOrStringified(), - new NullType() + new NullType(), ), ], [ new ConstantIntegerType(5), TypeCombinator::union( $this->floatOrStringified(), - new NullType() + new NullType(), ), ], [ new ConstantIntegerType(6), TypeCombinator::union( $this->floatOrStringified(), - new NullType() + new NullType(), ), ], [ @@ -754,7 +752,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( $this->stringifies() ? new ConstantStringType('1') : new ConstantIntegerType(1), - new NullType() + new NullType(), ), ], ]), @@ -770,14 +768,14 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( new StringType(), - $this->intOrStringified() + $this->intOrStringified(), ), ], [ new ConstantIntegerType(2), TypeCombinator::union( new StringType(), - new NullType() + new NullType(), ), ], [ @@ -790,7 +788,7 @@ public function getTestData(): iterable ? $this->numericString() : TypeCombinator::union( new IntegerType(), - new FloatType() + new FloatType(), ), ], ]), @@ -809,7 +807,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( new StringType(), - $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0) + $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0), ), ], ]), @@ -829,7 +827,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( new StringType(), - $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0) + $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0), ), ], ]), @@ -849,7 +847,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0), - $this->stringifies() ? new ConstantStringType('1') : new ConstantIntegerType(1) + $this->stringifies() ? new ConstantStringType('1') : new ConstantIntegerType(1), ), ], ]), @@ -868,7 +866,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), TypeCombinator::union( $this->stringifies() ? new ConstantStringType('0') : new ConstantIntegerType(0), - $this->stringifies() ? new ConstantStringType('1') : new ConstantIntegerType(1) + $this->stringifies() ? new ConstantStringType('1') : new ConstantIntegerType(1), ), ], ]), @@ -1083,7 +1081,7 @@ public function getTestData(): iterable new ConstantIntegerType(1), new ObjectType(OneId::class), ], - ]) + ]), ), ' SELECT NEW QueryResult\Entities\ManyId(m.id), From 731ac4cdbebc7a08c7ca87f972f9b6c568412f16 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 14:55:55 +0200 Subject: [PATCH 04/39] Remove obsolete skips --- .../UnusedPrivatePropertyRuleTest.php | 4 -- .../ORM/QueryBuilderDqlRuleSlowTest.php | 4 -- .../Doctrine/ORM/QueryBuilderDqlRuleTest.php | 5 --- ...ingGedmoByPhpDocPropertyAssignRuleTest.php | 5 --- ...ReadOnlyByPhpDocPropertyAssignRuleTest.php | 5 --- .../Query/QueryResultTypeWalkerTest.php | 44 +++++++++---------- 6 files changed, 21 insertions(+), 46 deletions(-) diff --git a/tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php b/tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php index 8c582618..e7a88b28 100644 --- a/tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php +++ b/tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php @@ -27,10 +27,6 @@ public static function getAdditionalConfigFiles(): array public function testRule(): void { - if (PHP_VERSION_ID < 70400) { - self::markTestSkipped('Test requires PHP 7.4.'); - } - $this->analyse([__DIR__ . '/data/unused-private-property.php'], [ [ 'Property PHPStan\Rules\Doctrine\ORM\UnusedPrivateProperty\EntityWithAGeneratedId::$unused is never written, only read.', diff --git a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php index 49cec42d..2c4e03f7 100644 --- a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php +++ b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php @@ -5,7 +5,6 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPStan\Type\Doctrine\ObjectMetadataResolver; -use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -23,9 +22,6 @@ protected function getRule(): Rule public function testRule(): void { - if (PHP_VERSION_ID < 70300) { - self::markTestSkipped('For some reason PHP 7.2 cannot recover from Trying to get property value of non-object'); - } $this->analyse([__DIR__ . '/data/query-builder-dql.php'], [ [ "QueryBuilder: [Syntax Error] line 0, col 66: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = 1)", diff --git a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php index bb7f6b87..65fd38d6 100644 --- a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php +++ b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php @@ -5,7 +5,6 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPStan\Type\Doctrine\ObjectMetadataResolver; -use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -23,10 +22,6 @@ protected function getRule(): Rule public function testRule(): void { - if (PHP_VERSION_ID < 70300) { - self::markTestSkipped('For some reason PHP 7.2 cannot recover from Trying to get property value of non-object'); - } - $this->analyse([__DIR__ . '/data/query-builder-dql.php'], [ [ "QueryBuilder: [Syntax Error] line 0, col 66: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = 1)", diff --git a/tests/Rules/Properties/MissingGedmoByPhpDocPropertyAssignRuleTest.php b/tests/Rules/Properties/MissingGedmoByPhpDocPropertyAssignRuleTest.php index 683ddff3..7b66451e 100644 --- a/tests/Rules/Properties/MissingGedmoByPhpDocPropertyAssignRuleTest.php +++ b/tests/Rules/Properties/MissingGedmoByPhpDocPropertyAssignRuleTest.php @@ -7,7 +7,6 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPStan\Type\Doctrine\ObjectMetadataResolver; -use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -34,10 +33,6 @@ public static function getAdditionalConfigFiles(): array public function testRule(): void { - if (PHP_VERSION_ID < 70400) { - self::markTestSkipped('Test requires PHP 7.4.'); - } - $this->analyse([__DIR__ . '/data/gedmo-property-assign-phpdoc.php'], [ // No errors expected ]); diff --git a/tests/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRuleTest.php b/tests/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRuleTest.php index 2f42a9a4..8a72494f 100644 --- a/tests/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRuleTest.php +++ b/tests/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRuleTest.php @@ -4,7 +4,6 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -24,10 +23,6 @@ public static function getAdditionalConfigFiles(): array public function testRule(): void { - if (PHP_VERSION_ID < 70400) { - self::markTestSkipped('Test requires PHP 7.4.'); - } - $this->analyse([__DIR__ . '/data/missing-readonly-property-assign-phpdoc.php'], [ [ 'Class MissingReadOnlyPropertyAssignPhpDoc\EntityWithAGeneratedId has an uninitialized @readonly property $unassigned. Assign it in the constructor.', diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index d7d42b14..9b17c3c5 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -1533,35 +1533,33 @@ private function yieldConditionalDataset(): iterable ]; } - if (PHP_VERSION_ID >= 70400) { - yield 'locate function' => [ - $this->constantArray([ - [new ConstantIntegerType(1), $this->uintOrStringified()], - [new ConstantIntegerType(2), TypeCombinator::addNull($this->uintOrStringified())], - [new ConstantIntegerType(3), TypeCombinator::addNull($this->uintOrStringified())], - [new ConstantIntegerType(4), $this->uintOrStringified()], - ]), - ' + yield 'locate function' => [ + $this->constantArray([ + [new ConstantIntegerType(1), $this->uintOrStringified()], + [new ConstantIntegerType(2), TypeCombinator::addNull($this->uintOrStringified())], + [new ConstantIntegerType(3), TypeCombinator::addNull($this->uintOrStringified())], + [new ConstantIntegerType(4), $this->uintOrStringified()], + ]), + ' SELECT LOCATE(m.stringColumn, m.stringColumn, 0), LOCATE(m.stringNullColumn, m.stringColumn, 0), LOCATE(m.stringColumn, m.stringNullColumn, 0), LOCATE(\'f\', \'foo\', 0) FROM QueryResult\Entities\Many m ', - null, - InstalledVersions::satisfies(new VersionParser(), 'doctrine/dbal', '>=3.4') - ? null - : ( - PHP_VERSION_ID >= 80100 - ? 'strpos(): Passing null to parameter #2 ($needle) of type string is deprecated' - : ( - PHP_VERSION_ID < 80000 - ? 'strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior' - : null - ) - ), - ]; - } + null, + InstalledVersions::satisfies(new VersionParser(), 'doctrine/dbal', '>=3.4') + ? null + : ( + PHP_VERSION_ID >= 80100 + ? 'strpos(): Passing null to parameter #2 ($needle) of type string is deprecated' + : ( + PHP_VERSION_ID < 80000 + ? 'strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior' + : null + ) + ), + ]; $ormVersion = InstalledVersions::getVersion('doctrine/orm'); $hasOrm3 = $ormVersion !== null && strpos($ormVersion, '3.') === 0; From 9ddc146f78776d5eff79a354bebb0838ac593b86 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:00:32 +0200 Subject: [PATCH 05/39] Put doctrine/lexer:^2.0 back --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1bad25c5..58c0ac4e 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "doctrine/collections": "^2.1", "doctrine/common": "^2.7 || ^3.0", "doctrine/dbal": "^3.3.8", - "doctrine/lexer": "^3.0", + "doctrine/lexer": "^2.0 || ^3.0", "doctrine/mongodb-odm": "^2.4.3", "doctrine/orm": "^2.16.0", "doctrine/persistence": "^2.2.1 || ^3.2", From 22a33bc188f1228252597acb794e4d629daa3352 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:00:53 +0200 Subject: [PATCH 06/39] Do not run PHPStan on 7.3 --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3230e295..ad3633e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -153,7 +153,6 @@ jobs: fail-fast: false matrix: php-version: - - "7.3" - "7.4" - "8.0" - "8.1" From da4e194fcdba5b141f095d0509d2e35d632fc12a Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:02:17 +0200 Subject: [PATCH 07/39] Put doctrine/collections:^1.6 back --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 58c0ac4e..fc15096e 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "composer/semver": "^3.3.2", "cweagans/composer-patches": "^1.7.3", "doctrine/annotations": "^2.0", - "doctrine/collections": "^2.1", + "doctrine/collections": "^1.6 || ^2.1", "doctrine/common": "^2.7 || ^3.0", "doctrine/dbal": "^3.3.8", "doctrine/lexer": "^2.0 || ^3.0", From d462eb98c6d2b7c2311ac8a4a9ad33f20e99a623 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:02:54 +0200 Subject: [PATCH 08/39] Fix CS --- tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index 9b17c3c5..bceab2fc 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -1554,10 +1554,10 @@ private function yieldConditionalDataset(): iterable PHP_VERSION_ID >= 80100 ? 'strpos(): Passing null to parameter #2 ($needle) of type string is deprecated' : ( - PHP_VERSION_ID < 80000 - ? 'strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior' - : null - ) + PHP_VERSION_ID < 80000 + ? 'strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior' + : null + ) ), ]; From 0f98bd177aac3eaf529d1aa9dee6456545c77016 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:08:34 +0200 Subject: [PATCH 09/39] Do not expect deprecation in test --- .../Doctrine/Query/QueryResultTypeWalkerTest.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index bceab2fc..b5ac7ee8 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -199,7 +199,7 @@ public function setUp(): void } /** @dataProvider getTestData */ - public function test(Type $expectedType, string $dql, ?string $expectedExceptionMessage = null, ?string $expectedDeprecationMessage = null): void + public function test(Type $expectedType, string $dql, ?string $expectedExceptionMessage = null): void { $em = self::$em; @@ -210,9 +210,6 @@ public function test(Type $expectedType, string $dql, ?string $expectedException if ($expectedExceptionMessage !== null) { $this->expectException(Throwable::class); $this->expectExceptionMessage($expectedExceptionMessage); - } elseif ($expectedDeprecationMessage !== null) { - $this->expectDeprecation(); - $this->expectDeprecationMessage($expectedDeprecationMessage); } QueryResultTypeWalker::walk( @@ -1548,17 +1545,6 @@ private function yieldConditionalDataset(): iterable FROM QueryResult\Entities\Many m ', null, - InstalledVersions::satisfies(new VersionParser(), 'doctrine/dbal', '>=3.4') - ? null - : ( - PHP_VERSION_ID >= 80100 - ? 'strpos(): Passing null to parameter #2 ($needle) of type string is deprecated' - : ( - PHP_VERSION_ID < 80000 - ? 'strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior' - : null - ) - ), ]; $ormVersion = InstalledVersions::getVersion('doctrine/orm'); From 039d325e5aed2b047b6d8a5d143ec6753defceed Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 15:18:12 +0200 Subject: [PATCH 10/39] Remove test about deprecated LOCATE() function in DBAL SQLite platform See https://github.com/doctrine/dbal/pull/5749 --- .../Query/QueryResultTypeWalkerTest.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index b5ac7ee8..33fa5bbd 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -1530,23 +1530,6 @@ private function yieldConditionalDataset(): iterable ]; } - yield 'locate function' => [ - $this->constantArray([ - [new ConstantIntegerType(1), $this->uintOrStringified()], - [new ConstantIntegerType(2), TypeCombinator::addNull($this->uintOrStringified())], - [new ConstantIntegerType(3), TypeCombinator::addNull($this->uintOrStringified())], - [new ConstantIntegerType(4), $this->uintOrStringified()], - ]), - ' - SELECT LOCATE(m.stringColumn, m.stringColumn, 0), - LOCATE(m.stringNullColumn, m.stringColumn, 0), - LOCATE(m.stringColumn, m.stringNullColumn, 0), - LOCATE(\'f\', \'foo\', 0) - FROM QueryResult\Entities\Many m - ', - null, - ]; - $ormVersion = InstalledVersions::getVersion('doctrine/orm'); $hasOrm3 = $ormVersion !== null && strpos($ormVersion, '3.') === 0; From d198a78b0b3ad70758c43c822f9bb86ebbcd0a48 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 13 Sep 2024 14:51:58 +0200 Subject: [PATCH 11/39] Fixes after TypeSpecifier BC break --- .../Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php | 2 ++ .../QueryBuilder/QueryBuilderTypeSpecifyingExtension.php | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php index d94a455a..32765e79 100644 --- a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php @@ -61,12 +61,14 @@ public function specifyTypes( new MethodCall($node->var, self::FIRST_METHOD_NAME), new ConstantBooleanType(false), $context, + $scope, ); $last = $this->typeSpecifier->create( new MethodCall($node->var, self::LAST_METHOD_NAME), new ConstantBooleanType(false), $context, + $scope, ); return $first->unionWith($last); diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php index 83966118..a6ab404d 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php @@ -98,8 +98,8 @@ public function specifyTypes(MethodReflection $methodReflection, MethodCall $nod $queryBuilderNode, TypeCombinator::union(...$resultTypes), TypeSpecifierContext::createTruthy(), - true, - ); + $scope, + )->setAlwaysOverwriteTypes(); } } From d45a6401fb657e43a90965ed5adbf486b630580f Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 17:55:23 +0200 Subject: [PATCH 12/39] Uncover everything behind the bleedingEdge flag --- rules.neon | 16 ++-------------- src/Rules/Doctrine/ORM/EntityColumnRule.php | 7 ------- src/Rules/Doctrine/ORM/EntityRelationRule.php | 10 +--------- .../Rules/Doctrine/ORM/EntityColumnRuleTest.php | 1 - .../Doctrine/ORM/EntityRelationRuleTest.php | 1 - 5 files changed, 3 insertions(+), 32 deletions(-) diff --git a/rules.neon b/rules.neon index de338d2a..cf2396b2 100644 --- a/rules.neon +++ b/rules.neon @@ -23,14 +23,10 @@ parametersSchema: rules: - PHPStan\Rules\Doctrine\ORM\DqlRule - PHPStan\Rules\Doctrine\ORM\RepositoryMethodCallRule + - PHPStan\Rules\Doctrine\ORM\EntityConstructorNotFinalRule + - PHPStan\Rules\Doctrine\ORM\EntityMappingExceptionRule - PHPStan\Rules\Doctrine\ORM\EntityNotFinalRule -conditionalTags: - PHPStan\Rules\Doctrine\ORM\EntityMappingExceptionRule: - phpstan.rules.rule: %featureToggles.bleedingEdge% - PHPStan\Rules\Doctrine\ORM\EntityConstructorNotFinalRule: - phpstan.rules.rule: %featureToggles.bleedingEdge% - services: - class: PHPStan\Rules\Doctrine\ORM\QueryBuilderDqlRule @@ -43,23 +39,15 @@ services: arguments: reportUnknownTypes: %doctrine.reportUnknownTypes% allowNullablePropertyForRequiredField: %doctrine.allowNullablePropertyForRequiredField% - bleedingEdge: %featureToggles.bleedingEdge% descriptorRegistry: @doctrineTypeDescriptorRegistry tags: - phpstan.rules.rule - - - class: PHPStan\Rules\Doctrine\ORM\EntityMappingExceptionRule - - - class: PHPStan\Rules\Doctrine\ORM\EntityNotFinalRule - class: PHPStan\Rules\Doctrine\ORM\EntityRelationRule arguments: allowNullablePropertyForRequiredField: %doctrine.allowNullablePropertyForRequiredField% - bleedingEdge: %featureToggles.bleedingEdge% tags: - phpstan.rules.rule - - - class: PHPStan\Rules\Doctrine\ORM\EntityConstructorNotFinalRule - class: PHPStan\Classes\DoctrineProxyForbiddenClassNamesExtension tags: diff --git a/src/Rules/Doctrine/ORM/EntityColumnRule.php b/src/Rules/Doctrine/ORM/EntityColumnRule.php index c2ee7a15..86cde306 100644 --- a/src/Rules/Doctrine/ORM/EntityColumnRule.php +++ b/src/Rules/Doctrine/ORM/EntityColumnRule.php @@ -44,15 +44,12 @@ class EntityColumnRule implements Rule private bool $allowNullablePropertyForRequiredField; - private bool $bleedingEdge; - public function __construct( ObjectMetadataResolver $objectMetadataResolver, DescriptorRegistry $descriptorRegistry, ReflectionProvider $reflectionProvider, bool $reportUnknownTypes, bool $allowNullablePropertyForRequiredField, - bool $bleedingEdge ) { $this->objectMetadataResolver = $objectMetadataResolver; @@ -60,7 +57,6 @@ public function __construct( $this->reflectionProvider = $reflectionProvider; $this->reportUnknownTypes = $reportUnknownTypes; $this->allowNullablePropertyForRequiredField = $allowNullablePropertyForRequiredField; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -70,9 +66,6 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { - if (!$this->bleedingEdge && !$this->objectMetadataResolver->hasObjectManagerLoader()) { - return []; - } $class = $scope->getClassReflection(); if ($class === null) { return []; diff --git a/src/Rules/Doctrine/ORM/EntityRelationRule.php b/src/Rules/Doctrine/ORM/EntityRelationRule.php index 97e3ae2f..62f8a22f 100644 --- a/src/Rules/Doctrine/ORM/EntityRelationRule.php +++ b/src/Rules/Doctrine/ORM/EntityRelationRule.php @@ -32,17 +32,13 @@ class EntityRelationRule implements Rule private bool $allowNullablePropertyForRequiredField; - private bool $bleedingEdge; - public function __construct( ObjectMetadataResolver $objectMetadataResolver, - bool $allowNullablePropertyForRequiredField, - bool $bleedingEdge + bool $allowNullablePropertyForRequiredField ) { $this->objectMetadataResolver = $objectMetadataResolver; $this->allowNullablePropertyForRequiredField = $allowNullablePropertyForRequiredField; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -52,10 +48,6 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { - if (!$this->bleedingEdge && !$this->objectMetadataResolver->hasObjectManagerLoader()) { - return []; - } - $class = $scope->getClassReflection(); if ($class === null) { return []; diff --git a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php index 091ef9c3..60a05db7 100644 --- a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php @@ -83,7 +83,6 @@ protected function getRule(): Rule $this->createReflectionProvider(), true, $this->allowNullablePropertyForRequiredField, - true, ); } diff --git a/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php b/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php index 5222b65f..7e81545f 100644 --- a/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php @@ -23,7 +23,6 @@ protected function getRule(): Rule return new EntityRelationRule( new ObjectMetadataResolver($this->objectManagerLoader, __DIR__ . '/../../../../tmp'), $this->allowNullablePropertyForRequiredField, - true, ); } From 674c9d44b5d2e385eaa5061615aa8a0ffac6e1fd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 18:00:11 +0200 Subject: [PATCH 13/39] Fixes after PHPStan update --- src/Type/Doctrine/Descriptors/SimpleArrayType.php | 3 ++- src/Type/Doctrine/HydrationModeReturnTypeResolver.php | 4 ++-- tests/Platform/data/config.neon | 3 --- .../Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php | 4 +--- tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php | 2 +- tests/Type/Doctrine/data/QueryResult/config.neon | 2 -- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Type/Doctrine/Descriptors/SimpleArrayType.php b/src/Type/Doctrine/Descriptors/SimpleArrayType.php index 8044caca..2154eb91 100644 --- a/src/Type/Doctrine/Descriptors/SimpleArrayType.php +++ b/src/Type/Doctrine/Descriptors/SimpleArrayType.php @@ -8,6 +8,7 @@ use PHPStan\Type\MixedType; use PHPStan\Type\StringType; use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; class SimpleArrayType implements DoctrineTypeDescriptor { @@ -19,7 +20,7 @@ public function getType(): string public function getWritableToPropertyType(): Type { - return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())); + return TypeCombinator::intersect(new ArrayType(new IntegerType(), new StringType()), new AccessoryArrayListType()); } public function getWritableToDatabaseType(): Type diff --git a/src/Type/Doctrine/HydrationModeReturnTypeResolver.php b/src/Type/Doctrine/HydrationModeReturnTypeResolver.php index c0522e7f..e978ae2f 100644 --- a/src/Type/Doctrine/HydrationModeReturnTypeResolver.php +++ b/src/Type/Doctrine/HydrationModeReturnTypeResolver.php @@ -77,10 +77,10 @@ public function getMethodReturnTypeForHydrationMode( ); default: if ($queryKeyType->isNull()->yes()) { - return AccessoryArrayListType::intersectWith(new ArrayType( + return TypeCombinator::intersect(new ArrayType( new IntegerType(), $queryResultType, - )); + ), new AccessoryArrayListType()); } return new ArrayType( $queryKeyType, diff --git a/tests/Platform/data/config.neon b/tests/Platform/data/config.neon index 38f26ed7..e6dd2808 100644 --- a/tests/Platform/data/config.neon +++ b/tests/Platform/data/config.neon @@ -1,5 +1,2 @@ includes: - ../../../extension.neon -parameters: - featureToggles: - listType: true diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php index 52e08911..307a867d 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php @@ -116,8 +116,6 @@ public function test(Type $expectedType, string $dql, string $methodName, ?int $ */ public static function getTestData(): iterable { - AccessoryArrayListType::setListTypeEnabled(true); - yield 'getResult(object), full entity' => [ self::list(new ObjectType(Simple::class)), ' @@ -305,7 +303,7 @@ private static function constantArray(array $elements): Type private static function list(Type $values): Type { - return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $values)); + return TypeCombinator::intersect(new ArrayType(new IntegerType(), $values), new AccessoryArrayListType()); } private static function numericString(): Type diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index 33fa5bbd..427212a4 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -1497,7 +1497,7 @@ private function yieldConditionalDataset(): iterable $this->constantArray([ [new ConstantStringType('stringEnumColumn'), new ObjectType(StringEnum::class)], [new ConstantStringType('intEnumColumn'), new ObjectType(IntEnum::class)], - [new ConstantStringType('stringEnumListColumn'), AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new ObjectType(StringEnum::class)))], + [new ConstantStringType('stringEnumListColumn'), TypeCombinator::intersect(new ArrayType(new IntegerType(), new ObjectType(StringEnum::class)), new AccessoryArrayListType())], ]), ' SELECT e.stringEnumColumn, e.intEnumColumn, e.stringEnumListColumn diff --git a/tests/Type/Doctrine/data/QueryResult/config.neon b/tests/Type/Doctrine/data/QueryResult/config.neon index 5ce3210a..147e4f94 100644 --- a/tests/Type/Doctrine/data/QueryResult/config.neon +++ b/tests/Type/Doctrine/data/QueryResult/config.neon @@ -3,5 +3,3 @@ includes: parameters: doctrine: objectManagerLoader: entity-manager.php - featureToggles: - listType: true From a110d8a13ace9c5fcdfd63cc3c6e081ab1cc4da4 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 20:51:55 +0200 Subject: [PATCH 14/39] Fix --- src/Rules/Doctrine/ORM/EntityColumnRule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rules/Doctrine/ORM/EntityColumnRule.php b/src/Rules/Doctrine/ORM/EntityColumnRule.php index 86cde306..06b9343f 100644 --- a/src/Rules/Doctrine/ORM/EntityColumnRule.php +++ b/src/Rules/Doctrine/ORM/EntityColumnRule.php @@ -49,7 +49,7 @@ public function __construct( DescriptorRegistry $descriptorRegistry, ReflectionProvider $reflectionProvider, bool $reportUnknownTypes, - bool $allowNullablePropertyForRequiredField, + bool $allowNullablePropertyForRequiredField ) { $this->objectMetadataResolver = $objectMetadataResolver; From c17a736f8c5d4c0d7ac2179e109541a9f4a7ba2d Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 26 Sep 2024 14:53:22 +0200 Subject: [PATCH 15/39] Fixes after PHPStan updates --- .../QueryBuilder/QueryBuilderExecuteMethodExtension.php | 6 +++++- .../DBAL/RowCountMethodDynamicReturnTypeExtension.php | 3 +-- .../Query/QueryResultDynamicReturnTypeExtension.php | 6 ++++-- src/Type/Doctrine/Query/QueryResultTypeWalker.php | 2 +- .../QueryBuilderMethodDynamicReturnTypeExtension.php | 5 +---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php index a997c2da..ad30e430 100644 --- a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php +++ b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php @@ -38,7 +38,11 @@ public function isMethodSupported(MethodReflection $methodReflection): bool public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type { - $defaultReturnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); + $defaultReturnType = ParametersAcceptorSelector::selectFromArgs( + $scope, + $methodCall->getArgs(), + $methodReflection->getVariants() + )->getReturnType(); $queryBuilderType = new ObjectType(QueryBuilder::class); $var = $methodCall->var; diff --git a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php index 03a988e1..60c17e79 100644 --- a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php @@ -8,7 +8,6 @@ use PHPStan\Analyser\Scope; use PHPStan\Doctrine\Driver\DriverDetector; use PHPStan\Reflection\MethodReflection; -use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\Doctrine\ObjectMetadataResolver; use PHPStan\Type\DynamicMethodReturnTypeExtension; @@ -76,7 +75,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } $rowCountMethod = $resultReflection->getNativeMethod('rowCount'); - $variant = ParametersAcceptorSelector::selectSingle($rowCountMethod->getVariants()); + $variant = $rowCountMethod->getOnlyVariant(); return $variant->getReturnType(); } diff --git a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php index 24aecb38..dda9e637 100644 --- a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php @@ -68,8 +68,10 @@ public function getTypeFromMethodCall( if (isset($args[$argIndex])) { $hydrationMode = $scope->getType($args[$argIndex]->value); } else { - $parametersAcceptor = ParametersAcceptorSelector::selectSingle( - $methodReflection->getVariants(), + $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( + $scope, + $methodCall->getArgs(), + $methodReflection->getVariants() ); $parameter = $parametersAcceptor->getParameters()[$argIndex]; $hydrationMode = $parameter->getDefaultValue() ?? new NullType(); diff --git a/src/Type/Doctrine/Query/QueryResultTypeWalker.php b/src/Type/Doctrine/Query/QueryResultTypeWalker.php index 4b96044d..e508d925 100644 --- a/src/Type/Doctrine/Query/QueryResultTypeWalker.php +++ b/src/Type/Doctrine/Query/QueryResultTypeWalker.php @@ -609,7 +609,7 @@ public function walkFunction($function): string if ($this->driverType === DriverDetector::MYSQLI || $this->driverType === DriverDetector::PDO_MYSQL || $this->driverType === DriverDetector::SQLITE3 || $this->driverType === DriverDetector::PDO_SQLITE) { $type = new FloatType(); - $cannotBeNegative = $exprType->isSmallerThan(new ConstantIntegerType(0))->no(); + $cannotBeNegative = $exprType->isSmallerThan(new ConstantIntegerType(0), $this->phpVersion)->no(); $canBeNegative = !$cannotBeNegative; if ($canBeNegative) { $type = TypeCombinator::addNull($type); diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php index 4e9ea601..67003dc6 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php @@ -7,7 +7,6 @@ use PhpParser\Node\Identifier; use PHPStan\Analyser\Scope; use PHPStan\Reflection\MethodReflection; -use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Type\Doctrine\DoctrineTypeUtils; use PHPStan\Type\DynamicMethodReturnTypeExtension; use PHPStan\Type\MixedType; @@ -39,9 +38,7 @@ public function getClass(): string public function isMethodSupported(MethodReflection $methodReflection): bool { - $returnType = ParametersAcceptorSelector::selectSingle( - $methodReflection->getVariants(), - )->getReturnType(); + $returnType = $methodReflection->getVariants()[0]->getReturnType(); if ($returnType instanceof MixedType) { return false; } From c5856104344ad18ad5e405ada91d384be5ca0e26 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 16:58:44 +0200 Subject: [PATCH 16/39] [BCB] Remove options that existed only for performance reasons --- extension.neon | 6 - rules.neon | 2 - ...QueryBuilderDynamicReturnTypeExtension.php | 13 +- .../OtherMethodQueryBuilderParser.php | 9 +- .../QueryBuilder/SimpleQueryBuilderType.php | 33 ---- .../ORM/QueryBuilderDqlRuleSlowTest.php | 147 ------------------ tests/Rules/Doctrine/ORM/slow.neon | 3 - 7 files changed, 3 insertions(+), 210 deletions(-) delete mode 100644 src/Type/Doctrine/QueryBuilder/SimpleQueryBuilderType.php delete mode 100644 tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php delete mode 100644 tests/Rules/Doctrine/ORM/slow.neon diff --git a/extension.neon b/extension.neon index 63365d37..b8f68a86 100644 --- a/extension.neon +++ b/extension.neon @@ -9,8 +9,6 @@ parameters: queryBuilderClass: null allCollectionsSelectable: true objectManagerLoader: null - searchOtherMethodsForQueryBuilderBeginning: true - queryBuilderFastAlgorithm: false literalString: false featureToggles: skipCheckGenericClasses: @@ -79,8 +77,6 @@ parametersSchema: queryBuilderClass: schema(string(), nullable()) allCollectionsSelectable: bool() objectManagerLoader: schema(string(), nullable()) - searchOtherMethodsForQueryBuilderBeginning: bool() - queryBuilderFastAlgorithm: bool() reportDynamicQueryBuilders: bool() reportUnknownTypes: bool() allowNullablePropertyForRequiredField: bool() @@ -117,7 +113,6 @@ services: class: PHPStan\Type\Doctrine\QueryBuilder\CreateQueryBuilderDynamicReturnTypeExtension arguments: queryBuilderClass: %doctrine.queryBuilderClass% - fasterVersion: %doctrine.queryBuilderFastAlgorithm% tags: - phpstan.broker.dynamicMethodReturnTypeExtension - @@ -194,7 +189,6 @@ services: - class: PHPStan\Type\Doctrine\QueryBuilder\OtherMethodQueryBuilderParser arguments: - descendIntoOtherMethods: %doctrine.searchOtherMethodsForQueryBuilderBeginning% parser: @defaultAnalysisParser - diff --git a/rules.neon b/rules.neon index cf2396b2..0853184d 100644 --- a/rules.neon +++ b/rules.neon @@ -12,8 +12,6 @@ parametersSchema: queryBuilderClass: schema(string(), nullable()) allCollectionsSelectable: bool() objectManagerLoader: schema(string(), nullable()) - searchOtherMethodsForQueryBuilderBeginning: bool() - queryBuilderFastAlgorithm: bool() reportDynamicQueryBuilders: bool() reportUnknownTypes: bool() allowNullablePropertyForRequiredField: bool() diff --git a/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php index 8389395a..3fe7e9b1 100644 --- a/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/CreateQueryBuilderDynamicReturnTypeExtension.php @@ -13,15 +13,11 @@ class CreateQueryBuilderDynamicReturnTypeExtension implements DynamicMethodRetur private ?string $queryBuilderClass = null; - private bool $fasterVersion; - public function __construct( - ?string $queryBuilderClass, - bool $fasterVersion + ?string $queryBuilderClass ) { $this->queryBuilderClass = $queryBuilderClass; - $this->fasterVersion = $fasterVersion; } public function getClass(): string @@ -40,12 +36,7 @@ public function getTypeFromMethodCall( Scope $scope ): Type { - $class = SimpleQueryBuilderType::class; - if (!$this->fasterVersion) { - $class = BranchingQueryBuilderType::class; - } - - return new $class( + return new BranchingQueryBuilderType( $this->queryBuilderClass ?? 'Doctrine\ORM\QueryBuilder', ); } diff --git a/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php b/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php index cddd3a93..153291f5 100644 --- a/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php +++ b/src/Type/Doctrine/QueryBuilder/OtherMethodQueryBuilderParser.php @@ -28,8 +28,6 @@ class OtherMethodQueryBuilderParser { - private bool $descendIntoOtherMethods; - private Parser $parser; private Container $container; @@ -41,9 +39,8 @@ class OtherMethodQueryBuilderParser */ private array $cache = []; - public function __construct(bool $descendIntoOtherMethods, Parser $parser, Container $container) + public function __construct(Parser $parser, Container $container) { - $this->descendIntoOtherMethods = $descendIntoOtherMethods; $this->parser = $parser; $this->container = $container; } @@ -53,10 +50,6 @@ public function __construct(bool $descendIntoOtherMethods, Parser $parser, Conta */ public function findQueryBuilderTypesInCalledMethod(Scope $scope, MethodReflection $methodReflection): array { - if (!$this->descendIntoOtherMethods) { - return []; - } - $methodName = $methodReflection->getName(); $className = $methodReflection->getDeclaringClass()->getName(); $fileName = $methodReflection->getDeclaringClass()->getFileName(); diff --git a/src/Type/Doctrine/QueryBuilder/SimpleQueryBuilderType.php b/src/Type/Doctrine/QueryBuilder/SimpleQueryBuilderType.php deleted file mode 100644 index 98660de8..00000000 --- a/src/Type/Doctrine/QueryBuilder/SimpleQueryBuilderType.php +++ /dev/null @@ -1,33 +0,0 @@ -getMethodCalls()) === count($type->getMethodCalls()); - } - - return parent::equals($type); - } - - public function isSuperTypeOf(Type $type): TrinaryLogic - { - if ($type instanceof parent) { - $thisCount = count($this->getMethodCalls()); - $thatCount = count($type->getMethodCalls()); - - return TrinaryLogic::createFromBoolean($thisCount === $thatCount); - } - - return parent::isSuperTypeOf($type); - } - -} diff --git a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php b/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php deleted file mode 100644 index 2c4e03f7..00000000 --- a/tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php +++ /dev/null @@ -1,147 +0,0 @@ - - */ -class QueryBuilderDqlRuleSlowTest extends RuleTestCase -{ - - protected function getRule(): Rule - { - return new QueryBuilderDqlRule( - new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', __DIR__ . '/../../../../tmp'), - true, - ); - } - - public function testRule(): void - { - $this->analyse([__DIR__ . '/data/query-builder-dql.php'], [ - [ - "QueryBuilder: [Syntax Error] line 0, col 66: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = 1)", - 31, - ], - [ - "QueryBuilder: [Syntax Error] line 0, col 68: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = :id)", - 43, - ], - [ - "QueryBuilder: [Syntax Error] line 0, col 68: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = :id)", - 55, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 60 near \'transient = \': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named transient', - 62, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 14 near \'Foo e\': Error: Class \'Foo\' is not defined.', - 71, - ], - [ - 'Could not analyse QueryBuilder with dynamic arguments.', - 99, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 60 near \'transient = \': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named transient', - 107, - ], - [ - "QueryBuilder: [Syntax Error] line 0, col 82: Error: Expected end of string, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = 1 ORDER BY e.name) ASC", - 129, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 78 near \'name ASC\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named name', - 139, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 78 near \'name ASC\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named name', - 160, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 60 near \'transient = 1\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named transient', - 170, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 72 near \'nickname LIKE\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named nickname', - 194, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 72 near \'nickname IS \': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named nickname', - 206, - ], - [ - "QueryBuilder: [Syntax Error] line 0, col 80: Error: Expected =, <, <=, <>, >, >=, !=, got ')'\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE e.id = 1 OR e.nickname) IS NULL", - 218, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 60 near \'transient = \': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named transient', - 234, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 60 near \'nonexistent =\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named nonexistent', - 251, - ], - [ - "QueryBuilder: [Syntax Error] line 0, col -1: Error: Expected =, <, <=, <>, >, >=, !=, got end of string.\nDQL: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE foo", - 281, - ], - ]); - } - - public function testRuleBranches(): void - { - $errors = [ - [ - 'QueryBuilder: [Semantical Error] line 0, col 58 near \'p.id = 1\': Error: \'p\' is not defined.', - 31, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 58 near \'p.id = 1\': Error: \'p\' is not defined.', - 45, - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 58 near \'p.id = 1\': Error: \'p\' is not defined.', - 59, - 'Detected from DQL branch: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e WHERE p.id = 1', - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 93 near \'t.id = 1\': Error: \'t\' is not defined.', - 90, - 'Detected from DQL branch: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e INNER JOIN e.parent p WHERE p.id = 1 AND t.id = 1', - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 95 near \'foo = 1\': Error: Class PHPStan\Rules\Doctrine\ORM\MyEntity has no field or association named foo', - 107, - 'Detected from DQL branch: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e INNER JOIN e.parent p WHERE p.id = 1 AND e.foo = 1', - ], - [ - 'QueryBuilder: [Semantical Error] line 0, col 93 near \'t.id = 1\': Error: \'t\' is not defined.', - 107, - 'Detected from DQL branch: SELECT e FROM PHPStan\Rules\Doctrine\ORM\MyEntity e INNER JOIN e.parent p WHERE p.id = 1 AND t.id = 1', - ], - ]; - $this->analyse([__DIR__ . '/data/query-builder-branches-dql.php'], $errors); - } - - public static function getAdditionalConfigFiles(): array - { - return [ - __DIR__ . '/../../../../extension.neon', - __DIR__ . '/entity-manager.neon', - __DIR__ . '/slow.neon', - ]; - } - - protected function shouldFailOnPhpErrors(): bool - { - // doctrine/orm/src/Query/Parser.php throws assert($peek !== null) failed - return false; - } - -} diff --git a/tests/Rules/Doctrine/ORM/slow.neon b/tests/Rules/Doctrine/ORM/slow.neon deleted file mode 100644 index bfda5b8a..00000000 --- a/tests/Rules/Doctrine/ORM/slow.neon +++ /dev/null @@ -1,3 +0,0 @@ -parameters: - doctrine: - queryBuilderFastAlgorithm: false From 493457ac434afdbfa5604f01f98261cdd4e45d6b Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 17:01:10 +0200 Subject: [PATCH 17/39] Fix CS --- .../DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php | 2 +- .../Doctrine/Query/QueryResultDynamicReturnTypeExtension.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php index ad30e430..0a644f3a 100644 --- a/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php +++ b/src/Type/Doctrine/DBAL/QueryBuilder/QueryBuilderExecuteMethodExtension.php @@ -41,7 +41,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $defaultReturnType = ParametersAcceptorSelector::selectFromArgs( $scope, $methodCall->getArgs(), - $methodReflection->getVariants() + $methodReflection->getVariants(), )->getReturnType(); $queryBuilderType = new ObjectType(QueryBuilder::class); diff --git a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php index dda9e637..22ed0b5a 100644 --- a/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php @@ -71,7 +71,7 @@ public function getTypeFromMethodCall( $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( $scope, $methodCall->getArgs(), - $methodReflection->getVariants() + $methodReflection->getVariants(), ); $parameter = $parametersAcceptor->getParameters()[$argIndex]; $hydrationMode = $parameter->getDefaultValue() ?? new NullType(); From 261b19d3a59d02caa4f7d1da8c78976d01a20913 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 17:03:34 +0200 Subject: [PATCH 18/39] Fixes after PHPStan update --- src/Rules/Doctrine/ORM/DqlRule.php | 3 +-- src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php | 3 +-- src/Type/Doctrine/ArgumentsProcessor.php | 2 +- .../Doctrine/GetRepositoryDynamicReturnTypeExtension.php | 2 +- ...sitoryCreateQueryBuilderDynamicReturnTypeExtension.php | 2 +- tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php | 8 ++++---- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Rules/Doctrine/ORM/DqlRule.php b/src/Rules/Doctrine/ORM/DqlRule.php index 77cd3664..23f4da41 100644 --- a/src/Rules/Doctrine/ORM/DqlRule.php +++ b/src/Rules/Doctrine/ORM/DqlRule.php @@ -11,7 +11,6 @@ use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\Doctrine\ObjectMetadataResolver; use PHPStan\Type\ObjectType; -use PHPStan\Type\TypeUtils; use function count; use function sprintf; @@ -54,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array return []; } - $dqls = TypeUtils::getConstantStrings($scope->getType($node->getArgs()[0]->value)); + $dqls = $scope->getType($node->getArgs()[0]->value)->getConstantStrings(); if (count($dqls) === 0) { return []; } diff --git a/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php b/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php index 62155d01..69f9791a 100644 --- a/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php +++ b/src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php @@ -13,7 +13,6 @@ use PHPStan\Type\Doctrine\DoctrineTypeUtils; use PHPStan\Type\Doctrine\ObjectMetadataResolver; use PHPStan\Type\ObjectType; -use PHPStan\Type\TypeUtils; use Throwable; use function array_values; use function count; @@ -81,7 +80,7 @@ public function processNode(Node $node, Scope $scope): array ]; } - $dqls = TypeUtils::getConstantStrings($dqlType); + $dqls = $dqlType->getConstantStrings(); if (count($dqls) === 0) { if ($this->reportDynamicQueryBuilders) { return [ diff --git a/src/Type/Doctrine/ArgumentsProcessor.php b/src/Type/Doctrine/ArgumentsProcessor.php index 77eeb5d7..2cd94fd7 100644 --- a/src/Type/Doctrine/ArgumentsProcessor.php +++ b/src/Type/Doctrine/ArgumentsProcessor.php @@ -58,7 +58,7 @@ public function processArgs( continue; } - if ($value->isClassStringType()->yes() && count($value->getClassStringObjectType()->getObjectClassNames()) === 1) { + if ($value->isClassString()->yes() && count($value->getClassStringObjectType()->getObjectClassNames()) === 1) { /** @var class-string $className */ $className = $value->getClassStringObjectType()->getObjectClassNames()[0]; if ($this->objectMetadataResolver->isTransient($className)) { diff --git a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php index d514a12b..8daaece8 100644 --- a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php @@ -85,7 +85,7 @@ public function getTypeFromMethodCall( ); } $argType = $scope->getType($methodCall->getArgs()[0]->value); - if (!$argType->isClassStringType()->yes()) { + if (!$argType->isClassString()->yes()) { return $this->getDefaultReturnType($scope, $methodCall->getArgs(), $methodReflection, $defaultRepositoryClass); } diff --git a/src/Type/Doctrine/QueryBuilder/EntityRepositoryCreateQueryBuilderDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/EntityRepositoryCreateQueryBuilderDynamicReturnTypeExtension.php index f170b550..44201e45 100644 --- a/src/Type/Doctrine/QueryBuilder/EntityRepositoryCreateQueryBuilderDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/EntityRepositoryCreateQueryBuilderDynamicReturnTypeExtension.php @@ -35,7 +35,7 @@ public function getTypeFromMethodCall( $entityNameExpr = new MethodCall($methodCall->var, new Identifier('getEntityName')); $entityNameExprType = $scope->getType($entityNameExpr); - if ($entityNameExprType->isClassStringType()->yes() && count($entityNameExprType->getClassStringObjectType()->getObjectClassNames()) === 1) { + if ($entityNameExprType->isClassString()->yes() && count($entityNameExprType->getClassStringObjectType()->getObjectClassNames()) === 1) { $entityNameExpr = new String_($entityNameExprType->getClassStringObjectType()->getObjectClassNames()[0]); } diff --git a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php index 60a05db7..d03da719 100644 --- a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php @@ -75,10 +75,10 @@ protected function getRule(): Rule new StringType(), new SimpleArrayType(), new UuidTypeDescriptor(FakeTestingUuidType::class), - new ReflectionDescriptor(CarbonImmutableType::class, $this->createBroker(), self::getContainer()), - new ReflectionDescriptor(CarbonType::class, $this->createBroker(), self::getContainer()), - new ReflectionDescriptor(CustomType::class, $this->createBroker(), self::getContainer()), - new ReflectionDescriptor(CustomNumericType::class, $this->createBroker(), self::getContainer()), + new ReflectionDescriptor(CarbonImmutableType::class, $this->createReflectionProvider(), self::getContainer()), + new ReflectionDescriptor(CarbonType::class, $this->createReflectionProvider(), self::getContainer()), + new ReflectionDescriptor(CustomType::class, $this->createReflectionProvider(), self::getContainer()), + new ReflectionDescriptor(CustomNumericType::class, $this->createReflectionProvider(), self::getContainer()), ]), $this->createReflectionProvider(), true, From 4f513337c20586277cdc76871eb482b614396bf2 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 4 Oct 2024 13:36:14 +0200 Subject: [PATCH 19/39] Fixes after PHPStan update --- src/Rules/Doctrine/ORM/EntityColumnRule.php | 3 +-- src/Rules/Doctrine/ORM/EntityRelationRule.php | 3 +-- .../DBAL/RowCountMethodDynamicReturnTypeExtension.php | 4 ++++ .../Doctrine/GetRepositoryDynamicReturnTypeExtension.php | 4 ++++ .../QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php | 4 ++++ .../QueryBuilderGetDqlDynamicReturnTypeExtension.php | 4 ++++ .../QueryBuilderGetQueryDynamicReturnTypeExtension.php | 4 ++++ .../QueryBuilderMethodDynamicReturnTypeExtension.php | 4 ++++ .../QueryBuilder/QueryBuilderTypeSpecifyingExtension.php | 4 ++++ stubs/MongoClassMetadataInfo.stub | 5 ----- .../ORM/EntityRepositoryDynamicReturnIntegrationTest.php | 2 +- ...ithoutObjectManagerLoaderDynamicReturnIntegrationTest.php | 2 +- tests/Rules/Doctrine/ORM/FakeTestingUuidType.php | 1 + 13 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Rules/Doctrine/ORM/EntityColumnRule.php b/src/Rules/Doctrine/ORM/EntityColumnRule.php index 06b9343f..b5f42bb6 100644 --- a/src/Rules/Doctrine/ORM/EntityColumnRule.php +++ b/src/Rules/Doctrine/ORM/EntityColumnRule.php @@ -16,7 +16,6 @@ use PHPStan\Type\MixedType; use PHPStan\Type\NeverType; use PHPStan\Type\ObjectType; -use PHPStan\Type\ParserNodeTypeToPHPStanType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypehintHelper; @@ -176,7 +175,7 @@ public function processNode(Node $node, Scope $scope): array } $phpDocType = $node->getPhpDocType(); - $nativeType = $node->getNativeType() !== null ? ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $scope->getClassReflection()) : new MixedType(); + $nativeType = $node->getNativeType() ?? new MixedType(); $propertyType = TypehintHelper::decideType($nativeType, $phpDocType); if (get_class($propertyType) === MixedType::class || $propertyType instanceof ErrorType || $propertyType instanceof NeverType) { diff --git a/src/Rules/Doctrine/ORM/EntityRelationRule.php b/src/Rules/Doctrine/ORM/EntityRelationRule.php index 62f8a22f..84ce9120 100644 --- a/src/Rules/Doctrine/ORM/EntityRelationRule.php +++ b/src/Rules/Doctrine/ORM/EntityRelationRule.php @@ -13,7 +13,6 @@ use PHPStan\Type\MixedType; use PHPStan\Type\NeverType; use PHPStan\Type\ObjectType; -use PHPStan\Type\ParserNodeTypeToPHPStanType; use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypehintHelper; use PHPStan\Type\VerbosityLevel; @@ -96,7 +95,7 @@ public function processNode(Node $node, Scope $scope): array } $phpDocType = $node->getPhpDocType(); - $nativeType = $node->getNativeType() !== null ? ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $scope->getClassReflection()) : new MixedType(); + $nativeType = $node->getNativeType() ?? new MixedType(); $propertyType = TypehintHelper::decideType($nativeType, $phpDocType); $errors = []; diff --git a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php index 60c17e79..7781fc9f 100644 --- a/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/DBAL/RowCountMethodDynamicReturnTypeExtension.php @@ -16,6 +16,7 @@ class RowCountMethodDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { + /** @var class-string */ private string $class; private ObjectMetadataResolver $objectMetadataResolver; @@ -24,6 +25,9 @@ class RowCountMethodDynamicReturnTypeExtension implements DynamicMethodReturnTyp private ReflectionProvider $reflectionProvider; + /** + * @param class-string $class + */ public function __construct( string $class, ObjectMetadataResolver $objectMetadataResolver, diff --git a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php index 8daaece8..07d40ffa 100644 --- a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php @@ -35,10 +35,14 @@ class GetRepositoryDynamicReturnTypeExtension implements DynamicMethodReturnType private ?string $odmRepositoryClass = null; + /** @var class-string */ private string $managerClass; private ObjectMetadataResolver $metadataResolver; + /** + * @param class-string $managerClass + */ public function __construct( ReflectionProvider $reflectionProvider, ?string $repositoryClass, diff --git a/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php index 6f9a69c8..79206e1c 100644 --- a/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/Expr/NewExprDynamicReturnTypeExtension.php @@ -20,10 +20,14 @@ class NewExprDynamicReturnTypeExtension implements DynamicStaticMethodReturnType private ArgumentsProcessor $argumentsProcessor; + /** @var class-string */ private string $class; private ReflectionProvider $reflectionProvider; + /** + * @param class-string $class + */ public function __construct( ArgumentsProcessor $argumentsProcessor, string $class, diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php index c6f4a5a7..69ceb824 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetDqlDynamicReturnTypeExtension.php @@ -13,8 +13,12 @@ class QueryBuilderGetDqlDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { + /** @var class-string|null */ private ?string $queryBuilderClass = null; + /** + * @param class-string|null $queryBuilderClass + */ public function __construct( ?string $queryBuilderClass ) diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php index b02018be..98fdefb3 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php @@ -59,6 +59,7 @@ class QueryBuilderGetQueryDynamicReturnTypeExtension implements DynamicMethodRet private ArgumentsProcessor $argumentsProcessor; + /** @var class-string|null */ private ?string $queryBuilderClass = null; private DescriptorRegistry $descriptorRegistry; @@ -67,6 +68,9 @@ class QueryBuilderGetQueryDynamicReturnTypeExtension implements DynamicMethodRet private DriverDetector $driverDetector; + /** + * @param class-string|null $queryBuilderClass + */ public function __construct( ObjectMetadataResolver $objectMetadataResolver, ArgumentsProcessor $argumentsProcessor, diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php index 67003dc6..0c6d9266 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderMethodDynamicReturnTypeExtension.php @@ -22,8 +22,12 @@ class QueryBuilderMethodDynamicReturnTypeExtension implements DynamicMethodRetur private const MAX_COMBINATIONS = 16; + /** @var class-string|null */ private ?string $queryBuilderClass = null; + /** + * @param class-string|null $queryBuilderClass + */ public function __construct( ?string $queryBuilderClass ) diff --git a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php index a6ab404d..66b18f71 100644 --- a/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/QueryBuilder/QueryBuilderTypeSpecifyingExtension.php @@ -24,10 +24,14 @@ class QueryBuilderTypeSpecifyingExtension implements MethodTypeSpecifyingExtensi private const MAX_COMBINATIONS = 16; + /** @var class-string|null */ private ?string $queryBuilderClass = null; private TypeSpecifier $typeSpecifier; + /** + * @param class-string|null $queryBuilderClass + */ public function __construct(?string $queryBuilderClass) { $this->queryBuilderClass = $queryBuilderClass; diff --git a/stubs/MongoClassMetadataInfo.stub b/stubs/MongoClassMetadataInfo.stub index cfdba938..433ef2a4 100644 --- a/stubs/MongoClassMetadataInfo.stub +++ b/stubs/MongoClassMetadataInfo.stub @@ -15,11 +15,6 @@ class ClassMetadata implements BaseClassMetadata /** @var string|null */ public $customRepositoryClassName; - /** - * @var class-string - */ - public $name; - /** * @param class-string $documentName */ diff --git a/tests/DoctrineIntegration/ORM/EntityRepositoryDynamicReturnIntegrationTest.php b/tests/DoctrineIntegration/ORM/EntityRepositoryDynamicReturnIntegrationTest.php index e64f096d..de7910fc 100644 --- a/tests/DoctrineIntegration/ORM/EntityRepositoryDynamicReturnIntegrationTest.php +++ b/tests/DoctrineIntegration/ORM/EntityRepositoryDynamicReturnIntegrationTest.php @@ -10,7 +10,7 @@ final class EntityRepositoryDynamicReturnIntegrationTest extends LevelsTestCase /** * @return string[][] */ - public function dataTopics(): array + public static function dataTopics(): array { return [ ['entityRepositoryDynamicReturn'], diff --git a/tests/DoctrineIntegration/ORM/EntityRepositoryWithoutObjectManagerLoaderDynamicReturnIntegrationTest.php b/tests/DoctrineIntegration/ORM/EntityRepositoryWithoutObjectManagerLoaderDynamicReturnIntegrationTest.php index bb2d04c1..ea596a6e 100644 --- a/tests/DoctrineIntegration/ORM/EntityRepositoryWithoutObjectManagerLoaderDynamicReturnIntegrationTest.php +++ b/tests/DoctrineIntegration/ORM/EntityRepositoryWithoutObjectManagerLoaderDynamicReturnIntegrationTest.php @@ -10,7 +10,7 @@ final class EntityRepositoryWithoutObjectManagerLoaderDynamicReturnIntegrationTe /** * @return string[][] */ - public function dataTopics(): array + public static function dataTopics(): array { return [ ['entityRepositoryDynamicReturn'], diff --git a/tests/Rules/Doctrine/ORM/FakeTestingUuidType.php b/tests/Rules/Doctrine/ORM/FakeTestingUuidType.php index fcb28f7e..f6255563 100644 --- a/tests/Rules/Doctrine/ORM/FakeTestingUuidType.php +++ b/tests/Rules/Doctrine/ORM/FakeTestingUuidType.php @@ -47,6 +47,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str return null; } + /** @throws ConversionException */ return (string) $value; } From 14a59bb5b719d3740224b6ba8aec80c0294142f9 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 7 Oct 2024 09:02:25 +0200 Subject: [PATCH 20/39] Fix stub --- stubs/MongoClassMetadataInfo.stub | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stubs/MongoClassMetadataInfo.stub b/stubs/MongoClassMetadataInfo.stub index 433ef2a4..65cfa40f 100644 --- a/stubs/MongoClassMetadataInfo.stub +++ b/stubs/MongoClassMetadataInfo.stub @@ -15,6 +15,12 @@ class ClassMetadata implements BaseClassMetadata /** @var string|null */ public $customRepositoryClassName; + /** + * @readonly + * @var class-string + */ + public $name; + /** * @param class-string $documentName */ From bcb88b6f1690052fcc45e6bfbc65921fe4385457 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 7 Oct 2024 09:10:55 +0200 Subject: [PATCH 21/39] Fix tests after PHPStan update --- tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php index d03da719..f0a799e6 100644 --- a/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php +++ b/tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php @@ -159,7 +159,7 @@ public function testRule(?string $objectManagerLoader): void 156, ], [ - 'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidSimpleArray type mapping mismatch: database can contain array but property expects array.', + 'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidSimpleArray type mapping mismatch: database can contain list but property expects array.', 162, ], [ @@ -230,7 +230,7 @@ public function testRuleWithAllowedNullableProperty(?string $objectManagerLoader 156, ], [ - 'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidSimpleArray type mapping mismatch: database can contain array but property expects array.', + 'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidSimpleArray type mapping mismatch: database can contain list but property expects array.', 162, ], [ @@ -399,7 +399,7 @@ public function testEnumType(?string $objectManagerLoader): void 45, ], [ - 'Property PHPStan\Rules\Doctrine\ORMAttributes\Foo::$type5 type mapping mismatch: database can contain array but property expects PHPStan\Rules\Doctrine\ORMAttributes\FooEnum.', + 'Property PHPStan\Rules\Doctrine\ORMAttributes\Foo::$type5 type mapping mismatch: database can contain list but property expects PHPStan\Rules\Doctrine\ORMAttributes\FooEnum.', 51, ], [ From 4a00482cf3b27c9ee6ec41970d543554f0c716fe Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 7 Oct 2024 11:15:08 +0200 Subject: [PATCH 22/39] Fixes after PHPStan update --- src/Type/Doctrine/Query/QueryType.php | 6 +++--- .../Doctrine/QueryBuilder/BranchingQueryBuilderType.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Type/Doctrine/Query/QueryType.php b/src/Type/Doctrine/Query/QueryType.php index ead7ef2b..53842dd2 100644 --- a/src/Type/Doctrine/Query/QueryType.php +++ b/src/Type/Doctrine/Query/QueryType.php @@ -2,8 +2,8 @@ namespace PHPStan\Type\Doctrine\Query; -use PHPStan\TrinaryLogic; use PHPStan\Type\Generic\GenericObjectType; +use PHPStan\Type\IsSuperTypeOfResult; use PHPStan\Type\MixedType; use PHPStan\Type\Type; @@ -44,10 +44,10 @@ public function changeSubtractedType(?Type $subtractedType): Type return new self('Doctrine\ORM\Query', $this->indexType, $this->resultType, $subtractedType); } - public function isSuperTypeOf(Type $type): TrinaryLogic + public function isSuperTypeOf(Type $type): IsSuperTypeOfResult { if ($type instanceof self) { - return TrinaryLogic::createFromBoolean($this->equals($type)); + return IsSuperTypeOfResult::createFromBoolean($this->equals($type)); } return parent::isSuperTypeOf($type); diff --git a/src/Type/Doctrine/QueryBuilder/BranchingQueryBuilderType.php b/src/Type/Doctrine/QueryBuilder/BranchingQueryBuilderType.php index e9c7bfb8..473dffb5 100644 --- a/src/Type/Doctrine/QueryBuilder/BranchingQueryBuilderType.php +++ b/src/Type/Doctrine/QueryBuilder/BranchingQueryBuilderType.php @@ -2,7 +2,7 @@ namespace PHPStan\Type\Doctrine\QueryBuilder; -use PHPStan\TrinaryLogic; +use PHPStan\Type\IsSuperTypeOfResult; use PHPStan\Type\Type; use function array_keys; use function count; @@ -35,10 +35,10 @@ public function equals(Type $type): bool return parent::equals($type); } - public function isSuperTypeOf(Type $type): TrinaryLogic + public function isSuperTypeOf(Type $type): IsSuperTypeOfResult { if ($type instanceof parent) { - return TrinaryLogic::createFromBoolean($this->equals($type)); + return IsSuperTypeOfResult::createFromBoolean($this->equals($type)); } return parent::isSuperTypeOf($type); From 8b557dec231a93bc7aaab9d449ce4d28d4cee5ff Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Tue, 8 Oct 2024 11:05:12 +0200 Subject: [PATCH 23/39] Readme: `index by` is supported --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83bc5364..c8a587b1 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ $query->getResult(); // array Queries are analyzed statically and do not require a running database server. This makes use of the Doctrine DQL parser and entities metadata. -Most DQL features are supported, including `GROUP BY`, `DISTINCT`, all flavors of `JOIN`, arithmetic expressions, functions, aggregations, `NEW`, etc. Sub queries and `INDEX BY` are not yet supported (infered type will be `mixed`). +Most DQL features are supported, including `GROUP BY`, `INDEX BY`, `DISTINCT`, all flavors of `JOIN`, arithmetic expressions, functions, aggregations, `NEW`, etc. Sub queries are not yet supported (infered type will be `mixed`). ### Query type inference of expressions From b129887388641766b5d306492351b96a4ee7cbe4 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 9 Oct 2024 16:39:36 +0200 Subject: [PATCH 24/39] Cleanup `skipCheckGenericClasses` --- extension.neon | 9 --------- 1 file changed, 9 deletions(-) diff --git a/extension.neon b/extension.neon index b8f68a86..6b09c624 100644 --- a/extension.neon +++ b/extension.neon @@ -10,15 +10,6 @@ parameters: allCollectionsSelectable: true objectManagerLoader: null literalString: false - featureToggles: - skipCheckGenericClasses: - - Doctrine\ODM\MongoDB\Mapping\ClassMetadata - - Doctrine\ORM\Mapping\ClassMetadata - - Doctrine\ORM\Mapping\ClassMetadataInfo - - Doctrine\Persistence\Mapping\ClassMetadata - - Doctrine\ORM\AbstractQuery - - Doctrine\ORM\Query - - Doctrine\ORM\Tools\Pagination\Paginator stubFiles: - stubs/Criteria.stub - stubs/DBAL/Cache/CacheException.stub From 992a62e337eff90308e88c67f5a807ab21ffe644 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 14 Oct 2024 05:21:12 +0200 Subject: [PATCH 25/39] Fix after PHPStan update --- tests/Type/Doctrine/data/QueryResult/queryResult.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Type/Doctrine/data/QueryResult/queryResult.php b/tests/Type/Doctrine/data/QueryResult/queryResult.php index de4cc5bf..54eef205 100644 --- a/tests/Type/Doctrine/data/QueryResult/queryResult.php +++ b/tests/Type/Doctrine/data/QueryResult/queryResult.php @@ -169,7 +169,7 @@ public function testReturnTypeOfQueryMethodsWithExplicitArrayHydrationMode(Entit ); assertType( - 'array', + 'array', $query->getArrayResult() ); assertType( From e26fd3c8969d7e2a4c3056f6a2585cb7d5a752db Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 14 Oct 2024 05:51:47 +0200 Subject: [PATCH 26/39] Fix nonexistent BackedEnum in stubs --- compatibility/BackedEnum.stub | 6 ++++++ phpstan.neon | 6 ++++++ tests/BackedEnumStubExtension.php | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 compatibility/BackedEnum.stub create mode 100644 tests/BackedEnumStubExtension.php diff --git a/compatibility/BackedEnum.stub b/compatibility/BackedEnum.stub new file mode 100644 index 00000000..2376a2fc --- /dev/null +++ b/compatibility/BackedEnum.stub @@ -0,0 +1,6 @@ += 80100) { + return []; + } + + return [ + __DIR__ . '/../compatibility/BackedEnum.stub', + ]; + } + +} From 815d5ae40ffe3a7788df1cd557e30e474f3aba1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Mirtes?= Date: Tue, 28 Jan 2025 10:26:47 +0100 Subject: [PATCH 27/39] Update LICENSE --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index 7c0f2b7b..e5f34e60 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2016 Ondřej Mirtes +Copyright (c) 2025 PHPStan s.r.o. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From a61a04a361b60014ec04881ccb87252d3bf02e94 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Mon, 3 Mar 2025 10:22:39 +0100 Subject: [PATCH 28/39] EntityRepository.stub fix nullability in findOneBy --- stubs/EntityRepository.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/EntityRepository.stub b/stubs/EntityRepository.stub index 4dcde8bf..784b14c8 100644 --- a/stubs/EntityRepository.stub +++ b/stubs/EntityRepository.stub @@ -42,7 +42,7 @@ class EntityRepository implements ObjectRepository * @phpstan-param array|null $orderBy * @phpstan-return TEntityClass|null */ - public function findOneBy(array $criteria, array $orderBy = null); + public function findOneBy(array $criteria, ?array $orderBy = null); /** * @phpstan-return class-string From baf73e368f2cbdc13ced4c42df3269ba577621a0 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Tue, 18 Mar 2025 11:17:26 +0100 Subject: [PATCH 29/39] Introduce phpstan-deprecation-rules --- composer.json | 1 + phpstan-baseline-deprecations.neon | 127 ++++++++++++++++++ phpstan-baseline-orm-3.neon | 99 ++++++++++++++ phpstan.neon | 2 + .../IsEmptyTypeSpecifyingExtension.php | 7 +- 5 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 phpstan-baseline-deprecations.neon diff --git a/composer.json b/composer.json index daedadb0..4ce656ed 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,7 @@ "gedmo/doctrine-extensions": "^3.8", "nesbot/carbon": "^2.49", "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9.6.20", diff --git a/phpstan-baseline-deprecations.neon b/phpstan-baseline-deprecations.neon new file mode 100644 index 00000000..bd96685e --- /dev/null +++ b/phpstan-baseline-deprecations.neon @@ -0,0 +1,127 @@ +parameters: + ignoreErrors: + - + message: ''' + #^Fetching class constant class of deprecated class Doctrine\\DBAL\\Types\\ArrayType\: + Use \{@link JsonType\} instead\.$# + ''' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Type/Doctrine/Descriptors/ArrayType.php + + - + message: ''' + #^Fetching class constant class of deprecated class Doctrine\\DBAL\\Types\\ObjectType\: + Use \{@link JsonType\} instead\.$# + ''' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Type/Doctrine/Descriptors/ObjectType.php + + - + message: ''' + #^Call to deprecated method getSchemaManager\(\) of class Doctrine\\DBAL\\Connection\: + Use \{@see createSchemaManager\(\)\} instead\.$# + ''' + identifier: method.deprecated + count: 1 + path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + + - + message: ''' + #^Fetching class constant class of deprecated class Doctrine\\DBAL\\Types\\ArrayType\: + Use \{@link JsonType\} instead\.$# + ''' + identifier: classConstant.deprecatedClass + count: 1 + path: tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php + + - + message: ''' + #^Call to deprecated method create\(\) of class Doctrine\\ORM\\EntityManager\: + Use \{@see DriverManager\:\:getConnection\(\)\} to bootstrap the connection and call the constructor\.$# + ''' + identifier: staticMethod.deprecated + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + + - + message: ''' + #^Fetching class constant class of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Classes/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/DoctrineIntegration/ORM/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Rules/DeadCode/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Rules/Properties/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Type/Doctrine/DBAL/mysqli.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Type/Doctrine/DBAL/pdo.php diff --git a/phpstan-baseline-orm-3.neon b/phpstan-baseline-orm-3.neon index 92e5f87c..ae5e8dfd 100644 --- a/phpstan-baseline-orm-3.neon +++ b/phpstan-baseline-orm-3.neon @@ -54,3 +54,102 @@ parameters: message: "#^Parameter \\#2 \\$className of static method Doctrine\\\\DBAL\\\\Types\\\\Type\\:\\:addType\\(\\) expects class\\-string\\, string given\\.$#" count: 1 path: tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php + + - + message: ''' + #^Fetching class constant class of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Classes/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/DoctrineIntegration/ORM/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Rules/DeadCode/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Rules/Properties/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Type/Doctrine/DBAL/mysqli.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\. + Copyright \(c\) Doctrine Project + From https\://github\.com/doctrine/orm/blob/40fbbf4429b0d66517244051237a2bd0616a7a13/src/Mapping/Driver/AnnotationDriver\.php$# + ''' + identifier: new.deprecated + count: 1 + path: tests/Type/Doctrine/DBAL/pdo.php diff --git a/phpstan.neon b/phpstan.neon index 8009fd82..efbf455d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,9 +2,11 @@ includes: - extension.neon - rules.neon - phpstan-baseline.neon + - phpstan-baseline-deprecations.neon - phpstan-baseline-dbal-3.neon - compatibility/orm-3-baseline.php - vendor/phpstan/phpstan-strict-rules/rules.neon + - vendor/phpstan/phpstan-deprecation-rules/rules.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon - phar://phpstan.phar/conf/bleedingEdge.neon diff --git a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php index 32765e79..9a177304 100644 --- a/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php @@ -43,11 +43,8 @@ public function isMethodSupported( TypeSpecifierContext $context ): bool { - return ( - $methodReflection->getDeclaringClass()->getName() === $this->collectionClass - || $methodReflection->getDeclaringClass()->isSubclassOf($this->collectionClass) - ) - && $methodReflection->getName() === self::IS_EMPTY_METHOD_NAME; + return $methodReflection->getDeclaringClass()->is($this->collectionClass) + && $methodReflection->getName() === self::IS_EMPTY_METHOD_NAME; } public function specifyTypes( From 6d00a6c08c934dd02b9d77b1ec32518378922e63 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 02:32:35 +0000 Subject: [PATCH 30/39] Update metcalfc/changelog-generator action to v4.5.0 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1a669a9..be6cad08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.3.1 + uses: metcalfc/changelog-generator@v4.5.0 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }} From ce89f09ef294aae03e08133313014d8d542d835a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 02:34:18 +0000 Subject: [PATCH 31/39] Update metcalfc/changelog-generator action to v4.6.2 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be6cad08..b8c96d48 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.5.0 + uses: metcalfc/changelog-generator@v4.6.2 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }} From 6317ec1d1ba6cd4ad6ee1e78f17ece1d1eb7f3de Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 19 Apr 2025 22:03:22 +0200 Subject: [PATCH 32/39] Fix build --- composer.json | 4 ++-- phpstan-baseline.neon | 54 +++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index 1fd25ef6..24ea4782 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.10" + "phpstan/phpstan": "^2.1.13" }, "conflict": { "doctrine/collections": "<1.0", @@ -31,7 +31,7 @@ "gedmo/doctrine-extensions": "^3.8", "nesbot/carbon": "^2.49", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.2", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9.6.20", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index cc1e2048..73d72b45 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,71 +1,85 @@ parameters: ignoreErrors: - - message: "#^Calling PHPStan\\\\Type\\\\ParserNodeTypeToPHPStanType\\:\\:resolve\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" - count: 1 - path: src/Rules/Doctrine/ORM/EntityColumnRule.php + message: '#^Call to internal method Doctrine\\DBAL\\Connection\:\:getParams\(\) from outside its root namespace Doctrine\.$#' + identifier: method.internal + count: 2 + path: src/Doctrine/Driver/DriverDetector.php - - message: "#^Calling PHPStan\\\\Type\\\\TypehintHelper\\:\\:decideType\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" + message: '#^Calling PHPStan\\Type\\TypehintHelper\:\:decideType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method count: 1 path: src/Rules/Doctrine/ORM/EntityColumnRule.php - - message: "#^Calling PHPStan\\\\Type\\\\ParserNodeTypeToPHPStanType\\:\\:resolve\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" - count: 1 - path: src/Rules/Doctrine/ORM/EntityRelationRule.php - - - - message: "#^Calling PHPStan\\\\Type\\\\TypehintHelper\\:\\:decideType\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" + message: '#^Calling PHPStan\\Type\\TypehintHelper\:\:decideType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method count: 1 path: src/Rules/Doctrine/ORM/EntityRelationRule.php - - message: "#^PHPDoc tag @var with type class\\-string is not subtype of native type 'Doctrine\\\\\\\\Bundle…'\\.$#" + message: '#^PHPDoc tag @var with type class\-string is not subtype of native type ''Doctrine\\\\Bundle…''\.$#' + identifier: varTag.nativeType count: 1 path: src/Stubs/Doctrine/StubFilesExtensionLoader.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Classes\\\\InstantiationRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Classes\\InstantiationRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\DeadCode\\\\UnusedPrivatePropertyRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Call to internal method PHPUnit\\Framework\\TestCase\:\:dataName\(\) from outside its root namespace PHPUnit\.$#' + identifier: method.internal + count: 14 + path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + + - + message: '#^Accessing PHPStan\\Rules\\DeadCode\\UnusedPrivatePropertyRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Methods\\\\CallMethodsRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Methods\\CallMethodsRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Doctrine/ORM/MagicRepositoryMethodCallRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Exceptions\\\\CatchWithUnthrownExceptionRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Exceptions\\CatchWithUnthrownExceptionRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Exceptions\\\\TooWideMethodThrowTypeRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Exceptions\\TooWideMethodThrowTypeRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Exceptions/TooWideMethodThrowTypeRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\DeadCode\\\\UnusedPrivatePropertyRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\DeadCode\\UnusedPrivatePropertyRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Properties/MissingGedmoByPhpDocPropertyAssignRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\DeadCode\\\\UnusedPrivatePropertyRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\DeadCode\\UnusedPrivatePropertyRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Properties/MissingGedmoPropertyAssignRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Properties\\\\MissingReadOnlyByPhpDocPropertyAssignRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Properties\\MissingReadOnlyByPhpDocPropertyAssignRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRuleTest.php - - message: "#^Accessing PHPStan\\\\Rules\\\\Properties\\\\MissingReadOnlyPropertyAssignRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Accessing PHPStan\\Rules\\Properties\\MissingReadOnlyPropertyAssignRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Properties/MissingReadOnlyPropertyAssignRuleTest.php From 93d1307c50079c9d8447d72f73ca0b888cb75a07 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 24 Apr 2025 17:49:40 +0200 Subject: [PATCH 33/39] Fix build --- phpstan-baseline.neon | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 73d72b45..15848bab 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -24,6 +24,12 @@ parameters: count: 1 path: src/Stubs/Doctrine/StubFilesExtensionLoader.php + - + message: '#^Parameter references internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional in its type\.$#' + identifier: parameter.internalInterface + count: 2 + path: src/Type/Doctrine/Query/QueryResultTypeWalker.php + - message: '#^Accessing PHPStan\\Rules\\Classes\\InstantiationRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' identifier: phpstanApi.classConstant From 8e76755816cece825b91c96034f969f673864593 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Thu, 24 Apr 2025 17:47:35 +0200 Subject: [PATCH 34/39] Use stable PHP 8.4 with xdebug in docker image --- tests/Platform/docker/Dockerfile84 | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/Platform/docker/Dockerfile84 b/tests/Platform/docker/Dockerfile84 index 81ac9834..30b47ed2 100644 --- a/tests/Platform/docker/Dockerfile84 +++ b/tests/Platform/docker/Dockerfile84 @@ -1,4 +1,4 @@ -FROM php:8.4.0beta4-cli +FROM php:8.4-cli # MSSQL RUN apt update \ @@ -12,13 +12,8 @@ RUN apt update \ && pecl install pdo_sqlsrv \ && docker-php-ext-enable sqlsrv pdo_sqlsrv -RUN set -ex \ - && apt update \ - && apt install -y bash zip libpq-dev libsqlite3-dev \ - && pecl install xdebug-3.4 mongodb \ - && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ - && docker-php-ext-install pdo mysqli pgsql pdo_mysql pdo_pgsql pdo_sqlite \ - && docker-php-ext-enable mongodb # TODO xdebug not yet supported here +COPY ./docker-setup.sh /opt/src/scripts/setup.sh +RUN /opt/src/scripts/setup.sh COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer From b22695147e835fdcd117624a7f9ad2c943c80af7 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 25 Apr 2025 22:36:15 +0200 Subject: [PATCH 35/39] Fix build --- phpstan-baseline.neon | 50 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 15848bab..01f874ed 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6,6 +6,12 @@ parameters: count: 2 path: src/Doctrine/Driver/DriverDetector.php + - + message: '#^Access to constant on deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\.$#' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + - message: '#^Calling PHPStan\\Type\\TypehintHelper\:\:decideType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' identifier: phpstanApi.method @@ -25,11 +31,47 @@ parameters: path: src/Stubs/Doctrine/StubFilesExtensionLoader.php - - message: '#^Parameter references internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional in its type\.$#' + message: '#^Catching deprecated class Doctrine\\Common\\CommonException\.$#' + identifier: catch.deprecatedClass + count: 1 + path: src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php + + - + message: '#^Catching deprecated class Doctrine\\ORM\\ORMException\.$#' + identifier: catch.deprecatedClass + count: 1 + path: src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php + + - + message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\.$#' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Type/Doctrine/Descriptors/ArrayType.php + + - + message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ObjectType\.$#' + identifier: classConstant.deprecatedClass + count: 1 + path: src/Type/Doctrine/Descriptors/ObjectType.php + + - + message: '#^Parameter \$condExpr references internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional in its type\.$#' identifier: parameter.internalInterface count: 2 path: src/Type/Doctrine/Query/QueryResultTypeWalker.php + - + message: '#^Catching deprecated class Doctrine\\Common\\CommonException\.$#' + identifier: catch.deprecatedClass + count: 1 + path: src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php + + - + message: '#^Catching deprecated class Doctrine\\ORM\\ORMException\.$#' + identifier: catch.deprecatedClass + count: 1 + path: src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php + - message: '#^Accessing PHPStan\\Rules\\Classes\\InstantiationRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' identifier: phpstanApi.classConstant @@ -48,6 +90,12 @@ parameters: count: 1 path: tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php + - + message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\.$#' + identifier: classConstant.deprecatedClass + count: 1 + path: tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php + - message: '#^Accessing PHPStan\\Rules\\Methods\\CallMethodsRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' identifier: phpstanApi.classConstant From 1a479e5d212bb5f9191a164d28df7e89c1bb5cc2 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 26 Apr 2025 11:30:51 +0200 Subject: [PATCH 36/39] Fix build --- phpstan-baseline.neon | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 01f874ed..38a63aef 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -55,9 +55,15 @@ parameters: path: src/Type/Doctrine/Descriptors/ObjectType.php - - message: '#^Parameter \$condExpr references internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional in its type\.$#' + message: '#^Parameter \$condExpr of method PHPStan\\Type\\Doctrine\\Query\\QueryResultTypeWalker\:\:walkConditionalExpression\(\) has typehint with internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional\.$#' identifier: parameter.internalInterface - count: 2 + count: 1 + path: src/Type/Doctrine/Query/QueryResultTypeWalker.php + + - + message: '#^Parameter \$condExpr of method PHPStan\\Type\\Doctrine\\Query\\QueryResultTypeWalker\:\:walkJoinAssociationDeclaration\(\) has typehint with internal interface Doctrine\\ORM\\Query\\AST\\Phase2OptimizableConditional\.$#' + identifier: parameter.internalInterface + count: 1 path: src/Type/Doctrine/Query/QueryResultTypeWalker.php - From 913dac215f5f5ba8ba800780243461f4a9859e31 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 26 Apr 2025 11:36:04 +0200 Subject: [PATCH 37/39] Fix test-projects.yml --- .github/workflows/test-projects.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-projects.yml b/.github/workflows/test-projects.yml index 2b85f70e..6f3a7fb7 100644 --- a/.github/workflows/test-projects.yml +++ b/.github/workflows/test-projects.yml @@ -26,4 +26,4 @@ jobs: token: ${{ secrets.REPO_ACCESS_TOKEN }} repository: "${{ matrix.repository }}" event-type: test_phpstan - client-payload: '{"ref": "1.11.x"}' + client-payload: '{"ref": "${{ github.ref_name }}"}' From 3bf5dc8cf97dd1fd8b2d8ba160b400fc7afeee2f Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 26 Apr 2025 22:06:31 +0200 Subject: [PATCH 38/39] Fix build --- phpstan-baseline.neon | 112 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 8 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 38a63aef..64b1a032 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7,11 +7,23 @@ parameters: path: src/Doctrine/Driver/DriverDetector.php - - message: '#^Access to constant on deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\.$#' + message: ''' + #^Access to constant on deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' identifier: classConstant.deprecatedClass count: 1 path: src/Doctrine/Mapping/ClassMetadataFactory.php + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: src/Doctrine/Mapping/ClassMetadataFactory.php + - message: '#^Calling PHPStan\\Type\\TypehintHelper\:\:decideType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' identifier: phpstanApi.method @@ -31,25 +43,37 @@ parameters: path: src/Stubs/Doctrine/StubFilesExtensionLoader.php - - message: '#^Catching deprecated class Doctrine\\Common\\CommonException\.$#' + message: ''' + #^Catching deprecated class Doctrine\\Common\\CommonException\: + The doctrine/common package is deprecated, please use specific packages and their exceptions instead\.$# + ''' identifier: catch.deprecatedClass count: 1 path: src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php - - message: '#^Catching deprecated class Doctrine\\ORM\\ORMException\.$#' + message: ''' + #^Catching deprecated class Doctrine\\ORM\\ORMException\: + Use Doctrine\\ORM\\Exception\\ORMException for catch and instanceof$# + ''' identifier: catch.deprecatedClass count: 1 path: src/Type/Doctrine/CreateQueryDynamicReturnTypeExtension.php - - message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\.$#' + message: ''' + #^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\: + Use \{@link JsonType\} instead\.$# + ''' identifier: classConstant.deprecatedClass count: 1 path: src/Type/Doctrine/Descriptors/ArrayType.php - - message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ObjectType\.$#' + message: ''' + #^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ObjectType\: + Use \{@link JsonType\} instead\.$# + ''' identifier: classConstant.deprecatedClass count: 1 path: src/Type/Doctrine/Descriptors/ObjectType.php @@ -67,13 +91,19 @@ parameters: path: src/Type/Doctrine/Query/QueryResultTypeWalker.php - - message: '#^Catching deprecated class Doctrine\\Common\\CommonException\.$#' + message: ''' + #^Catching deprecated class Doctrine\\Common\\CommonException\: + The doctrine/common package is deprecated, please use specific packages and their exceptions instead\.$# + ''' identifier: catch.deprecatedClass count: 1 path: src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php - - message: '#^Catching deprecated class Doctrine\\ORM\\ORMException\.$#' + message: ''' + #^Catching deprecated class Doctrine\\ORM\\ORMException\: + Use Doctrine\\ORM\\Exception\\ORMException for catch and instanceof$# + ''' identifier: catch.deprecatedClass count: 1 path: src/Type/Doctrine/QueryBuilder/QueryBuilderGetQueryDynamicReturnTypeExtension.php @@ -84,12 +114,39 @@ parameters: count: 1 path: tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Classes/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/DoctrineIntegration/ORM/entity-manager.php + - message: '#^Call to internal method PHPUnit\\Framework\\TestCase\:\:dataName\(\) from outside its root namespace PHPUnit\.$#' identifier: method.internal count: 14 path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php + - message: '#^Accessing PHPStan\\Rules\\DeadCode\\UnusedPrivatePropertyRule\:\:class is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' identifier: phpstanApi.classConstant @@ -97,7 +154,19 @@ parameters: path: tests/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php - - message: '#^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\.$#' + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Rules/DeadCode/entity-manager.php + + - + message: ''' + #^Access to constant on deprecated class Doctrine\\DBAL\\Types\\ArrayType\: + Use \{@link JsonType\} instead\.$# + ''' identifier: classConstant.deprecatedClass count: 1 path: tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php @@ -143,3 +212,30 @@ parameters: identifier: phpstanApi.classConstant count: 1 path: tests/Rules/Properties/MissingReadOnlyPropertyAssignRuleTest.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Rules/Properties/entity-manager.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Type/Doctrine/DBAL/mysqli.php + + - + message: ''' + #^Instantiation of deprecated class Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver\: + This class will be removed in 3\.0 without replacement\.$# + ''' + identifier: new.deprecatedClass + count: 1 + path: tests/Type/Doctrine/DBAL/pdo.php From b1209a31a7ffdfc31cd37142a03e172a97827265 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 26 Apr 2025 22:11:07 +0200 Subject: [PATCH 39/39] Fix test-projects.yml --- .github/workflows/test-projects.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-projects.yml b/.github/workflows/test-projects.yml index 6f3a7fb7..cebc3431 100644 --- a/.github/workflows/test-projects.yml +++ b/.github/workflows/test-projects.yml @@ -26,4 +26,4 @@ jobs: token: ${{ secrets.REPO_ACCESS_TOKEN }} repository: "${{ matrix.repository }}" event-type: test_phpstan - client-payload: '{"ref": "${{ github.ref_name }}"}' + client-payload: '{"ref": "2.1.x"}'