Skip to content

Commit 325b636

Browse files
authored
Merge pull request #13 from koolkode/Cleanup
Changes Requested in Review
2 parents b905510 + d905161 commit 325b636

11 files changed

+187
-25
lines changed

Zend/tests/attributes/001_placement.phpt

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ Attributes can be placed on all supported elements.
77
class Foo
88
{
99
<<A1(2)>>
10-
public const FOO = 'foo', BAR = 'bar';
10+
public const FOO = 'foo';
1111

1212
<<A1(3)>>
13-
public $x, $y;
13+
public $x;
1414

1515
<<A1(4)>>
1616
public function foo(<<A1(5)>> $a, <<A1(6)>> $b) { }
@@ -30,9 +30,7 @@ $ref = new \ReflectionClass(Foo::class);
3030
$sources = [
3131
$ref,
3232
$ref->getReflectionConstant('FOO'),
33-
$ref->getReflectionConstant('BAR'),
3433
$ref->getProperty('x'),
35-
$ref->getProperty('y'),
3634
$ref->getMethod('foo'),
3735
$ref->getMethod('foo')->getParameters()[0],
3836
$ref->getMethod('foo')->getParameters()[1],
@@ -71,9 +69,6 @@ array(1) {
7169
int(2)
7270
}
7371

74-
string(23) "ReflectionClassConstant"
75-
int(0)
76-
7772
string(18) "ReflectionProperty"
7873
int(1)
7974
string(2) "A1"
@@ -82,9 +77,6 @@ array(1) {
8277
int(3)
8378
}
8479

85-
string(18) "ReflectionProperty"
86-
int(0)
87-
8880
string(16) "ReflectionMethod"
8981
int(1)
9082
string(2) "A1"
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
--TEST--
2+
Attributes make use of correct scope.
3+
--FILE--
4+
<?php
5+
6+
<<A1(self::class, self::FOO)>>
7+
class C1
8+
{
9+
<<A1(self::class, self::FOO)>>
10+
private const FOO = 'foo';
11+
12+
<<A1(self::class, self::FOO)>>
13+
public $a;
14+
15+
<<A1(self::class, self::FOO)>>
16+
public function bar(<<A1(self::class, self::FOO)>> $p) { }
17+
}
18+
19+
$ref = new \ReflectionClass(C1::class);
20+
print_r($ref->getAttributes()[0]->getArguments());
21+
print_r($ref->getReflectionConstant('FOO')->getAttributes()[0]->getArguments());
22+
print_r($ref->getProperty('a')->getAttributes()[0]->getArguments());
23+
print_r($ref->getMethod('bar')->getAttributes()[0]->getArguments());
24+
print_r($ref->getMethod('bar')->getParameters()[0]->getAttributes()[0]->getArguments());
25+
26+
echo "\n";
27+
28+
class C2
29+
{
30+
private const FOO = 'foo';
31+
32+
public static function foo()
33+
{
34+
return <<A1(self::class, self::FOO)>> function (<<A1(self::class, self::FOO)>> $p) { };
35+
}
36+
}
37+
38+
$ref = new \ReflectionFunction(C2::foo());
39+
print_r($ref->getAttributes()[0]->getArguments());
40+
print_r($ref->getParameters()[0]->getAttributes()[0]->getArguments());
41+
42+
echo "\n";
43+
44+
class C3
45+
{
46+
private const FOO = 'foo';
47+
48+
public static function foo()
49+
{
50+
return new <<A1(self::class, self::FOO)>> class() {
51+
private const FOO = 'bar';
52+
53+
<<A1(self::class, self::FOO)>>
54+
public function bar() { }
55+
};
56+
}
57+
}
58+
59+
$obj = C3::foo();
60+
$ref = new \ReflectionObject($obj);
61+
$name = $ref->getMethod('bar')->getAttributes()[0]->getArguments()[0];
62+
63+
print_r($ref->getAttributes()[0]->getArguments());
64+
var_dump($name == get_class($obj));
65+
var_dump($ref->getMethod('bar')->getAttributes()[0]->getArguments()[1]);
66+
67+
?>
68+
--EXPECT--
69+
Array
70+
(
71+
[0] => C1
72+
[1] => foo
73+
)
74+
Array
75+
(
76+
[0] => C1
77+
[1] => foo
78+
)
79+
Array
80+
(
81+
[0] => C1
82+
[1] => foo
83+
)
84+
Array
85+
(
86+
[0] => C1
87+
[1] => foo
88+
)
89+
Array
90+
(
91+
[0] => C1
92+
[1] => foo
93+
)
94+
95+
Array
96+
(
97+
[0] => C2
98+
[1] => foo
99+
)
100+
Array
101+
(
102+
[0] => C2
103+
[1] => foo
104+
)
105+
106+
Array
107+
(
108+
[0] => C3
109+
[1] => foo
110+
)
111+
bool(true)
112+
string(3) "bar"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Attributes cannot be applied to groups of class constants.
3+
--FILE--
4+
<?php
5+
6+
class C1
7+
{
8+
<<A1>>
9+
public const A = 1, B = 2;
10+
}
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: Cannot apply attributes to a group of constants in %s
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Attributes cannot be applied to groups of properties.
3+
--FILE--
4+
<?php
5+
6+
class C1
7+
{
8+
<<A1>>
9+
public $x, $y;
10+
}
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: Cannot apply attributes to a group of properties in %s

Zend/zend_ast.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
15901590
case ZEND_AST_CLASS_CONST_DECL:
15911591
smart_str_appends(str, "const ");
15921592
goto simple_list;
1593-
case ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES:
1593+
case ZEND_AST_CLASS_CONST_GROUP:
15941594
if (ast->child[1]) {
15951595
zend_ast_export_attributes(str, ast->child[1], indent, 1);
15961596
}
@@ -2192,7 +2192,7 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)
21922192
case ZEND_AST_PARAM:
21932193
ast->child[3] = attr;
21942194
break;
2195-
case ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES:
2195+
case ZEND_AST_CLASS_CONST_GROUP:
21962196
ast->child[1] = attr;
21972197
break;
21982198
EMPTY_SWITCH_DEFAULT_CASE()

Zend/zend_ast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ enum _zend_ast_kind {
139139
ZEND_AST_USE_ELEM,
140140
ZEND_AST_TRAIT_ALIAS,
141141
ZEND_AST_GROUP_USE,
142-
ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES,
142+
ZEND_AST_CLASS_CONST_GROUP,
143143
ZEND_AST_ATTRIBUTE,
144144

145145
/* 3 child nodes */

Zend/zend_attributes.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ ZEND_API void zend_attribute_free(zend_attribute *attr)
3838
efree(attr);
3939
}
4040

41-
ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
41+
static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
4242
{
4343
if (attributes) {
4444
zend_attribute *attr;
@@ -53,7 +53,7 @@ ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *
5353
return NULL;
5454
}
5555

56-
ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset)
56+
static zend_attribute *get_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset)
5757
{
5858
if (attributes) {
5959
zend_attribute *attr;
@@ -70,6 +70,26 @@ ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const cha
7070
return NULL;
7171
}
7272

73+
ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname)
74+
{
75+
return get_attribute(attributes, lcname, 0);
76+
}
77+
78+
ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len)
79+
{
80+
return get_attribute_str(attributes, str, len, 0);
81+
}
82+
83+
ZEND_API zend_attribute *zend_get_parameter_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
84+
{
85+
return get_attribute(attributes, lcname, offset + 1);
86+
}
87+
88+
ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset)
89+
{
90+
return get_attribute_str(attributes, str, len, offset + 1);
91+
}
92+
7393
ZEND_API void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator validator)
7494
{
7595
zend_string *lcname = zend_string_tolower_ex(ce->name, 1);

Zend/zend_attributes.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern ZEND_API zend_class_entry *zend_ce_php_compiler_attribute;
1919
typedef struct _zend_attribute {
2020
zend_string *name;
2121
zend_string *lcname;
22+
/* Parameter offsets start at 1, everything else uses 0. */
2223
uint32_t offset;
2324
uint32_t argc;
2425
zval argv[1];
@@ -28,8 +29,11 @@ typedef void (*zend_attributes_internal_validator)(zend_attribute *attr, int tar
2829

2930
ZEND_API void zend_attribute_free(zend_attribute *attr);
3031

31-
ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset);
32-
ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset);
32+
ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname);
33+
ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len);
34+
35+
ZEND_API zend_attribute *zend_get_parameter_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset);
36+
ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset);
3337

