Skip to content

Commit

Permalink
Support PHP 7.1 class constant visibility
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
nikic committed Mar 10, 2016
1 parent e7c507c commit 26bf9d3
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 11 additions & 3 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions tests/class.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
67 changes: 67 additions & 0 deletions tests/class_consts.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
--TEST--
Class constants
--SKIPIF--
<?php if (PHP_VERSION_ID < 70100) die('skip PHP >= 7.1 only'); ?>
--FILE--
<?php

require __DIR__ . '/../util.php';

$code = <<<'PHP'
<?php
class Test {
/** Doc A */
const A = 1;
public const B = 2;
protected const C = 3;
private const D = 4;
const
/** Doc E */
E = 5,
/** Doc F */
F = 6;
}
PHP;

echo ast_dump(ast\parse_code($code, $version=30));

?>
--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
3 changes: 2 additions & 1 deletion util.php
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down

0 comments on commit 26bf9d3

Please sign in to comment.