Skip to content

Commit

Permalink
Add support for for <T>::$field::hook()
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed May 18, 2023
1 parent 6031c35 commit f21a615
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/main/php/lang/ast/emit/PropertyHooks.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
OffsetExpression,
Parameter,
ReturnStatement,
ScopeExpression,
Signature,
Variable
};
Expand All @@ -25,7 +26,7 @@ trait PropertyHooks {

protected function rewriteHook($node, $name, $virtual, $literal) {

// Magic constant referencing property nae
// Magic constant referencing property name
if ($node instanceof Literal && '__PROPERTY__' === $node->expression) return $literal;

// Special variable $field, $this->propertyName syntax
Expand All @@ -35,6 +36,22 @@ protected function rewriteHook($node, $name, $virtual, $literal) {
$node->member instanceof Literal && $name === $node->member->expression
)) return $virtual;

// <T>::$field::hook() => <T>::__<hook>_<field>()
if (
$node instanceof ScopeExpression &&
$node->member instanceof InvokeExpression &&
$node->member->expression instanceof Literal &&
$node->type instanceof ScopeExpression &&
$node->type->member instanceof Variable &&
is_string($node->type->type) &&
is_string($node->type->member->pointer)
) {
return new ScopeExpression($node->type->type, new InvokeExpression(
new Literal('__'.$node->member->expression->expression.'_'.$node->type->member->pointer),
$node->member->arguments
));
}

foreach ($node->children() as &$child) {
$child= $this->rewriteHook($child, $name, $virtual, $literal);
}
Expand Down
16 changes: 16 additions & 0 deletions src/test/php/lang/ast/unittest/emit/PropertyHooksTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,20 @@ public function accessing_protected_property_reflectively() {

Assert::equals('Test', $t->getField('test')->setAccessible(true)->get($t->newInstance()));
}

#[Test]
public function get_parent_hook() {
$base= $this->type('class <T> {
public string $test { get => "Test"; }
}');
$r= $this->run('class <T> extends '.$base->literal().' {
public string $test { get => parent::$test::get()."!"; }
public function run() {
return $this->test;
}
}');

Assert::equals('Test!', $r);
}
}

0 comments on commit f21a615

Please sign in to comment.