Skip to content

Commit

Permalink
Property hook can be final
Browse files Browse the repository at this point in the history
  • Loading branch information
kukulich committed Dec 30, 2024
1 parent 9e682f8 commit 166e4ca
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
1 change: 1 addition & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
<code><![CDATA[classExists]]></code>
<code><![CDATA[isAbstract]]></code>
<code><![CDATA[isFinal]]></code>
<code><![CDATA[isFinal]]></code>
<code><![CDATA[isPrivate]]></code>
<code><![CDATA[isProtected]]></code>
<code><![CDATA[isPublic]]></code>
Expand Down
19 changes: 12 additions & 7 deletions src/Reflection/ReflectionMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private function __construct(
assert($node instanceof MethodNode || $node instanceof Node\PropertyHook);

$this->name = $name;
$this->modifiers = $node instanceof MethodNode ? $this->computeModifiers($node) : 0;
$this->modifiers = $this->computeModifiers($node);

$this->fillFromNode($node);
}
Expand Down Expand Up @@ -305,13 +305,18 @@ public function getModifiers(): int
}

/** @return int-mask-of<ReflectionMethodAdapter::IS_*> */
private function computeModifiers(MethodNode $node): int
private function computeModifiers(MethodNode|Node\PropertyHook $node): int
{
$modifiers = $node->isStatic() ? CoreReflectionMethod::IS_STATIC : 0;
$modifiers += $node->isPublic() ? CoreReflectionMethod::IS_PUBLIC : 0;
$modifiers += $node->isProtected() ? CoreReflectionMethod::IS_PROTECTED : 0;
$modifiers += $node->isPrivate() ? CoreReflectionMethod::IS_PRIVATE : 0;
$modifiers += $node->isAbstract() ? CoreReflectionMethod::IS_ABSTRACT : 0;
$modifiers = 0;

if ($node instanceof MethodNode) {
$modifiers += $node->isStatic() ? CoreReflectionMethod::IS_STATIC : 0;
$modifiers += $node->isPublic() ? CoreReflectionMethod::IS_PUBLIC : 0;
$modifiers += $node->isProtected() ? CoreReflectionMethod::IS_PROTECTED : 0;
$modifiers += $node->isPrivate() ? CoreReflectionMethod::IS_PRIVATE : 0;
$modifiers += $node->isAbstract() ? CoreReflectionMethod::IS_ABSTRACT : 0;
}

$modifiers += $node->isFinal() ? CoreReflectionMethod::IS_FINAL : 0;

return $modifiers;
Expand Down
11 changes: 11 additions & 0 deletions test/unit/Fixture/PropertyHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,14 @@ class GetPropertyHooksReturnTypes
public $hookWithoutType { get => 'string'; }

}

class FinalPropertyHooks
{
public string $notFinalHook {
set => strtolower($value);
}

public string $finalHook {
final set => strtolower($value);
}
}
21 changes: 21 additions & 0 deletions test/unit/Reflection/ReflectionMethodTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -882,4 +882,25 @@ public function testGetPropertyHookReturnType(string $propertyName, string|null
self::assertNotNull($getHookReflection);
self::assertSame($returnType, $getHookReflection->getReturnType()?->__toString());
}

/** @return list<array{0: non-empty-string, 1: bool}> */
public static function finalPropertyHookProvider(): array
{
return [
['notFinalHook', false],
['finalHook', true],
];
}

#[DataProvider('finalPropertyHookProvider')]
public function testFinalPropertyHook(string $propertyName, bool $isFinal): void
{
$reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/PropertyHooks.php', $this->astLocator));
$classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\FinalPropertyHooks');

$hookProperty = $classInfo->getProperty($propertyName);
$hookReflection = $hookProperty->getHook(ReflectionPropertyHookType::Set);
self::assertNotNull($hookReflection);
self::assertSame($isFinal, $hookReflection->isFinal());
}
}

0 comments on commit 166e4ca

Please sign in to comment.