Skip to content

Commit

Permalink
Remove use of Doctrine stub and and generic Doctrine result types (#705)
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm authored Nov 7, 2024
1 parent 415c4a6 commit 61a6233
Show file tree
Hide file tree
Showing 20 changed files with 115 additions and 70 deletions.
17 changes: 0 additions & 17 deletions config/DoctrineDbal.stub

This file was deleted.

9 changes: 0 additions & 9 deletions config/dba.neon
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
includes:
- stubFiles.neon
- extensions.neon
- rules.neon

parameters:
featureToggles:
skipCheckGenericClasses:
- Doctrine\DBAL\Result
- Doctrine\DBAL\Statement

duplicateStubs: false # workaround for: https://github.com/staabm/phpstan-dba/issues/466
3 changes: 0 additions & 3 deletions config/stubFiles.neon

This file was deleted.

1 change: 0 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- config/stubFiles.neon
- config/extensions.neon
- config/rules.neon
- phpstan-baseline.neon
Expand Down
4 changes: 2 additions & 2 deletions src/DoctrineReflection/DoctrineReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function createGenericStatement(iterable $queryStrings, int $reflectionFe
return null;
}

$genericObjects[] = new DoctrineStatementObjectType($resultType);
$genericObjects[] = DoctrineStatementObjectType::newWithRowType($resultType);
}

if (\count($genericObjects) > 1) {
Expand Down Expand Up @@ -173,7 +173,7 @@ public function createGenericResult(iterable $queryStrings, int $reflectionFetch
return null;
}

$genericObjects[] = new DoctrineResultObjectType($resultType);
$genericObjects[] = DoctrineResultObjectType::newWithRowType($resultType);
}

if (\count($genericObjects) > 1) {
Expand Down
54 changes: 48 additions & 6 deletions src/DoctrineReflection/DoctrineResultObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,62 @@
namespace staabm\PHPStanDba\DoctrineReflection;

use Doctrine\DBAL\Result;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

final class DoctrineResultObjectType extends GenericObjectType
final class DoctrineResultObjectType extends ObjectType
{
public function __construct(Type $rowType)
private ?Type $rowType;

public static function newWithRowType(Type $rowType): self
{
parent::__construct(Result::class, [$rowType]);
$new = new self(Result::class);
$new->rowType = $rowType;
return $new;
}

public function getRowType(): Type
{
$genericTypes = $this->getTypes();
if ($this->rowType === null) {
throw new ShouldNotHappenException();
}

return $this->rowType;
}

public function getIterableValueType(): Type
{
return $this->getRowType();
}

// differentiate objects based on the local properties,
// to make sure TypeCombinator::union() will not normalize separate objects away.
// this means we need to implement equals() and isSuperTypeOf().
public function equals(Type $type): bool
{
if ($type instanceof self
) {
return $type->rowType !== null
&& $this->rowType !== null
&& $type->rowType === $this->rowType
&& $type->rowType->equals($this->rowType);
}

return parent::equals($type);
}

public function isSuperTypeOf(Type $type): TrinaryLogic
{
if ($type instanceof self) {
return TrinaryLogic::createFromBoolean(
$type->rowType !== null
&& $this->rowType !== null
&& $type->rowType->equals($this->rowType)
);
}

return $genericTypes[0];
return parent::isSuperTypeOf($type);
}
}
57 changes: 53 additions & 4 deletions src/DoctrineReflection/DoctrineStatementObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,62 @@
namespace staabm\PHPStanDba\DoctrineReflection;

use Doctrine\DBAL\Statement;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

final class DoctrineStatementObjectType extends GenericObjectType
final class DoctrineStatementObjectType extends ObjectType
{
public function __construct(Type $rowType)
private ?Type $rowType;

public static function newWithRowType(Type $rowType): self
{
$new = new self(Statement::class);
$new->rowType = $rowType;
return $new;
}

public function getRowType(): Type
{
if ($this->rowType === null) {
throw new ShouldNotHappenException();
}

return $this->rowType;
}

public function getIterableValueType(): Type
{
parent::__construct(Statement::class, [$rowType]);
return $this->getRowType();
}

// differentiate objects based on the local properties,
// to make sure TypeCombinator::union() will not normalize separate objects away.
// this means we need to implement equals() and isSuperTypeOf().
public function equals(Type $type): bool
{
if ($type instanceof self
) {
return $type->rowType !== null
&& $this->rowType !== null
&& $type->rowType === $this->rowType
&& $type->rowType->equals($this->rowType);
}

return parent::equals($type);
}

public function isSuperTypeOf(Type $type): TrinaryLogic
{
if ($type instanceof self) {
return TrinaryLogic::createFromBoolean(
$type->rowType !== null
&& $this->rowType !== null
&& $type->rowType->equals($this->rowType)
);
}

return parent::isSuperTypeOf($type);
}
}
2 changes: 1 addition & 1 deletion tests/default/DbaInferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function dataFileAsserts(): iterable
throw new \Exception('doctrine/dbal 3.x is required to run tests for php 7.3+. Please install it via composer.');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/doctrine-dbal-union-result.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/doctrine-dbal.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/inference-placeholder.php');

Expand Down Expand Up @@ -90,7 +91,6 @@ public function testFileAsserts(
public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../config/stubFiles.neon',
__DIR__ . '/../../config/extensions.neon',
];
}
Expand Down
1 change: 0 additions & 1 deletion tests/default/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down
8 changes: 3 additions & 5 deletions tests/default/data/doctrine-dbal-union-result.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ public function doFoo(Connection $conn)

