Skip to content

Commit d09401d

Browse files
committed
Refactor pieces looking for dead code for more precise detection of properties, methods, constants
1 parent 564f79f commit d09401d

File tree

4 files changed

+48
-48
lines changed

4 files changed

+48
-48
lines changed

src/Node/ClassPropertiesNode.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
use PHPStan\Node\Method\MethodCall;
1515
use PHPStan\Node\Property\PropertyRead;
1616
use PHPStan\Node\Property\PropertyWrite;
17+
use PHPStan\Reflection\ClassReflection;
1718
use PHPStan\Reflection\MethodReflection;
1819
use PHPStan\Rules\Properties\ReadWritePropertiesExtension;
1920
use PHPStan\Rules\Properties\ReadWritePropertiesExtensionProvider;
2021
use PHPStan\ShouldNotHappenException;
21-
use PHPStan\Type\MixedType;
22-
use PHPStan\Type\ObjectType;
2322
use function array_key_exists;
2423
use function array_keys;
2524
use function count;
@@ -133,8 +132,7 @@ public function getUninitializedProperties(
133132
if ($constructors === []) {
134133
return [$properties, [], []];
135134
}
136-
$classType = new ObjectType($scope->getClassReflection()->getName());
137-
$methodsCalledFromConstructor = $this->getMethodsCalledFromConstructor($classType, $this->methodCalls, $constructors);
135+
$methodsCalledFromConstructor = $this->getMethodsCalledFromConstructor($classReflection, $this->methodCalls, $constructors);
138136
$prematureAccess = [];
139137
$additionalAssigns = [];
140138
$originalProperties = $properties;
@@ -163,10 +161,12 @@ public function getUninitializedProperties(
163161
}
164162
$propertyName = $fetch->name->toString();
165163
$fetchedOnType = $usageScope->getType($fetch->var);
166-
if ($classType->isSuperTypeOf($fetchedOnType)->no()) {
164+
165+
$propertyReflection = $usageScope->getPropertyReflection($fetchedOnType, $propertyName);
166+
if ($propertyReflection === null) {
167167
continue;
168168
}
169-
if ($fetchedOnType instanceof MixedType) {
169+
if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
170170
continue;
171171
}
172172

@@ -202,7 +202,7 @@ public function getUninitializedProperties(
202202
* @return string[]
203203
*/
204204
private function getMethodsCalledFromConstructor(
205-
ObjectType $classType,
205+
ClassReflection $classReflection,
206206
array $methodCalls,
207207
array $methods,
208208
): array
@@ -226,14 +226,16 @@ private function getMethodsCalledFromConstructor(
226226

227227
$calledOnType = $callScope->resolveTypeByName($methodCallNode->class);
228228
}
229-
if ($classType->isSuperTypeOf($calledOnType)->no()) {
229+
230+
$methodName = $methodCallNode->name->toString();
231+
if (in_array($methodName, $methods, true)) {
230232
continue;
231233
}
232-
if ($calledOnType instanceof MixedType) {
234+
$methodReflection = $callScope->getMethodReflection($calledOnType, $methodName);
235+
if ($methodReflection === null) {
233236
continue;
234237
}
235-
$methodName = $methodCallNode->name->toString();
236-
if (in_array($methodName, $methods, true)) {
238+
if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
237239
continue;
238240
}
239241
$inMethod = $callScope->getFunction();
@@ -250,7 +252,7 @@ private function getMethodsCalledFromConstructor(
250252
return $methods;
251253
}
252254

253-
return $this->getMethodsCalledFromConstructor($classType, $methodCalls, $methods);
255+
return $this->getMethodsCalledFromConstructor($classReflection, $methodCalls, $methods);
254256
}
255257

256258
}

src/Rules/DeadCode/UnusedPrivateConstantRule.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
1111
use PHPStan\ShouldNotHappenException;
12-
use PHPStan\TrinaryLogic;
1312
use function sprintf;
1413

1514
/**
@@ -64,21 +63,20 @@ public function processNode(Node $node, Scope $scope): array
6463
continue;
6564
}
6665

66+
$fetchScope = $fetch->getScope();
6767
if ($fetchNode->class instanceof Node\Name) {
68-
$fetchScope = $fetch->getScope();
69-
$fetchedOnClass = $fetchScope->resolveName($fetchNode->class);
70-
if ($fetchedOnClass !== $classReflection->getName()) {
71-
continue;
72-
}
68+
$fetchedOnClass = $fetchScope->resolveTypeByName($fetchNode->class);
7369
} else {
74-
$classExprType = $fetch->getScope()->getType($fetchNode->class);
75-
$isDifferentClass = TrinaryLogic::createNo()->lazyOr(
76-
$classExprType->getObjectClassNames(),
77-
static fn (string $objectClassName) => TrinaryLogic::createFromBoolean($objectClassName !== $classReflection->getName()),
78-
);
79-
if ($isDifferentClass->yes()) {
80-
continue;
81-
}
70+
$fetchedOnClass = $fetchScope->getType($fetchNode->class);
71+
}
72+
73+
$constantReflection = $fetchScope->getConstantReflection($fetchedOnClass, $fetchNode->name->toString());
74+
if ($constantReflection === null) {
75+
continue;
76+
}
77+
78+
if ($constantReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
79+
continue;
8280
}
8381

8482
unset($constants[$fetchNode->name->toString()]);

src/Rules/DeadCode/UnusedPrivateMethodRule.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
use PHPStan\Rules\RuleErrorBuilder;
1212
use PHPStan\ShouldNotHappenException;
1313
use PHPStan\Type\Constant\ConstantStringType;
14-
use PHPStan\Type\MixedType;
15-
use PHPStan\Type\ObjectType;
1614
use function array_map;
1715
use function count;
1816
use function sprintf;
@@ -42,7 +40,6 @@ public function processNode(Node $node, Scope $scope): array
4240
if ($classReflection->hasConstructor()) {
4341
$constructor = $classReflection->getConstructor();
4442
}
45-
$classType = new ObjectType($classReflection->getName());
4643

4744
$methods = [];
4845
foreach ($node->getMethods() as $method) {
@@ -90,18 +87,20 @@ public function processNode(Node $node, Scope $scope): array
9087
}
9188
$calledOnType = $scope->resolveTypeByName($methodCallNode->class);
9289
}
93-
if ($classType->isSuperTypeOf($calledOnType)->no()) {
94-
continue;
95-
}
96-
if ($calledOnType instanceof MixedType) {
97-
continue;
98-
}
90+
9991
$inMethod = $callScope->getFunction();
10092
if (!$inMethod instanceof MethodReflection) {
10193
continue;
10294
}
10395

10496
foreach ($methodNames as $methodName) {
97+
$methodReflection = $callScope->getMethodReflection($calledOnType, $methodName);
98+
if ($methodReflection === null) {
99+
continue;
100+
}
101+
if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
102+
continue;
103+
}
105104
if ($inMethod->getName() === $methodName) {
106105
continue;
107106
}
@@ -126,13 +125,17 @@ public function processNode(Node $node, Scope $scope): array
126125
if (!$typeAndMethod->getCertainty()->yes()) {
127126
return [];
128127
}
128+
129129
$calledOnType = $typeAndMethod->getType();
130-
if ($classType->isSuperTypeOf($calledOnType)->no()) {
130+
$methodReflection = $arrayScope->getMethodReflection($calledOnType, $typeAndMethod->getMethod());
131+
if ($methodReflection === null) {
131132
continue;
132133
}
133-
if ($calledOnType instanceof MixedType) {
134+
135+
if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
134136
continue;
135137
}
138+
136139
$inMethod = $arrayScope->getFunction();
137140
if (!$inMethod instanceof MethodReflection) {
138141
continue;

src/Rules/DeadCode/UnusedPrivatePropertyRule.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
use PHPStan\Rules\RuleErrorBuilder;
1212
use PHPStan\ShouldNotHappenException;
1313
use PHPStan\Type\Constant\ConstantStringType;
14-
use PHPStan\Type\MixedType;
15-
use PHPStan\Type\ObjectType;
1614
use function array_key_exists;
1715
use function array_map;
1816
use function count;
@@ -52,8 +50,6 @@ public function processNode(Node $node, Scope $scope): array
5250
throw new ShouldNotHappenException();
5351
}
5452
$classReflection = $scope->getClassReflection();
55-
$classType = new ObjectType($classReflection->getName());
56-
5753
$properties = [];
5854
foreach ($node->getProperties() as $property) {
5955
if (!$property->isPrivate()) {
@@ -141,17 +137,18 @@ public function processNode(Node $node, Scope $scope): array
141137
$fetchedOnType = $usage->getScope()->resolveTypeByName($fetch->class);
142138
}
143139

144-
if ($classType->isSuperTypeOf($fetchedOnType)->no()) {
145-
continue;
146-
}
147-
if ($fetchedOnType instanceof MixedType) {
148-
continue;
149-
}
150-
151140
foreach ($propertyNames as $propertyName) {
152141
if (!array_key_exists($propertyName, $properties)) {
153142
continue;
154143
}
144+
$propertyReflection = $usage->getScope()->getPropertyReflection($fetchedOnType, $propertyName);
145+
if ($propertyReflection === null) {
146+
continue;
147+
}
148+
if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
149+
continue;
150+
}
151+
155152
if ($usage instanceof PropertyRead) {
156153
$properties[$propertyName]['read'] = true;
157154
} else {

0 commit comments

Comments
 (0)