Skip to content

Commit

Permalink
Reflection: support members only on descendants (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal authored Dec 30, 2024
1 parent d3938da commit 3e8c4f1
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 24 deletions.
16 changes: 2 additions & 14 deletions src/Collector/ProvidedUsagesCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Collectors\Collector;
use PHPStan\Reflection\ReflectionProvider;
use ShipMonk\PHPStan\DeadCode\Graph\ClassConstantRef;
use ShipMonk\PHPStan\DeadCode\Graph\ClassMemberUsage;
use ShipMonk\PHPStan\DeadCode\Graph\ClassMethodRef;
use ShipMonk\PHPStan\DeadCode\Provider\MemberUsageProvider;
use function get_class;
use function sprintf;
Expand Down Expand Up @@ -88,18 +86,8 @@ private function validateUsage(
$node->getStartLine(),
);

if ($memberRefClass !== null) {
if (!$this->reflectionProvider->hasClass($memberRefClass)) {
throw new LogicException("Class '$memberRefClass' does not exist. $context");
}

if ($memberRef instanceof ClassMethodRef && !$this->reflectionProvider->getClass($memberRefClass)->hasMethod($memberRef->getMemberName())) {
throw new LogicException("Method '{$memberRef->getMemberName()}' does not exist in class '$memberRefClass'. $context");
}

if ($memberRef instanceof ClassConstantRef && !$this->reflectionProvider->getClass($memberRefClass)->hasConstant($memberRef->getMemberName())) {
throw new LogicException("Constant '{$memberRef->getMemberName()}' does not exist in class '$memberRefClass'. $context");
}
if (($memberRefClass !== null) && !$this->reflectionProvider->hasClass($memberRefClass)) {
throw new LogicException("Class '$memberRefClass' does not exist. $context");
}

if (
Expand Down
12 changes: 2 additions & 10 deletions src/Provider/ReflectionUsageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ private function extractConstantsUsedByReflection(
$firstArg = $args[array_key_first($args)]; // @phpstan-ignore offsetAccess.notFound

foreach ($scope->getType($firstArg->value)->getConstantStrings() as $constantString) {
if (!$genericReflection->hasConstant($constantString->getValue())) {
continue;
}

$usedConstants[] = $this->createConstantUsage($genericReflection->getName(), $constantString->getValue());
}
}
Expand Down Expand Up @@ -140,10 +136,6 @@ private function extractMethodsUsedByReflection(
$firstArg = $args[array_key_first($args)]; // @phpstan-ignore offsetAccess.notFound

foreach ($scope->getType($firstArg->value)->getConstantStrings() as $constantString) {
if (!$genericReflection->hasMethod($constantString->getValue())) {
continue;
}

$usedMethods[] = $this->createMethodUsage($genericReflection->getName(), $constantString->getValue());
}
}
Expand Down Expand Up @@ -189,7 +181,7 @@ private function createConstantUsage(string $className, string $constantName): C
new ClassConstantRef(
$className,
$constantName,
false,
true,
),
);
}
Expand All @@ -201,7 +193,7 @@ private function createMethodUsage(string $className, string $methodName): Class
new ClassMethodRef(
$className,
$methodName,
false,
true,
),
);
}
Expand Down
17 changes: 17 additions & 0 deletions tests/Rule/data/providers/reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ class Holder5
public function __construct() {}
}

abstract class HolderParent {}
class Holder6 extends HolderParent
{
const NOT_IN_PARENT = 1;
}

enum EnumHolder1 {
const CONST1 = 1;
public function used() {}
Expand Down Expand Up @@ -73,3 +79,14 @@ public function used() {}
$enumReflection1 = new \ReflectionClass(EnumHolder1::class);
$enumReflection1->getConstants();
$enumReflection1->getMethod('used');

/**
* @param class-string<HolderParent> $fqn
*/
function testMemberOnlyInDescendant(string $fqn) {
$classReflection = new \ReflectionClass($fqn);

if ($classReflection->hasConstant('NOT_IN_PARENT')) {
echo $classReflection->getConstant('NOT_IN_PARENT');
}
}

0 comments on commit 3e8c4f1

Please sign in to comment.