Port class const decl

This commit is contained in:
Nikita Popov 2014-07-19 15:13:50 +02:00
parent 43d6e599cf
commit 222430d99c
3 changed files with 54 additions and 4 deletions

View file

@ -106,6 +106,9 @@ enum _zend_ast_kind {
ZEND_AST_PROP_DECL,
ZEND_AST_PROP_ELEM,
ZEND_AST_CLASS_CONST_DECL,
ZEND_AST_CONST_ELEM,
};
typedef unsigned short zend_ast_kind;

View file

@ -6512,6 +6512,44 @@ void zend_compile_prop_decl(zend_ast *ast TSRMLS_DC) {
}
}
void zend_compile_class_const_decl(zend_ast *ast TSRMLS_DC) {
zend_class_entry *ce = CG(active_class_entry);
zend_uint i;
for (i = 0; i < ast->children; ++i) {
zend_ast *const_ast = ast->child[i];
zend_ast *name_ast = const_ast->child[0];
zend_ast *value_ast = const_ast->child[1];
zend_string *name = Z_STR_P(zend_ast_get_zval(name_ast));
zval value_zv;
if (ce->ce_flags & ZEND_ACC_TRAIT) {
zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
return;
}
if (value_ast) {
_tmp_compile_const_expr(&value_zv, value_ast TSRMLS_CC);
} else {
ZVAL_NULL(&value_zv);
}
if (Z_TYPE(value_zv) == IS_ARRAY
|| (Z_TYPE(value_zv) == IS_CONSTANT_AST && Z_ASTVAL(value_zv)->kind == ZEND_AST_ARRAY)
) {
zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
}
name = zend_new_interned_string(name TSRMLS_CC);
if (zend_hash_add(&ce->constants_table, name, &value_zv) == NULL) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s",
ce->name->val, name);
}
// TODO.AST doc comment
}
}
void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) {
zend_ast *left_ast = ast->child[0];
zend_ast *right_ast = ast->child[1];
@ -7352,6 +7390,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) {
case ZEND_AST_PROP_DECL:
zend_compile_prop_decl(ast TSRMLS_CC);
break;
case ZEND_AST_CLASS_CONST_DECL:
zend_compile_class_const_decl(ast TSRMLS_CC);
break;
default:
{
znode result;

View file

@ -628,7 +628,7 @@ class_statement_list:
class_statement:
variable_modifiers property_list ';'
{ $$.u.ast = $2.u.ast; $$.u.ast->attr = Z_LVAL($1.u.constant); AS($$); }
| class_constant_declaration ';'
| class_const_list ';' { $$.u.ast = $1.u.ast; AS($$); }
| trait_use_statement
| method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body
{ $$.u.ast = zend_ast_create_func_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
@ -733,9 +733,15 @@ property:
{ $$.u.ast = zend_ast_create_binary(ZEND_AST_PROP_ELEM, AST_ZVAL(&$1), $3.u.ast); }
;
class_constant_declaration:
class_constant_declaration ',' T_STRING '=' static_scalar { zend_do_declare_class_constant(&$3, &$5 TSRMLS_CC); }
| T_CONST T_STRING '=' static_scalar { zend_do_declare_class_constant(&$2, &$4 TSRMLS_CC); }
class_const_list:
class_const_list ',' class_const { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
| class_const
{ $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_CLASS_CONST_DECL, $1.u.ast); }
;
class_const:
T_CONST T_STRING '=' expr
{ $$.u.ast = zend_ast_create_binary(ZEND_AST_CONST_ELEM, AST_ZVAL(&$2), $4.u.ast); }
;
echo_expr_list: