Skip to content

Commit 761c962

Browse files
committed
TypeSpecifier - resolve values from fetched constants
1 parent cc15493 commit 761c962

4 files changed

Lines changed: 76 additions & 15 deletions

File tree

src/Analyser/TypeSpecifier.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use PHPStan\Type\Constant\ConstantBooleanType;
2828
use PHPStan\Type\Constant\ConstantIntegerType;
2929
use PHPStan\Type\Constant\ConstantStringType;
30+
use PHPStan\Type\ConstantType;
3031
use PHPStan\Type\Generic\GenericClassStringType;
3132
use PHPStan\Type\IntegerRangeType;
3233
use PHPStan\Type\IntegerType;
@@ -232,29 +233,26 @@ public function specifyTypesInCondition(
232233
return $leftTypes->unionWith($rightTypes);
233234
}
234235

236+
$exprLeftType = $scope->getType($expr->left);
237+
$exprRightType = $scope->getType($expr->right);
238+
235239
if (
236-
(
237-
$expr->left instanceof Node\Scalar
238-
|| $expr->left instanceof Expr\Array_
239-
)
240-
&& !$expr->right instanceof Node\Scalar
240+
$exprLeftType instanceof ConstantType
241+
&& !$exprRightType instanceof ConstantType
241242
) {
242243
return $this->create(
243244
$expr->right,
244-
$scope->getType($expr->left),
245+
$exprLeftType,
245246
$context
246247
);
247248
}
248249
if (
249-
(
250-
$expr->right instanceof Node\Scalar
251-
|| $expr->right instanceof Expr\Array_
252-
)
253-
&& !$expr->left instanceof Node\Scalar
250+
$exprRightType instanceof ConstantType
251+
&& !$exprLeftType instanceof ConstantType
254252
) {
255253
return $this->create(
256254
$expr->left,
257-
$scope->getType($expr->right),
255+
$exprRightType,
258256
$context
259257
);
260258
}

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8925,7 +8925,7 @@ public function dataConstantTypeAfterDuplicateCondition(): array
89258925
"'afterFirst'",
89268926
],
89278927
[
8928-
'int',
8928+
'int<min, -1>|int<1, max>',
89298929
'$a',
89308930
"'afterSecond'",
89318931
],
@@ -8940,12 +8940,12 @@ public function dataConstantTypeAfterDuplicateCondition(): array
89408940
"'afterSecond'",
89418941
],
89428942
[
8943-
'int',
8943+
'int<min, -1>|int<1, max>',
89448944
'$a',
89458945
"'afterThird'",
89468946
],
89478947
[
8948-
'int',
8948+
'int<min, -1>|int<1, max>',
89498949
'$b',
89508950
"'afterThird'",
89518951
],
@@ -10453,6 +10453,11 @@ public function dataBug4207(): array
1045310453
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4207.php');
1045410454
}
1045510455

10456+
public function dataBug4206(): array
10457+
{
10458+
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4206.php');
10459+
}
10460+
1045610461
/**
1045710462
* @param string $file
1045810463
* @return array<string, mixed[]>
@@ -10643,6 +10648,7 @@ private function gatherAssertTypes(string $file): array
1064310648
* @dataProvider dataBug2945
1064410649
* @dataProvider dataInferPrivateTypedPropertyTypeFromConstructor
1064510650
* @dataProvider dataBug4207
10651+
* @dataProvider dataBug4206
1064610652
* @param string $assertType
1064710653
* @param string $file
1064810654
* @param mixed ...$args
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Bug4206;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
class Foo
8+
{
9+
10+
public const ONE = 1;
11+
public const TWO = 2;
12+
13+
}
14+
15+
function (int $i): void {
16+
if ($i === Foo::ONE) {
17+
assertType('1', $i);
18+
}
19+
20+
if ($i === Foo::TWO) {
21+
assertType('2', $i);
22+
}
23+
};

tests/PHPStan/Rules/Comparison/data/match-expr.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,38 @@ public function doBaz($obj): void
103103
};
104104
}
105105

106+
public function doFooConstants(int $i): void
107+
{
108+
109+
}
110+
111+
}
112+
113+
class BarConstants
114+
{
115+
116+
const TEST1 = 1;
117+
const TEST2 = 2;
118+
119+
/**
120+
* @param BarConstants::TEST1|BarConstants::TEST2 $i
121+
*/
122+
public function doFoo(int $i): void {
123+
match ($i) {
124+
BarConstants::TEST1 => 'foo',
125+
BarConstants::TEST2 => 'bar',
126+
};
127+
}
128+
129+
/**
130+
* @param BarConstants::TEST* $i
131+
*/
132+
public function doBar(int $i): void {
133+
match ($i) {
134+
BarConstants::TEST1 => 'foo',
135+
BarConstants::TEST2 => 'bar',
136+
};
137+
}
138+
139+
106140
}

0 commit comments

Comments
 (0)