3438
ZEND_API void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator validator);
3539
ZEND_API zend_attributes_internal_validator zend_attribute_get_validator(zend_string *lcname);

Zend/zend_compile.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,7 +2367,7 @@ static inline zend_bool zend_is_variable_or_call(zend_ast *ast) /* {{{ */
23672367
static inline zend_bool zend_is_unticked_stmt(zend_ast *ast) /* {{{ */
23682368
{
23692369
return ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_LABEL
2370-
|| ast->kind == ZEND_AST_PROP_DECL || ast->kind == ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES
2370+
|| ast->kind == ZEND_AST_PROP_DECL || ast->kind == ZEND_AST_CLASS_CONST_GROUP
23712371
|| ast->kind == ZEND_AST_USE_TRAIT || ast->kind == ZEND_AST_METHOD;
23722372
}
23732373
/* }}} */
@@ -6520,8 +6520,6 @@ void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags, H
65206520
}
65216521

65226522
zend_declare_typed_property(ce, name, &value_zv, flags, doc_comment, attributes, type);
6523-
6524-
attributes = NULL;
65256523
}
65266524
}
65276525
/* }}} */
@@ -6534,6 +6532,11 @@ void zend_compile_prop_group(zend_ast *list) /* {{{ */
65346532
zend_ast *prop_ast = list->child[1];
65356533

65366534
if (list->child[2]) {
6535+
if (zend_ast_get_list(prop_ast)->children > 1) {
6536+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot apply attributes to a group of properties");
6537+
return;
6538+
}
6539+
65376540
attributes = create_attribute_array();
65386541
zend_compile_attributes(attributes, list->child[2], 0, ZEND_ATTRIBUTE_TARGET_PROPERTY);
65396542
}
@@ -6567,6 +6570,11 @@ void zend_compile_class_const_decl(zend_ast *ast, zend_ast *attr_ast) /* {{{ */
65676570
}
65686571

65696572
if (attr_ast) {
6573+
if (list->children > 1) {
6574+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot apply attributes to a group of constants");
6575+
return;
6576+
}
6577+
65706578
attributes = create_attribute_array();
65716579
zend_compile_attributes(attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST);
65726580
}
@@ -6586,8 +6594,6 @@ void zend_compile_class_const_decl(zend_ast *ast, zend_ast *attr_ast) /* {{{ */
65866594

65876595
zend_const_expr_to_zval(&value_zv, value_ast);
65886596
zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment, attributes);
6589-
6590-
attributes = NULL;
65916597
}
65926598
}
65936599
/* }}} */
@@ -8885,7 +8891,7 @@ void zend_compile_stmt(zend_ast *ast) /* {{{ */
88858891
case ZEND_AST_PROP_GROUP:
88868892
zend_compile_prop_group(ast);
88878893
break;
8888-
case ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES:
8894+
case ZEND_AST_CLASS_CONST_GROUP:
88898895
zend_compile_class_const_decl(ast->child[0], ast->child[1]);
88908896
break;
88918897
case ZEND_AST_USE_TRAIT:

Zend/zend_language_parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ annotated_class_statement:
786786
{ $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, $3, NULL);
787787
$$->attr = $1; }
788788
| method_modifiers T_CONST class_const_list ';'
789-
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST_DECL_ATTRIBUTES, $3, NULL); $3->attr = $1; }
789+
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST_GROUP, $3, NULL); $3->attr = $1; }
790790
| method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')'
791791
return_type backup_fn_flags method_body backup_fn_flags
792792
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5,

ext/reflection/php_reflection.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6582,7 +6582,7 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
65826582
RETURN_THROWS();
65836583
}
65846584

6585-
if (ce->type == ZEND_USER_CLASS && !zend_get_attribute_str(ce->info.user.attributes, ZEND_STRL("phpattribute"), 0)) {
6585+
if (ce->type == ZEND_USER_CLASS && !zend_get_attribute_str(ce->info.user.attributes, ZEND_STRL("phpattribute"))) {
65866586
zend_throw_error(NULL, "Attempting to use class '%s' as attribute that does not have <<PhpAttribute>>.", ZSTR_VAL(attr->data->name));
65876587
RETURN_THROWS();
65886588
} else if (ce->type == ZEND_INTERNAL_CLASS && !zend_attribute_get_validator(attr->data->lcname)) {

0 commit comments

Comments
 (0)