Skip to content

Commit

Permalink
Refactor pieces looking for dead code for more precise detection of p…
Browse files Browse the repository at this point in the history
…roperties, methods, constants
  • Loading branch information
ondrejmirtes committed Jun 7, 2023
1 parent 564f79f commit d09401d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 48 deletions.
26 changes: 14 additions & 12 deletions src/Node/ClassPropertiesNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@
use PHPStan\Node\Method\MethodCall;
use PHPStan\Node\Property\PropertyRead;
use PHPStan\Node\Property\PropertyWrite;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Rules\Properties\ReadWritePropertiesExtension;
use PHPStan\Rules\Properties\ReadWritePropertiesExtensionProvider;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use function array_key_exists;
use function array_keys;
use function count;
Expand Down Expand Up @@ -133,8 +132,7 @@ public function getUninitializedProperties(
if ($constructors === []) {
return [$properties, [], []];
}
$classType = new ObjectType($scope->getClassReflection()->getName());
$methodsCalledFromConstructor = $this->getMethodsCalledFromConstructor($classType, $this->methodCalls, $constructors);
$methodsCalledFromConstructor = $this->getMethodsCalledFromConstructor($classReflection, $this->methodCalls, $constructors);
$prematureAccess = [];
$additionalAssigns = [];
$originalProperties = $properties;
Expand Down Expand Up @@ -163,10 +161,12 @@ public function getUninitializedProperties(
}
$propertyName = $fetch->name->toString();
$fetchedOnType = $usageScope->getType($fetch->var);
if ($classType->isSuperTypeOf($fetchedOnType)->no()) {

$propertyReflection = $usageScope->getPropertyReflection($fetchedOnType, $propertyName);
if ($propertyReflection === null) {
continue;
}
if ($fetchedOnType instanceof MixedType) {
if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}

Expand Down Expand Up @@ -202,7 +202,7 @@ public function getUninitializedProperties(
* @return string[]
*/
private function getMethodsCalledFromConstructor(
ObjectType $classType,
ClassReflection $classReflection,
array $methodCalls,
array $methods,
): array
Expand All @@ -226,14 +226,16 @@ private function getMethodsCalledFromConstructor(

$calledOnType = $callScope->resolveTypeByName($methodCallNode->class);
}
if ($classType->isSuperTypeOf($calledOnType)->no()) {

$methodName = $methodCallNode->name->toString();
if (in_array($methodName, $methods, true)) {
continue;
}
if ($calledOnType instanceof MixedType) {
$methodReflection = $callScope->getMethodReflection($calledOnType, $methodName);
if ($methodReflection === null) {
continue;
}
$methodName = $methodCallNode->name->toString();
if (in_array($methodName, $methods, true)) {
if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}
$inMethod = $callScope->getFunction();
Expand All @@ -250,7 +252,7 @@ private function getMethodsCalledFromConstructor(
return $methods;
}

return $this->getMethodsCalledFromConstructor($classType, $methodCalls, $methods);
return $this->getMethodsCalledFromConstructor($classReflection, $methodCalls, $methods);
}

}
26 changes: 12 additions & 14 deletions src/Rules/DeadCode/UnusedPrivateConstantRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use function sprintf;

/**
Expand Down Expand Up @@ -64,21 +63,20 @@ public function processNode(Node $node, Scope $scope): array
continue;
}

$fetchScope = $fetch->getScope();
if ($fetchNode->class instanceof Node\Name) {
$fetchScope = $fetch->getScope();
$fetchedOnClass = $fetchScope->resolveName($fetchNode->class);
if ($fetchedOnClass !== $classReflection->getName()) {
continue;
}
$fetchedOnClass = $fetchScope->resolveTypeByName($fetchNode->class);
} else {
$classExprType = $fetch->getScope()->getType($fetchNode->class);
$isDifferentClass = TrinaryLogic::createNo()->lazyOr(
$classExprType->getObjectClassNames(),
static fn (string $objectClassName) => TrinaryLogic::createFromBoolean($objectClassName !== $classReflection->getName()),
);
if ($isDifferentClass->yes()) {
continue;
}
$fetchedOnClass = $fetchScope->getType($fetchNode->class);
}

$constantReflection = $fetchScope->getConstantReflection($fetchedOnClass, $fetchNode->name->toString());
if ($constantReflection === null) {
continue;
}

if ($constantReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}

unset($constants[$fetchNode->name->toString()]);
Expand Down
25 changes: 14 additions & 11 deletions src/Rules/DeadCode/UnusedPrivateMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use function array_map;
use function count;
use function sprintf;
Expand Down Expand Up @@ -42,7 +40,6 @@ public function processNode(Node $node, Scope $scope): array
if ($classReflection->hasConstructor()) {
$constructor = $classReflection->getConstructor();
}
$classType = new ObjectType($classReflection->getName());

$methods = [];
foreach ($node->getMethods() as $method) {
Expand Down Expand Up @@ -90,18 +87,20 @@ public function processNode(Node $node, Scope $scope): array
}
$calledOnType = $scope->resolveTypeByName($methodCallNode->class);
}
if ($classType->isSuperTypeOf($calledOnType)->no()) {
continue;
}
if ($calledOnType instanceof MixedType) {
continue;
}

$inMethod = $callScope->getFunction();
if (!$inMethod instanceof MethodReflection) {
continue;
}

foreach ($methodNames as $methodName) {
$methodReflection = $callScope->getMethodReflection($calledOnType, $methodName);
if ($methodReflection === null) {
continue;
}
if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}
if ($inMethod->getName() === $methodName) {
continue;
}
Expand All @@ -126,13 +125,17 @@ public function processNode(Node $node, Scope $scope): array
if (!$typeAndMethod->getCertainty()->yes()) {
return [];
}

$calledOnType = $typeAndMethod->getType();
if ($classType->isSuperTypeOf($calledOnType)->no()) {
$methodReflection = $arrayScope->getMethodReflection($calledOnType, $typeAndMethod->getMethod());
if ($methodReflection === null) {
continue;
}
if ($calledOnType instanceof MixedType) {

if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}

$inMethod = $arrayScope->getFunction();
if (!$inMethod instanceof MethodReflection) {
continue;
Expand Down
19 changes: 8 additions & 11 deletions src/Rules/DeadCode/UnusedPrivatePropertyRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use function array_key_exists;
use function array_map;
use function count;
Expand Down Expand Up @@ -52,8 +50,6 @@ public function processNode(Node $node, Scope $scope): array
throw new ShouldNotHappenException();
}
$classReflection = $scope->getClassReflection();
$classType = new ObjectType($classReflection->getName());

$properties = [];
foreach ($node->getProperties() as $property) {
if (!$property->isPrivate()) {
Expand Down Expand Up @@ -141,17 +137,18 @@ public function processNode(Node $node, Scope $scope): array
$fetchedOnType = $usage->getScope()->resolveTypeByName($fetch->class);
}

if ($classType->isSuperTypeOf($fetchedOnType)->no()) {
continue;
}
if ($fetchedOnType instanceof MixedType) {
continue;
}

foreach ($propertyNames as $propertyName) {
if (!array_key_exists($propertyName, $properties)) {
continue;
}
$propertyReflection = $usage->getScope()->getPropertyReflection($fetchedOnType, $propertyName);
if ($propertyReflection === null) {
continue;
}
if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) {
continue;
}

if ($usage instanceof PropertyRead) {
$properties[$propertyName]['read'] = true;
} else {
Expand Down

0 comments on commit d09401d

Please sign in to comment.