Created
May 18, 2023 15:21
-
-
Save thekid/d83bac22f30e3d3e41425bb703ab1d0b to your computer and use it in GitHub Desktop.
Alternative to parent::$x::get()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/main/php/lang/ast/emit/PHP.class.php b/src/main/php/lang/ast/emit/PHP.class.php | |
index b15f8bb..e85c8ba 100755 | |
--- a/src/main/php/lang/ast/emit/PHP.class.php | |
+++ b/src/main/php/lang/ast/emit/PHP.class.php | |
@@ -436,7 +436,7 @@ abstract class PHP extends Emitter { | |
// Virtual properties support: __virtual member + __get() and __set() | |
if ($context->virtual) { | |
- $result->out->write('private $__virtual= ['); | |
+ $result->out->write('protected $__virtual= ['); | |
foreach ($context->virtual as $name => $access) { | |
$name && $result->out->write("'{$name}' => null,"); | |
} | |
diff --git a/src/main/php/lang/ast/emit/PropertyHooks.class.php b/src/main/php/lang/ast/emit/PropertyHooks.class.php | |
index 391ba59..bc9fc51 100755 | |
--- a/src/main/php/lang/ast/emit/PropertyHooks.class.php | |
+++ b/src/main/php/lang/ast/emit/PropertyHooks.class.php | |
@@ -29,28 +29,29 @@ trait PropertyHooks { | |
// Magic constant referencing property name | |
if ($node instanceof Literal && '__PROPERTY__' === $node->expression) return $literal; | |
- // Special variable $field, $this->propertyName syntax | |
- if ($node instanceof Variable && 'field' === $node->pointer || ( | |
+ // Special variable $field syntax | |
+ if ($node instanceof Variable && 'field' === $node->pointer) return $virtual; | |
+ | |
+ // $this->propertyName for accessing parent's getter | |
+ if ( | |
$node instanceof InstanceExpression && | |
$node->expression instanceof Variable && 'this' === $node->expression->pointer && | |
$node->member instanceof Literal && $name === $node->member->expression | |
- )) return $virtual; | |
+ ) return new ScopeExpression('parent', new InvokeExpression( | |
+ new Literal('__get_'.$name), | |
+ [] | |
+ )); | |
- // <T>::$field::hook() => <T>::__<hook>_<field>() | |
+ // $this->propertyName= ... for accessing parent's setter | |
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 | |
- )); | |
- } | |
+ $node instanceof Assignment && | |
+ $node->variable instanceof InstanceExpression && | |
+ $node->variable->expression instanceof Variable && 'this' === $node->variable->expression->pointer && | |
+ $node->variable->member instanceof Literal && $name === $node->variable->member->expression | |
+ ) return new ScopeExpression('parent', new InvokeExpression( | |
+ new Literal('__set_'.$name), | |
+ [$node->expression] | |
+ )); | |
foreach ($node->children() as &$child) { | |
$child= $this->rewriteHook($child, $name, $virtual, $literal); | |
diff --git a/src/test/php/lang/ast/unittest/emit/PropertyHooksTest.class.php b/src/test/php/lang/ast/unittest/emit/PropertyHooksTest.class.php | |
index a4dcaf7..3e146e9 100755 | |
--- a/src/test/php/lang/ast/unittest/emit/PropertyHooksTest.class.php | |
+++ b/src/test/php/lang/ast/unittest/emit/PropertyHooksTest.class.php | |
@@ -108,23 +108,6 @@ class PropertyHooksTest extends EmittingTest { | |
Assert::equals('Test', $r); | |
} | |
- #[Test] | |
- public function get_and_set_using_property() { | |
- $r= $this->run('class <T> { | |
- public $test { | |
- get => $this->test; | |
- set => $this->test= ucfirst($value); | |
- } | |
- | |
- public function run() { | |
- $this->test= "test"; | |
- return $this->test; | |
- } | |
- }'); | |
- | |
- Assert::equals('Test', $r); | |
- } | |
- | |
#[Test] | |
public function implicit_set() { | |
$r= $this->run('class <T> { | |
@@ -336,9 +319,26 @@ class PropertyHooksTest extends EmittingTest { | |
public string $test { get => "Test"; } | |
}'); | |
$r= $this->run('class <T> extends '.$base->literal().' { | |
- public string $test { get => parent::$test::get()."!"; } | |
+ public string $test { get => $this->test."!"; } | |
+ | |
+ public function run() { | |
+ return $this->test; | |
+ } | |
+ }'); | |
+ | |
+ Assert::equals('Test!', $r); | |
+ } | |
+ | |
+ #[Test] | |
+ public function set_parent_hook() { | |
+ $base= $this->type('class <T> { | |
+ public string $test { set => $field= $value; } | |
+ }'); | |
+ $r= $this->run('class <T> extends '.$base->literal().' { | |
+ public string $test { set => $this->test= $value."!"; } | |
public function run() { | |
+ $this->test= "Test"; | |
return $this->test; | |
} | |
}'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment