Skip to content

Commit bb5e1c8

Browse files
committed
fix
1 parent 385c676 commit bb5e1c8

File tree

3 files changed

+103
-11
lines changed

3 files changed

+103
-11
lines changed

src/DoctrineReflection/DoctrineReflection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function createGenericStatement(iterable $queryStrings, int $reflectionFe
144144
return null;
145145
}
146146

147-
$genericObjects[] = new DoctrineStatementObjectType($resultType);
147+
$genericObjects[] = DoctrineStatementObjectType::newWithRowType($resultType);
148148
}
149149

150150
if (\count($genericObjects) > 1) {
@@ -173,7 +173,7 @@ public function createGenericResult(iterable $queryStrings, int $reflectionFetch
173173
return null;
174174
}
175175

176-
$genericObjects[] = new DoctrineResultObjectType($resultType);
176+
$genericObjects[] = DoctrineResultObjectType::newWithRowType($resultType);
177177
}
178178

179179
if (\count($genericObjects) > 1) {

src/DoctrineReflection/DoctrineResultObjectType.php

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,63 @@
44

55
namespace staabm\PHPStanDba\DoctrineReflection;
66

7-
use Doctrine\DBAL\Result;
8-
use PHPStan\Type\Generic\GenericObjectType;
7+
use PHPStan\ShouldNotHappenException;
8+
use PHPStan\TrinaryLogic;
9+
use PHPStan\Type\ObjectType;
910
use PHPStan\Type\Type;
1011

11-
final class DoctrineResultObjectType extends GenericObjectType
12+
final class DoctrineResultObjectType extends ObjectType
1213
{
13-
public function __construct(Type $rowType)
14+
private ?Type $rowType;
15+
16+
public static function newWithRowType(Type $rowType): self
1417
{
15-
parent::__construct(Result::class, [$rowType]);
18+
$new = new self(Result::class);
19+
$new->rowType = $rowType;
20+
return $new;
1621
}
1722

1823
public function getRowType(): Type
1924
{
20-
$genericTypes = $this->getTypes();
25+
if ($this->rowType === null) {
26+
throw new ShouldNotHappenException();
27+
}
28+
29+
return $this->rowType;
30+
}
31+
32+
public function getIterableValueType(): Type
33+
{
34+
return $this->getRowType();
35+
}
36+
37+
// differentiate objects based on the local properties,
38+
// to make sure TypeCombinator::union() will not normalize separate objects away.
39+
// this means we need to implement equals() and isSuperTypeOf().
40+
public function equals(Type $type): bool
41+
{
42+
if ($type instanceof self
43+
) {
44+
return
45+
$type->rowType !== null
46+
&& $this->rowType !== null
47+
&& $type->rowType === $this->rowType
48+
&& $type->rowType->equals($this->rowType);
49+
}
50+
51+
return parent::equals($type);
52+
}
53+
54+
public function isSuperTypeOf(Type $type): TrinaryLogic
55+
{
56+
if ($type instanceof self) {
57+
return TrinaryLogic::createFromBoolean(
58+
$type->rowType !== null
59+
&& $this->rowType !== null
60+
&& $type->rowType->equals($this->rowType)
61+
);
62+
}
2163

22-
return $genericTypes[0];
64+
return parent::isSuperTypeOf($type);
2365
}
2466
}

src/DoctrineReflection/DoctrineStatementObjectType.php

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,63 @@
55
namespace staabm\PHPStanDba\DoctrineReflection;
66

77
use Doctrine\DBAL\Statement;
8+
use PHPStan\ShouldNotHappenException;
9+
use PHPStan\TrinaryLogic;
810
use PHPStan\Type\Generic\GenericObjectType;
911
use PHPStan\Type\Type;
1012

1113
final class DoctrineStatementObjectType extends GenericObjectType
1214
{
13-
public function __construct(Type $rowType)
15+
private ?Type $rowType;
16+
17+
public static function newWithRowType(Type $rowType): self
18+
{
19+
$new = new self(Statement::class);
20+
$new->rowType = $rowType;
21+
return $new;
22+
}
23+
24+
public function getRowType(): Type
25+
{
26+
if ($this->rowType === null) {
27+
throw new ShouldNotHappenException();
28+
}
29+
30+
return $this->rowType;
31+
}
32+
33+
public function getIterableValueType(): Type
1434
{
15-
parent::__construct(Statement::class, [$rowType]);
35+
return $this->getRowType();
36+
}
37+
38+
// differentiate objects based on the local properties,
39+
// to make sure TypeCombinator::union() will not normalize separate objects away.
40+
// this means we need to implement equals() and isSuperTypeOf().
41+
public function equals(Type $type): bool
42+
{
43+
if ($type instanceof self
44+
) {
45+
return
46+
$type->rowType !== null
47+
&& $this->rowType !== null
48+
&& $type->rowType === $this->rowType
49+
&& $type->rowType->equals($this->rowType);
50+
}
51+
52+
return parent::equals($type);
53+
}
54+
55+
public function isSuperTypeOf(Type $type): TrinaryLogic
56+
{
57+
if ($type instanceof self) {
58+
return TrinaryLogic::createFromBoolean(
59+
$type->rowType !== null
60+
&& $this->rowType !== null
61+
&& $type->rowType->equals($this->rowType)
62+
);
63+
}
64+
65+
return parent::isSuperTypeOf($type);
1666
}
1767
}

0 commit comments

Comments
 (0)