Skip to content

Commit 8dbdd04

Browse files
committed
Extract modifier mapping to utility class
See #184 (review)
1 parent 2466c6e commit 8dbdd04

File tree

5 files changed

+41
-65
lines changed

5 files changed

+41
-65
lines changed

src/main/php/lang/ast/emit/AsymmetricVisibility.class.php

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,8 @@ trait AsymmetricVisibility {
2020
use VisibilityChecks;
2121

2222
protected function emitProperty($result, $property) {
23-
static $lookup= [
24-
'public' => MODIFIER_PUBLIC,
25-
'protected' => MODIFIER_PROTECTED,
26-
'private' => MODIFIER_PRIVATE,
27-
'static' => MODIFIER_STATIC,
28-
'final' => MODIFIER_FINAL,
29-
'abstract' => MODIFIER_ABSTRACT,
30-
'readonly' => MODIFIER_READONLY,
31-
'public(set)' => 0x1000000,
32-
'protected(set)' => 0x0000800,
33-
'private(set)' => 0x0001000,
34-
];
35-
3623
$scope= $result->codegen->scope[0];
37-
$modifiers= 0;
38-
foreach ($property->modifiers as $name) {
39-
$modifiers|= $lookup[$name];
40-
}
24+
$modifiers= Modifiers::bits($property->modifiers);
4125

4226
// Declare checks for private(set) and protected(set), folding declarations
4327
// like `[visibility] [visibility](set)` to just the visibility itself.

src/main/php/lang/ast/emit/FinalProperties.class.php

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
<?php namespace lang\ast\emit;
22

3+
/**
4+
* When property hooks were introduced into PHP 8.4, it also added a mechanism
5+
* for properties to be declared as final. For other PHP versions, emit without
6+
* final modifier, store `final` in xp::$meta
7+
*
8+
* @see https://wiki.php.net/rfc/property-hooks
9+
* @test lang.ast.unittest.emit.MembersTest
10+
*/
311
trait FinalProperties {
412

513
protected function emitProperty($result, $property) {
6-
static $lookup= [
7-
'public' => MODIFIER_PUBLIC,
8-
'protected' => MODIFIER_PROTECTED,
9-
'private' => MODIFIER_PRIVATE,
10-
'static' => MODIFIER_STATIC,
11-
'final' => MODIFIER_FINAL,
12-
'abstract' => MODIFIER_ABSTRACT,
13-
'readonly' => 0x0080, // XP 10.13: MODIFIER_READONLY
14-
];
15-
16-
$modifiers= 0;
17-
foreach ($property->modifiers as $name) {
18-
$modifiers|= $lookup[$name];
19-
}
20-
21-
// Emit without final modifier, store `final` in xp::$meta
2214
$property->modifiers= array_diff($property->modifiers, ['final']);
2315
parent::emitProperty($result, $property);
2416
$result->codegen->scope[0]->meta[self::PROPERTY][$property->name][DETAIL_ARGUMENTS]= [MODIFIER_FINAL];
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php namespace lang\ast\emit;
2+
3+
class Modifiers {
4+
const LOOKUP= [
5+
'public' => MODIFIER_PUBLIC,
6+
'protected' => MODIFIER_PROTECTED,
7+
'private' => MODIFIER_PRIVATE,
8+
'static' => MODIFIER_STATIC,
9+
'final' => MODIFIER_FINAL,
10+
'abstract' => MODIFIER_ABSTRACT,
11+
'readonly' => 0x0080, // XP 10.13: MODIFIER_READONLY
12+
'public(set)' => 0x1000000,
13+
'protected(set)' => 0x0000800,
14+
'private(set)' => 0x0001000,
15+
];
16+
17+
/**
18+
* Converts modifiers to a bit set
19+
*
20+
* @param string[] $modifiers
21+
* @return int
22+
*/
23+
public static function bits($modifiers) {
24+
$bits= 0;
25+
foreach ($modifiers as $name) {
26+
$bits|= self::LOOKUP[$name];
27+
}
28+
return $bits;
29+
}
30+
}

src/main/php/lang/ast/emit/PropertyHooks.class.php

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,8 @@ protected function withScopeCheck($modifiers, $nodes) {
7171
}
7272

7373
protected function emitProperty($result, $property) {
74-
static $lookup= [
75-
'public' => MODIFIER_PUBLIC,
76-
'protected' => MODIFIER_PROTECTED,
77-
'private' => MODIFIER_PRIVATE,
78-
'static' => MODIFIER_STATIC,
79-
'final' => MODIFIER_FINAL,
80-
'abstract' => MODIFIER_ABSTRACT,
81-
'readonly' => MODIFIER_READONLY,
82-
'public(set)' => 0x1000000,
83-
'protected(set)' => 0x0000800,
84-
'private(set)' => 0x0001000,
85-
];
86-
87-
// Emit XP meta information for the reflection API
8874
$scope= $result->codegen->scope[0];
89-
$modifiers= 0;
90-
foreach ($property->modifiers as $name) {
91-
$modifiers|= $lookup[$name];
92-
}
75+
$modifiers= Modifiers::bits($property->modifiers);
9376

9477
// Derive modifiers for private(set) and protected(set), folding declarations
9578
// like `[visibility] [visibility](set)` to just the visibility itself.

src/main/php/lang/ast/emit/ReadonlyProperties.class.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,10 @@ trait ReadonlyProperties {
2222
use VisibilityChecks;
2323

2424
protected function emitProperty($result, $property) {
25-
static $lookup= [
26-
'public' => MODIFIER_PUBLIC,
27-
'protected' => MODIFIER_PROTECTED,
28-
'private' => MODIFIER_PRIVATE,
29-
'static' => MODIFIER_STATIC,
30-
'final' => MODIFIER_FINAL,
31-
'abstract' => MODIFIER_ABSTRACT,
32-
'readonly' => 0x0080, // XP 10.13: MODIFIER_READONLY
33-
];
34-
3525
if (!in_array('readonly', $property->modifiers)) return parent::emitProperty($result, $property);
3626

3727
$scope= $result->codegen->scope[0];
38-
$modifiers= 0;
39-
foreach ($property->modifiers as $name) {
40-
$modifiers|= $lookup[$name];
41-
}
28+
$modifiers= Modifiers::bits($property->modifiers);
4229
$scope->meta[self::PROPERTY][$property->name]= [
4330
DETAIL_RETURNS => $property->type ? $property->type->name() : 'var',
4431
DETAIL_ANNOTATIONS => $property->annotations,

0 commit comments

Comments
 (0)