Skip to content

Commit 5b5e895

Browse files
committed
Adopt dstogov Attributes PR php#1878 to php8 without Ast Nodes but no values yet.
1 parent f031735 commit 5b5e895

21 files changed

+751
-60
lines changed

Zend/tests/attributes_001.phpt

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
--TEST--
2+
Basic attributes usage
3+
--FILE--
4+
<?php
5+
// No attributes
6+
function f0() {
7+
}
8+
$r = new ReflectionFunction("f0");
9+
var_dump($r->getAttributes());
10+
11+
// Function attributes
12+
<<TestFunction>>
13+
function foo() {
14+
}
15+
$r = new ReflectionFunction("foo");
16+
var_dump($r->getAttributes());
17+
18+
// Class attributes
19+
<<TestClass>>
20+
class Bar {
21+
<<TestConst>>
22+
const C = 2;
23+
<<TestProp>>
24+
public $x = 3;
25+
26+
}
27+
$r = new ReflectionClass("Bar");
28+
var_dump($r->getAttributes());
29+
$r1 = $r->getReflectionConstant("C");
30+
var_dump($r1->getAttributes());
31+
$r2 = $r->getProperty("x");
32+
var_dump($r2->getAttributes());
33+
34+
// Multiple attributes with multiple values
35+
<<a1,a2(1),a3(1,2)>>
36+
function f1() {}
37+
$r = new ReflectionFunction("f1");
38+
var_dump($r->getAttributes());
39+
40+
// Attributes with AST
41+
<<a1,a2(1+"a"),a3(1+"b",2+"c"),a4(["a"=>1,"b"=>2])>>
42+
function f2() {}
43+
$r = new ReflectionFunction("f2");
44+
var_dump($r->getAttributes());
45+
46+
// Attributes with namespaces
47+
<<Foo\Bar>>
48+
function f4() {
49+
}
50+
$r = new ReflectionFunction("f4");
51+
var_dump($r->getAttributes());
52+
?>
53+
--EXPECT--
54+
array(0) {
55+
}
56+
array(1) {
57+
["TestFunction"]=>
58+
array(0) {
59+
}
60+
}
61+
array(1) {
62+
["TestClass"]=>
63+
array(0) {
64+
}
65+
}
66+
array(1) {
67+
["TestConst"]=>
68+
array(0) {
69+
}
70+
}
71+
array(1) {
72+
["TestProp"]=>
73+
array(0) {
74+
}
75+
}
76+
array(3) {
77+
["a1"]=>
78+
array(0) {
79+
}
80+
["a2"]=>
81+
array(1) {
82+
[0]=>
83+
int(1)
84+
}
85+
["a3"]=>
86+
array(2) {
87+
[0]=>
88+
int(1)
89+
[1]=>
90+
int(2)
91+
}
92+
}
93+
array(4) {
94+
["a1"]=>
95+
array(0) {
96+
}
97+
["a2"]=>
98+
array(1) {
99+
[0]=>
100+
object(ast\Node)#4 (4) {
101+
["kind"]=>
102+
int(520)
103+
["flags"]=>
104+
int(1)
105+
["lineno"]=>
106+
NULL
107+
["children"]=>
108+
array(2) {
109+
[0]=>
110+
int(1)
111+
[1]=>
112+
string(1) "a"
113+
}
114+
}
115+
}
116+
["a3"]=>
117+
array(2) {
118+
[0]=>
119+
object(ast\Node)#5 (4) {
120+
["kind"]=>
121+
int(520)
122+
["flags"]=>
123+
int(1)
124+
["lineno"]=>
125+
NULL
126+
["children"]=>
127+
array(2) {
128+
[0]=>
129+
int(1)
130+
[1]=>
131+
string(1) "b"
132+
}
133+
}
134+
[1]=>
135+
object(ast\Node)#6 (4) {
136+
["kind"]=>
137+
int(520)
138+
["flags"]=>
139+
int(1)
140+
["lineno"]=>
141+
NULL
142+
["children"]=>
143+
array(2) {
144+
[0]=>
145+
int(2)
146+
[1]=>
147+
string(1) "c"
148+
}
149+
}
150+
}
151+
["a4"]=>
152+
array(1) {
153+
[0]=>
154+
object(ast\Node)#7 (4) {
155+
["kind"]=>
156+
int(130)
157+
["flags"]=>
158+
int(0)
159+
["lineno"]=>
160+
NULL
161+
["children"]=>
162+
array(2) {
163+
[0]=>
164+
object(ast\Node)#8 (4) {
165+
["kind"]=>
166+
int(525)
167+
["flags"]=>
168+
int(0)
169+
["lineno"]=>
170+
NULL
171+
["children"]=>
172+
array(2) {
173+
[0]=>
174+
int(1)
175+
[1]=>
176+
string(1) "a"
177+
}
178+
}
179+
[1]=>
180+
object(ast\Node)#9 (4) {
181+
["kind"]=>
182+
int(525)
183+
["flags"]=>
184+
int(0)
185+
["lineno"]=>
186+
NULL
187+
["children"]=>
188+
array(2) {
189+
[0]=>
190+
int(2)
191+
[1]=>
192+
string(1) "b"
193+
}
194+
}
195+
}
196+
}
197+
}
198+
}
199+
array(1) {
200+
["Foo\Bar"]=>
201+
array(0) {
202+
}
203+
}

Zend/tests/attributes_002.phpt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Doctrine-like attributes usage
3+
--FILE--
4+
<?php
5+
namespace Doctrine\ORM {
6+
7+
class Entity {
8+
private $name;
9+
public function __construct($name) {
10+
$this->name = $name;
11+
}
12+
}
13+
14+
function GetClassAttributes($class_name) {
15+
$reflClass = new \ReflectionClass($class_name);
16+
$attrs = $reflClass->getAttributes();
17+
foreach ($attrs as $name => &$values) {
18+
$name = "Doctrine\\" . $name;
19+
$values = new $name(...$values);
20+
}
21+
return $attrs;
22+
}
23+
}
24+
25+
namespace {
26+
<<ORM\Entity("user")>>
27+
class User {}
28+
29+
var_dump(Doctrine\ORM\GetClassAttributes("User"));
30+
}
31+
?>
32+
--EXPECT--
33+
array(1) {
34+
["ORM\Entity"]=>
35+
object(Doctrine\ORM\Entity)#2 (1) {
36+
["name":"Doctrine\ORM\Entity":private]=>
37+
string(4) "user"
38+
}
39+
}

Zend/zend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ struct _zend_class_entry {
177177
uint32_t line_start;
178178
uint32_t line_end;
179179
zend_string *doc_comment;
180+
HashTable *attributes;
180181
} user;
181182
struct {
182183
const struct _zend_function_entry *builtin_functions;

Zend/zend_API.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3491,7 +3491,7 @@ static zend_always_inline zend_bool is_persistent_class(zend_class_entry *ce) {
34913491
&& ce->info.internal.module->type == MODULE_PERSISTENT;
34923492
}
34933493

3494-
ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type) /* {{{ */
3494+
ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes, zend_type type) /* {{{ */
34953495
{
34963496
zend_property_info *property_info, *property_info_ptr;
34973497

@@ -3590,6 +3590,7 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
35903590
property_info->name = zend_new_interned_string(property_info->name);
35913591
property_info->flags = access_type;
35923592
property_info->doc_comment = doc_comment;
3593+
property_info->attributes = attributes;
35933594
property_info->ce = ce;
35943595
property_info->type = type;
35953596

@@ -3726,16 +3727,16 @@ ZEND_API int zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval *zv, ze
37263727
}
37273728
/* }}} */
37283729

3729-
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
3730+
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes) /* {{{ */
37303731
{
3731-
return zend_declare_typed_property(ce, name, property, access_type, doc_comment, (zend_type) ZEND_TYPE_INIT_NONE(0));
3732+
return zend_declare_typed_property(ce, name, property, access_type, doc_comment, attributes, (zend_type) ZEND_TYPE_INIT_NONE(0));
37323733
}
37333734
/* }}} */
37343735

37353736
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */
37363737
{
37373738
zend_string *key = zend_string_init(name, name_length, is_persistent_class(ce));
3738-
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
3739+
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL, NULL);
37393740
zend_string_release(key);
37403741
return ret;
37413742
}
@@ -3795,7 +3796,7 @@ ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *nam
37953796
}
37963797
/* }}} */
37973798

3798-
ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment) /* {{{ */
3799+
ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment, HashTable *attributes) /* {{{ */
37993800
{
38003801
zend_class_constant *c;
38013802

@@ -3822,6 +3823,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
38223823
ZVAL_COPY_VALUE(&c->value, value);
38233824
Z_ACCESS_FLAGS(c->value) = access_type;
38243825
c->doc_comment = doc_comment;
3826+
c->attributes = attributes;
38253827
c->ce = ce;
38263828
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
38273829
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
@@ -3847,7 +3849,7 @@ ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name,
38473849
} else {
38483850
key = zend_string_init(name, name_length, 0);
38493851
}
3850-
ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL);
3852+
ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL, NULL);
38513853
zend_string_release(key);
38523854
return ret;
38533855
}

Zend/zend_API.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,9 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
333333
ZEND_API const char *zend_get_module_version(const char *module_name);
334334
ZEND_API int zend_get_module_started(const char *module_name);
335335

336-
ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type);
336+
ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes, zend_type type);
337337

338-
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment);
338+
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes);
339339
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type);
340340
ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type);
341341
ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
@@ -344,7 +344,7 @@ ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name
344344
ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type);
345345
ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type);
346346

347-
ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment);
347+
ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment, HashTable *attributes);
348348
ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value);
349349
ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length);
350350
ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value);
@@ -650,6 +650,7 @@ END_EXTERN_C()
650650
#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value)
651651
#define RETVAL_RES(r) ZVAL_RES(return_value, r)
652652
#define RETVAL_ARR(r) ZVAL_ARR(return_value, r)
653+
#define RETVAL_IMMUTABLE_ARR(r) ZVAL_IMMUTABLE_ARR(return_value, r)
653654
#define RETVAL_EMPTY_ARRAY() ZVAL_EMPTY_ARRAY(return_value)
654655
#define RETVAL_OBJ(r) ZVAL_OBJ(return_value, r)
655656
#define RETVAL_COPY(zv) ZVAL_COPY(return_value, zv)
@@ -671,6 +672,7 @@ END_EXTERN_C()
671672
#define RETURN_EMPTY_STRING() do { RETVAL_EMPTY_STRING(); return; } while (0)
672673
#define RETURN_RES(r) do { RETVAL_RES(r); return; } while (0)
673674
#define RETURN_ARR(r) do { RETVAL_ARR(r); return; } while (0)
675+
#define RETURN_IMMUTABLE_ARR(r) do { RETVAL_IMMUTABLE_ARR(r); return; } while (0)
674676
#define RETURN_EMPTY_ARRAY() do { RETVAL_EMPTY_ARRAY(); return; } while (0)
675677
#define RETURN_OBJ(r) do { RETVAL_OBJ(r); return; } while (0)
676678
#define RETURN_COPY(zv) do { RETVAL_COPY(zv); return; } while (0)

0 commit comments

Comments
 (0)