]> granicus.if.org Git - php/commitdiff
Handle ::class in const expr via ast as well
authorNikita Popov <nikic@php.net>
Thu, 26 Jun 2014 19:44:46 +0000 (21:44 +0200)
committerNikita Popov <nikic@php.net>
Thu, 26 Jun 2014 19:44:46 +0000 (21:44 +0200)
Zend/zend_compile.c
Zend/zend_language_parser.y

index 50e6e5f5fff66a75c015f26fafd9d998babf20d3..1c5c951a4b3f1bbc06ca9e7f86ce832188383e77 100644 (file)
@@ -7795,7 +7795,8 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) {
                || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS
                || kind == ZEND_AST_CONDITIONAL
                || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
-               || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST;
+               || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
+               || kind == ZEND_AST_RESOLVE_CLASS_NAME;
 }
 
 void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) {
@@ -7868,6 +7869,39 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr TSRMLS_DC) {
        *ast_ptr = zend_ast_create_constant(&result.u.constant);
 }
 
+void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr TSRMLS_DC) {
+       zend_ast *ast = *ast_ptr;
+       zend_ast *name_ast = ast->child[0];
+       zval *name = zend_ast_get_zval(name_ast);
+       int fetch_type = zend_get_class_fetch_type(Z_STRVAL_P(name), Z_STRLEN_P(name));
+       znode result;
+
+       switch (fetch_type) {
+               case ZEND_FETCH_CLASS_SELF:
+                       if (!CG(active_class_entry)) {
+                               zend_error_noreturn(E_COMPILE_ERROR,
+                                       "Cannot access self::class when no class scope is active");
+                       }
+                       ZVAL_STR(&result.u.constant, STR_COPY(CG(active_class_entry)->name));
+                       break;
+        case ZEND_FETCH_CLASS_STATIC:
+        case ZEND_FETCH_CLASS_PARENT:
+                       zend_error_noreturn(E_COMPILE_ERROR,
+                               "%s::class cannot be used for compile-time class name resolution",
+                               fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
+                       );
+                       break;
+               case ZEND_FETCH_CLASS_DEFAULT:
+                       zend_compile_expr(&result, name_ast TSRMLS_CC);
+                       zend_resolve_class_name(&result TSRMLS_CC);
+                       break;
+               EMPTY_SWITCH_DEFAULT_CASE()
+       }
+
+       zend_ast_destroy(ast);
+       *ast_ptr = zend_ast_create_constant(&result.u.constant);
+}
+
 void zend_compile_const_expr(zend_ast **ast_ptr TSRMLS_DC) {
        zend_ast *ast = *ast_ptr;
        if (ast == NULL || ast->kind == ZEND_CONST) {
@@ -7892,6 +7926,9 @@ void zend_compile_const_expr(zend_ast **ast_ptr TSRMLS_DC) {
                case ZEND_AST_CONST:
                        zend_compile_const_expr_const(ast_ptr TSRMLS_CC);
                        break;
+               case ZEND_AST_RESOLVE_CLASS_NAME:
+                       zend_compile_const_expr_resolve_class_name(ast_ptr TSRMLS_CC);
+                       break;
        }
 }
 
index 6de001a5702d02bf6bd987d793d972b5f53f6135..3dbb27675c6675166d63051bee4463608604a276 100644 (file)
@@ -978,7 +978,8 @@ static_scalar: /* compile-time evaluated scalars */
 
 static_scalar_value:
                T_CONSTANT_ENCAPSED_STRING      { $$.u.ast = AST_ZVAL(&$1); }
-       |       static_class_name_scalar        { $$.u.ast = AST_ZVAL(&$1); }
+       |       class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS
+                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_RESOLVE_CLASS_NAME, AST_ZVAL(&$1)); }
        |       class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING
                        { $$.u.ast = zend_ast_create_binary(
                              ZEND_AST_CLASS_CONST, AST_ZVAL(&$1), AST_ZVAL(&$3)); }
@@ -1329,10 +1330,6 @@ class_constant:
                              ZEND_AST_CLASS_CONST, $1.u.ast, AST_ZVAL(&$3)); }
 ;
 
-static_class_name_scalar:
-       class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS { zend_do_resolve_class_name(&$$, &$1, 1 TSRMLS_CC); }
-;
-
 class_name_scalar:
        class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS
                { $$.u.ast = zend_ast_create_unary(ZEND_AST_RESOLVE_CLASS_NAME, AST_ZVAL(&$1)); }