From 26bf9d3c9635c1ecf745bb0ede232fc02aecfd71 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 10 Mar 2016 13:30:40 +0100 Subject: [PATCH] Support PHP 7.1 class constant visibility a) CLASS_CONST_DECL now uses modifier flags. For PHP < 7.1 we emuate MODIFIER_PUBLIC here for consistency. b) CONST_ELEM can now have a docComment properts (in analog to the property on PROP_ELEM). --- README.md | 3 +- ast.c | 14 +++++++-- tests/class.phpt | 1 + tests/class_consts.phpt | 67 +++++++++++++++++++++++++++++++++++++++++ util.php | 3 +- 5 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 tests/class_consts.phpt diff --git a/README.md b/README.md index 643f972..2f4449d 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,8 @@ ast\flags\NAME_FQ (= 0) ast\flags\NAME_NOT_FQ ast\flags\NAME_RELATIVE -// Used by ast\AST_METHOD, ast\AST_PROP_DECL, ast\AST_TRAIT_ALIAS (combinable) +// Used by ast\AST_METHOD, ast\AST_PROP_DECL, ast\AST_CLASS_CONST_DECL +// and ast\AST_TRAIT_ALIAS (combinable) ast\flags\MODIFIER_PUBLIC ast\flags\MOFIFIER_PROTECTED ast\flags\MOFIFIER_PRIVATE diff --git a/ast.c b/ast.c index bcee7de..fdb691c 100644 --- a/ast.c +++ b/ast.c @@ -96,7 +96,7 @@ static inline zend_bool ast_kind_uses_attr(zend_ast_kind kind) { || kind == ZEND_AST_CAST || kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_ARRAY_ELEM || kind == ZEND_AST_INCLUDE_OR_EVAL || kind == ZEND_AST_USE || kind == ZEND_AST_PROP_DECL || kind == ZEND_AST_GROUP_USE || kind == ZEND_AST_USE_ELEM - || kind == AST_NAME || kind == AST_CLOSURE_VAR; + || kind == AST_NAME || kind == AST_CLOSURE_VAR || kind == ZEND_AST_CLASS_CONST_DECL; } static inline zend_bool ast_kind_is_decl(zend_ast_kind kind) { @@ -222,7 +222,8 @@ static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, zend_long version ast_create_virtual_node(&child_zv, AST_CLOSURE_VAR, child, version); } else if (version >= 20 && ast_is_var_name(child, ast, i)) { ast_create_virtual_node(&child_zv, ZEND_AST_VAR, child, version); - } else if (ast->kind == ZEND_AST_PROP_ELEM && i == 2) { + } else if (i == 2 + && (ast->kind == ZEND_AST_PROP_ELEM || ast->kind == ZEND_AST_CONST_ELEM)) { /* Skip docComment child -- It's handled separately */ continue; } else { @@ -320,6 +321,11 @@ static void ast_to_zval(zval *zv, zend_ast *ast, zend_long version) { } ast_update_property(zv, AST_STR(str_docComment), &tmp_zv, NULL); } else { +#if PHP_VERSION_ID < 70100 + if (ast->kind == ZEND_AST_CLASS_CONST_DECL) { + ast->attr = ZEND_ACC_PUBLIC; + } +#endif ZVAL_LONG(&tmp_zv, ast->attr); ast_update_property(zv, AST_STR(str_flags), &tmp_zv, AST_CACHE_SLOT_FLAGS); } @@ -338,7 +344,9 @@ static void ast_to_zval(zval *zv, zend_ast *ast, zend_long version) { } } - if (version >= 15 && ast->kind == ZEND_AST_PROP_ELEM && ast->child[2]) { + /* Convert doc comments on properties and constants into properties */ + if ((version >= 15 && ast->kind == ZEND_AST_PROP_ELEM && ast->child[2]) + || (ast->kind == ZEND_AST_CONST_ELEM && ast->child[2])) { ZVAL_STR_COPY(&tmp_zv, zend_ast_get_str(ast->child[2])); ast_update_property(zv, AST_STR(str_docComment), &tmp_zv, NULL); } diff --git a/tests/class.phpt b/tests/class.phpt index c044fcb..a4d5b4f 100644 --- a/tests/class.phpt +++ b/tests/class.phpt @@ -44,6 +44,7 @@ AST_STMT_LIST 0: "S" 1: null 1: AST_CLASS_CONST_DECL + flags: MODIFIER_PUBLIC (256) 0: AST_CONST_ELEM 0: "X" 1: "Y" diff --git a/tests/class_consts.phpt b/tests/class_consts.phpt new file mode 100644 index 0000000..461ba0d --- /dev/null +++ b/tests/class_consts.phpt @@ -0,0 +1,67 @@ +--TEST-- +Class constants +--SKIPIF-- += 7.1 only'); ?> +--FILE-- + +--EXPECT-- +AST_STMT_LIST + 0: AST_CLASS + flags: 0 + name: Test + extends: null + implements: null + stmts: AST_STMT_LIST + 0: AST_CLASS_CONST_DECL + flags: MODIFIER_PUBLIC (256) + 0: AST_CONST_ELEM + docComment: /** Doc A */ + name: "A" + value: 1 + 1: AST_CLASS_CONST_DECL + flags: MODIFIER_PUBLIC (256) + 0: AST_CONST_ELEM + name: "B" + value: 2 + 2: AST_CLASS_CONST_DECL + flags: MODIFIER_PROTECTED (512) + 0: AST_CONST_ELEM + name: "C" + value: 3 + 3: AST_CLASS_CONST_DECL + flags: MODIFIER_PRIVATE (1024) + 0: AST_CONST_ELEM + name: "D" + value: 4 + 4: AST_CLASS_CONST_DECL + flags: MODIFIER_PUBLIC (256) + 0: AST_CONST_ELEM + docComment: /** Doc E */ + name: "E" + value: 5 + 1: AST_CONST_ELEM + docComment: /** Doc F */ + name: "F" + value: 6 diff --git a/util.php b/util.php index 11f42e8..daafd8c 100644 --- a/util.php +++ b/util.php @@ -128,7 +128,8 @@ function get_flag_info() : array { $combinable = []; $combinable[ast\AST_METHOD] = $combinable[ast\AST_FUNC_DECL] = $combinable[ast\AST_CLOSURE] - = $combinable[ast\AST_PROP_DECL] = $combinable[ast\AST_TRAIT_ALIAS] = $modifiers; + = $combinable[ast\AST_PROP_DECL] = $combinable[ast\AST_CLASS_CONST_DECL] + = $combinable[ast\AST_TRAIT_ALIAS] = $modifiers; return [$exclusive, $combinable]; }