Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c2f10c6

Browse files
committed
Fix FirstTypeSpecifyingExtension
1 parent d3fe64f commit c2f10c6

File tree

4 files changed

+118
-15
lines changed

4 files changed

+118
-15
lines changed

‎src/Type/Doctrine/Collection/FirstTypeSpecifyingExtension.php‎

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\Reflection\MethodReflection;
12-
use PHPStan\Reflection\ParametersAcceptorSelector;
1312
use PHPStan\Type\Constant\ConstantBooleanType;
1413
use PHPStan\Type\MethodTypeSpecifyingExtension;
15-
use PHPStan\Type\TypeCombinator;
1614

1715
final class FirstTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
1816
{
@@ -49,21 +47,11 @@ public function specifyTypes(
4947
TypeSpecifierContext $context
5048
): SpecifiedTypes
5149
{
52-
$classReflection = $methodReflection->getDeclaringClass();
53-
$methodVariants = $classReflection->getNativeMethod(self::FIRST_METHOD_NAME)->getVariants();
54-
55-
if ($context->truthy()) {
56-
return $this->typeSpecifier->create(
57-
new MethodCall($node->var, self::FIRST_METHOD_NAME),
58-
new ConstantBooleanType(false),
59-
$context
60-
);
61-
}
62-
6350
return $this->typeSpecifier->create(
6451
new MethodCall($node->var, self::FIRST_METHOD_NAME),
65-
TypeCombinator::remove(ParametersAcceptorSelector::selectSingle($methodVariants)->getReturnType(), new ConstantBooleanType(false)),
66-
$context
52+
new ConstantBooleanType(false),
53+
$context,
54+
true
6755
);
6856
}
6957

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Doctrine\Collection;
4+
5+
use PHPStan\Rules\Rule;
6+
7+
/**
8+
* @extends \PHPStan\Testing\RuleTestCase<VariableTypeReportingRule>
9+
*/
10+
class FirstTypeSpecifyingExtensionTest extends \PHPStan\Testing\RuleTestCase
11+
{
12+
13+
protected function getRule(): Rule
14+
{
15+
return new VariableTypeReportingRule();
16+
}
17+
18+
/**
19+
* @return \PHPStan\Type\MethodTypeSpecifyingExtension[]
20+
*/
21+
protected function getMethodTypeSpecifyingExtensions(): array
22+
{
23+
return [
24+
new FirstTypeSpecifyingExtension(),
25+
];
26+
}
27+
28+
public function testExtension(): void
29+
{
30+
$this->analyse([__DIR__ . '/data/collection.php'], [
31+
[
32+
'Variable $entityOrFalse is: MyEntity|false',
33+
18,
34+
],
35+
[
36+
'Variable $false is: false',
37+
22,
38+
],
39+
[
40+
'Variable $entity is: MyEntity',
41+
27,
42+
],
43+
]);
44+
}
45+
46+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Doctrine\Collection;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
8+
/**
9+
* @implements \PHPStan\Rules\Rule<Node\Expr\Variable>
10+
*/
11+
class VariableTypeReportingRule implements \PHPStan\Rules\Rule
12+
{
13+
14+
public function getNodeType(): string
15+
{
16+
return Node\Expr\Variable::class;
17+
}
18+
19+
public function processNode(Node $node, Scope $scope): array
20+
{
21+
if (!is_string($node->name)) {
22+
return [];
23+
}
24+
if (!$scope->isInFirstLevelStatement()) {
25+
return [];
26+
};
27+
28+
if ($scope->isInExpressionAssign($node)) {
29+
return [];
30+
}
31+
32+
return [
33+
sprintf(
34+
'Variable $%s is: %s',
35+
$node->name,
36+
$scope->getType($node)->describe(\PHPStan\Type\VerbosityLevel::value())
37+
),
38+
];
39+
}
40+
41+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types = 1);
2+
3+
use Doctrine\Common\Collections\ArrayCollection;
4+
5+
class MyEntity
6+
{
7+
8+
}
9+
10+
$new = new MyEntity();
11+
12+
/**
13+
* @var ArrayCollection<int, MyEntity> $collection
14+
*/
15+
$collection = new ArrayCollection();
16+
17+
$entityOrFalse = $collection->first();
18+
$entityOrFalse;
19+
20+
if ($collection->isEmpty()) {
21+
$false = $collection->first();
22+
$false;
23+
}
24+
25+
if (!$collection->isEmpty()) {
26+
$entity = $collection->first();
27+
$entity;
28+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /