Port property declarations

This commit is contained in:
Nikita Popov 2014-07-19 14:54:56 +02:00
parent 1aaaedc1eb
commit 43d6e599cf
3 changed files with 59 additions and 6 deletions

View file

@ -103,6 +103,9 @@ enum _zend_ast_kind {
ZEND_AST_CLOSURE, ZEND_AST_CLOSURE,
ZEND_AST_CLOSURE_USES, ZEND_AST_CLOSURE_USES,
ZEND_AST_METHOD, ZEND_AST_METHOD,
ZEND_AST_PROP_DECL,
ZEND_AST_PROP_ELEM,
}; };
typedef unsigned short zend_ast_kind; typedef unsigned short zend_ast_kind;

View file

@ -6470,6 +6470,48 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
CG(active_op_array) = orig_op_array; CG(active_op_array) = orig_op_array;
} }
void zend_compile_prop_decl(zend_ast *ast TSRMLS_DC) {
zend_uint flags = ast->attr;
zend_class_entry *ce = CG(active_class_entry);
zend_uint i;
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables");
}
if (flags & ZEND_ACC_ABSTRACT) {
zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract");
}
for (i = 0; i < ast->children; ++i) {
zend_ast *prop_ast = ast->child[i];
zend_ast *name_ast = prop_ast->child[0];
zend_ast *value_ast = prop_ast->child[1];
zend_string *name = Z_STR_P(zend_ast_get_zval(name_ast));
zval value_zv;
if (flags & ZEND_ACC_FINAL) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, "
"the final modifier is allowed only for methods and classes",
ce->name->val, name->val);
}
if (zend_hash_exists(&ce->properties_info, name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s",
ce->name->val, name->val);
}
if (value_ast) {
_tmp_compile_const_expr(&value_zv, value_ast TSRMLS_CC);
} else {
ZVAL_NULL(&value_zv);
}
name = zend_new_interned_string(name TSRMLS_CC);
zend_declare_property_ex(ce, name, &value_zv, flags, NULL /* TODO.AST doc comment */ TSRMLS_CC);
}
}
void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) { void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) {
zend_ast *left_ast = ast->child[0]; zend_ast *left_ast = ast->child[0];
zend_ast *right_ast = ast->child[1]; zend_ast *right_ast = ast->child[1];
@ -7307,6 +7349,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) {
case ZEND_AST_METHOD: case ZEND_AST_METHOD:
zend_compile_func_decl(NULL, ast TSRMLS_CC); zend_compile_func_decl(NULL, ast TSRMLS_CC);
break; break;
case ZEND_AST_PROP_DECL:
zend_compile_prop_decl(ast TSRMLS_CC);
break;
default: default:
{ {
znode result; znode result;

View file

@ -626,7 +626,8 @@ class_statement_list:
class_statement: class_statement:
variable_modifiers { CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration ';' variable_modifiers property_list ';'
{ $$.u.ast = $2.u.ast; $$.u.ast->attr = Z_LVAL($1.u.constant); AS($$); }
| class_constant_declaration ';' | class_constant_declaration ';'
| trait_use_statement | trait_use_statement
| method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body | method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body
@ -721,11 +722,15 @@ member_modifier:
| T_FINAL { Z_LVAL($$.u.constant) = ZEND_ACC_FINAL; } | T_FINAL { Z_LVAL($$.u.constant) = ZEND_ACC_FINAL; }
; ;
class_variable_declaration: property_list:
class_variable_declaration ',' T_VARIABLE { zend_do_declare_property(&$3, NULL, CG(access_type) TSRMLS_CC); } property_list ',' property { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
| class_variable_declaration ',' T_VARIABLE '=' static_scalar { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); } | property { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_PROP_DECL, $1.u.ast); }
| T_VARIABLE { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); } ;
| T_VARIABLE '=' static_scalar { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
property:
T_VARIABLE { $$.u.ast = zend_ast_create_binary(ZEND_AST_PROP_ELEM, AST_ZVAL(&$1), NULL); }
| T_VARIABLE '=' expr
{ $$.u.ast = zend_ast_create_binary(ZEND_AST_PROP_ELEM, AST_ZVAL(&$1), $3.u.ast); }
; ;
class_constant_declaration: class_constant_declaration: