Skip to content

Commit

Permalink
Add reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Aug 25, 2024
1 parent f553374 commit 7fba427
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"keywords": ["module", "xp"],
"require" : {
"xp-framework/core": "^12.0 | ^11.6 | ^10.16",
"xp-framework/reflection": "^3.0 | ^2.13",
"xp-framework/reflection": "dev-feature/asymmetric-visibility as 3.2.0",
"xp-framework/ast": "dev-feature/asymmetric-visibility as 11.3.0",
"php" : ">=7.4.0"
},
Expand Down
33 changes: 29 additions & 4 deletions src/main/php/lang/ast/emit/AsymmetricVisibility.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,37 @@ trait AsymmetricVisibility {
use VisibilityChecks;

protected function emitProperty($result, $property) {
static $lookup= [
'public' => MODIFIER_PUBLIC,
'protected' => MODIFIER_PROTECTED,
'private' => MODIFIER_PRIVATE,
'static' => MODIFIER_STATIC,
'final' => MODIFIER_FINAL,
'abstract' => MODIFIER_ABSTRACT,
'readonly' => MODIFIER_READONLY,
'private(set)' => 0x0400,
'protected(set)' => 0x0800,
'public(set)' => 0x1000,
];

// Emit XP meta information for the reflection API
$scope= $result->codegen->scope[0];
$modifiers= 0;
foreach ($property->modifiers as $name) {
$modifiers|= $lookup[$name];
}
$scope->meta[self::PROPERTY][$property->name]= [
DETAIL_RETURNS => $property->type ? $property->type->name() : 'var',
DETAIL_ANNOTATIONS => $property->annotations,
DETAIL_COMMENT => $property->comment,
DETAIL_TARGET_ANNO => [],
DETAIL_ARGUMENTS => [$modifiers]
];

$checks= [];
if (in_array('private(set)', $property->modifiers)) {
if ($modifiers & 0x0400) {
$checks[]= $this->private($property->name, 'modify private(set)');
} else if (in_array('protected(set)', $property->modifiers)) {
} else if ($modifiers & 0x0800) {
$checks[]= $this->protected($property->name, 'modify protected(set)');
}

Expand All @@ -36,8 +63,6 @@ protected function emitProperty($result, $property) {
new Literal('__virtual'),
new Literal("'{$property->name}'"))
);

$scope= $result->codegen->scope[0];
$scope->virtual[$property->name]= [
new ReturnStatement($virtual),
new Block([...$checks, new Assignment($virtual, '=', new Variable('value'))]),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php namespace lang\ast\unittest\emit;

use lang\Error;
use test\{Assert, Expect, Test};
use test\{Assert, Expect, Test, Values};

/**
* Asymmetric visibility tests
Expand Down Expand Up @@ -95,4 +95,16 @@ public function rename() {
}');
$t->newInstance()->rename();
}

#[Test, Values(['private', 'protected', 'public'])]
public function reflection($modifier) {
$t= $this->declare('class %T {
public '.$modifier.'(set) string $fixture= "Test";
}');

Assert::equals(
'public '.$modifier.'(set) string $fixture',
$t->property('fixture')->toString()
);
}
}

0 comments on commit 7fba427

Please sign in to comment.