foreach ($queries as $query) {
$stmt = $conn->prepare($query);
assertType('Doctrine\DBAL\Statement<array{adaid: int<-32768, 32767>, 0: int<-32768, 32767>}>|Doctrine\DBAL\Statement<array{email: string, 0: string}>', $stmt);

$result = $stmt->executeQuery([]);
assertType('Doctrine\DBAL\Result<array{adaid: int<-32768, 32767>, 0: int<-32768, 32767>}>|Doctrine\DBAL\Result<array{email: string, 0: string}>', $result);
assertType('array{adaid: int<-32768, 32767>}|array{email: string}|false', $result->fetchAssociative());

$result = $stmt->execute([]);
assertType('Doctrine\DBAL\Result<array{adaid: int<-32768, 32767>, 0: int<-32768, 32767>}>|Doctrine\DBAL\Result<array{email: string, 0: string}>', $result);
assertType('array{adaid: int<-32768, 32767>}|array{email: string}|false', $result->fetchAssociative());

$fetch = $result->fetchOne();
assertType('int<-32768, 32767>|string|false', $fetch);
Expand All @@ -35,7 +33,7 @@ public function doBar(Connection $conn)

foreach ($queries as $query) {
$result = $conn->query($query);
assertType('Doctrine\DBAL\Result<array{adaid: int<-32768, 32767>, 0: int<-32768, 32767>}>|Doctrine\DBAL\Result<array{email: string, 0: string}>', $result);
assertType('array{adaid: int<-32768, 32767>}|array{email: string}|false', $result->fetchAssociative());
}
}
}
20 changes: 8 additions & 12 deletions tests/default/data/doctrine-dbal.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class Foo
public function foo(Connection $conn)
{
$result = $conn->query('SELECT email, adaid FROM ada');
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $result);

$columnCount = $result->columnCount();
assertType('2', $columnCount);
Expand Down Expand Up @@ -54,28 +53,25 @@ public function foo(Connection $conn)

public function executeQuery(Connection $conn, array $types, QueryCacheProfile $qcp)
{
$stmt = $conn->executeQuery('SELECT email, adaid FROM ada WHERE adaid = ?', [1]);
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $stmt);
$result = $conn->executeQuery('SELECT email, adaid FROM ada WHERE adaid = ?', [1]);
assertType('array{email: string, adaid: int<-32768, 32767>}|false', $result->fetchAssociative());

$stmt = $conn->executeCacheQuery('SELECT email, adaid FROM ada WHERE adaid = ?', [1], $types, $qcp);
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $stmt);
$result = $conn->executeCacheQuery('SELECT email, adaid FROM ada WHERE adaid = ?', [1], $types, $qcp);
assertType('array{email: string, adaid: int<-32768, 32767>}|false', $result->fetchAssociative());

$stmt = $conn->executeQuery('SELECT email, adaid FROM ada');
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $stmt);
$result = $conn->executeQuery('SELECT email, adaid FROM ada');
assertType('array{email: string, adaid: int<-32768, 32767>}|false', $result->fetchAssociative());
}

public function executeStatement(Connection $conn, int $adaid)
{
$stmt = $conn->prepare('SELECT email, adaid FROM ada');
assertType('Doctrine\DBAL\Statement<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $stmt);

$stmt = $conn->prepare('SELECT email, adaid FROM ada WHERE adaid = ?');
$result = $stmt->execute([$adaid]);
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $result);
assertType('array{email: string, adaid: int<-32768, 32767>}|false', $result->fetchAssociative());

$stmt = $conn->prepare('SELECT email, adaid FROM ada WHERE adaid = ?');
$result = $stmt->executeQuery([$adaid]);
assertType('Doctrine\DBAL\Result<array{email: string, 0: string, adaid: int<-32768, 32767>, 1: int<-32768, 32767>}>', $result);
assertType('array{email: string, adaid: int<-32768, 32767>}|false', $result->fetchAssociative());
}

public function fetchAssociative(Connection $conn)
Expand Down
1 change: 0 additions & 1 deletion tests/defaultFetchAssoc/DefaultFetchModeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public function testFileAsserts(
public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../config/stubFiles.neon',
__DIR__ . '/../../config/extensions.neon',
];
}
Expand Down
1 change: 0 additions & 1 deletion tests/defaultFetchAssoc/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down
1 change: 0 additions & 1 deletion tests/defaultFetchNumeric/DefaultFetchModeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public function testFileAsserts(
public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../config/stubFiles.neon',
__DIR__ . '/../../config/extensions.neon',
];
}
Expand Down
1 change: 0 additions & 1 deletion tests/defaultFetchNumeric/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down
1 change: 0 additions & 1 deletion tests/rules/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down
1 change: 0 additions & 1 deletion tests/sqlAst/SqlAstInferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public function testFileAsserts(
public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../config/stubFiles.neon',
__DIR__ . '/../../config/extensions.neon',
];
}
Expand Down
1 change: 0 additions & 1 deletion tests/sqlAst/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down
1 change: 0 additions & 1 deletion tests/stringify/InferenceStringifyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public function testFileAsserts(
public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../config/stubFiles.neon',
__DIR__ . '/../../config/extensions.neon',
];
}
Expand Down
1 change: 0 additions & 1 deletion tests/stringify/config/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
includes:
- ../../../config/stubFiles.neon
- ../../../config/extensions.neon

parameters:
Expand Down

0 comments on commit 61a6233

Please sign in to comment.