Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ ast\flags\MODIFIER_STATIC
ast\flags\MODIFIER_ABSTRACT
ast\flags\MODIFIER_FINAL
ast\flags\MODIFIER_READONLY
ast\flags\MODIFIER_PUBLIC_SET
ast\flags\MODIFIER_PROTECTED_SET
ast\flags\MODIFIER_PRIVATE_SET

// Used by ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
ast\flags\MODIFIER_STATIC
Expand Down
18 changes: 17 additions & 1 deletion ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@
# define ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (1<<1)
#endif

#if PHP_VERSION_ID < 80400
# define MODIFIER_PUBLIC_SET (1 << 10)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like in PHP 7.3 ZEND_ACC_PRIVATE was 1024: https://github.com/php/php-src/blob/89dc78e0f0c1a4f27b889f232b109a3919ecf478/Zend/zend_compile.h#L214. But for all later versions it was updated to 4: https://github.com/php/php-src/blob/master/Zend/zend_compile.h#L220C9-L220C25.

Because of that introducing MODIFIER_PUBLIC_SET for 7.2./7.3 leads to failed tests. Is there a simple way to introduce modifiers from this PR only for PHP8.4+?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikic seems like setting 0 for the new flags (<8.4) fixes this. Can you please give it a look? And run tests one more time? I`ve run 7.3 and 8.4 tests locally, and it seemed fine.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a good idea to set these to zero. People can reasonably expect that the flags are all disjoint and non-zero. We should find values here that work (but don't have to match any specific PHP version).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I probably should be more clear in my initial comment. Please let me try doing better job at explaining my vision of the problem here:

Because of that, we can't use 1024 value for MODIFIER_PUBLIC_SET for <8.4 versions. As it conflicts with ZEND_ACC_PRIVATE flag on <7.4.

Setting 0 value for MODIFIER_PUBLIC_SET flag for <8.4 seemed as simplest approach. As this flag (and other set modifiers) is not available in those PHP versions at all.

Seems like you are suggesting to use non-zero but not-conflicting (non-existing) flag values for set modifiers for versions where they were unavailable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I`ve just pushed 18ea5b5 and all local test runs were green for that change. @nikic can you please give it a look?

# define MODIFIER_PROTECTED_SET (1 << 11)
# define MODIFIER_PRIVATE_SET (1 << 12)
#else
# define MODIFIER_PUBLIC_SET ZEND_ACC_PUBLIC_SET
# define MODIFIER_PROTECTED_SET ZEND_ACC_PROTECTED_SET
# define MODIFIER_PRIVATE_SET ZEND_ACC_PRIVATE_SET
#endif

#if PHP_VERSION_ID >= 80400
# define ZEND_DIM_ALTERNATIVE_SYNTAX (1<<1)
#endif
Expand Down Expand Up @@ -287,7 +297,10 @@ static const char *closure_use_flags[] = {
AST_FLAG(MODIFIER_STATIC), \
AST_FLAG(MODIFIER_ABSTRACT), \
AST_FLAG(MODIFIER_FINAL), \
AST_FLAG(MODIFIER_READONLY)
AST_FLAG(MODIFIER_READONLY), \
AST_FLAG(MODIFIER_PUBLIC_SET), \
AST_FLAG(MODIFIER_PROTECTED_SET), \
AST_FLAG(MODIFIER_PRIVATE_SET)

static const char *modifier_flags[] = {
AST_MODIFIER_FLAGS,
Expand Down Expand Up @@ -1466,6 +1479,9 @@ PHP_MINIT_FUNCTION(ast) {
ast_register_flag_constant("MODIFIER_ABSTRACT", ZEND_ACC_ABSTRACT);
ast_register_flag_constant("MODIFIER_FINAL", ZEND_ACC_FINAL);
ast_register_flag_constant("MODIFIER_READONLY", ZEND_ACC_READONLY);
ast_register_flag_constant("MODIFIER_PUBLIC_SET", MODIFIER_PUBLIC_SET);
ast_register_flag_constant("MODIFIER_PROTECTED_SET", MODIFIER_PROTECTED_SET);
ast_register_flag_constant("MODIFIER_PRIVATE_SET", MODIFIER_PRIVATE_SET);

ast_register_flag_constant("PARAM_MODIFIER_PUBLIC", PARAM_MODIFIER_PUBLIC);
ast_register_flag_constant("PARAM_MODIFIER_PROTECTED", PARAM_MODIFIER_PROTECTED);
Expand Down
3 changes: 3 additions & 0 deletions ast_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@
const MODIFIER_ABSTRACT = 64;
const MODIFIER_FINAL = 32;
const MODIFIER_READONLY = 128;
const MODIFIER_PUBLIC_SET = 1024;
const MODIFIER_PROTECTED_SET = 2048;
const MODIFIER_PRIVATE_SET = 4096;
const PARAM_MODIFIER_PUBLIC = 1;
const PARAM_MODIFIER_PROTECTED = 2;
const PARAM_MODIFIER_PRIVATE = 4;
Expand Down
1 change: 1 addition & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<file name="assign_ops.phpt" role="test" />
<file name="ast_dump_with_exclude_doc.phpt" role="test" />
<file name="ast_dump_with_linenos.phpt" role="test" />
<file name="asymmetric_visibility.phpt" role="test" />
<file name="attributes_01.phpt" role="test" />
<file name="attributes_02.phpt" role="test" />
<file name="binary_ops.phpt" role="test" />
Expand Down
134 changes: 134 additions & 0 deletions tests/asymmetric_visibility.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
--TEST--
Asymmetric Visibility in php 8.4
--SKIPIF--
<?php if (PHP_VERSION_ID < 80400) die('skip PHP >=8.4 only'); ?>
--FILE--
<?php
require __DIR__ . '/../util.php';
$code = <<<'PHP'
<?php
class PublicPropsWithAV
{
public public(set) int $p1 = 0;
public protected(set) int $p2 = 0;
public private(set) int $p3 = 0;
protected public(set) int $p4 = 0;
protected protected(set) int $p5 = 0;
protected private(set) int $p6 = 0;
private public(set) int $p7 = 0;
private protected(set) int $pp8 = 0;
private private(set) int $p9 = 0;
}
PHP;
$node = ast\parse_code($code, $version=110);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "PublicPropsWithAV"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC | MODIFIER_PUBLIC_SET (1025)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p1"
default: 0
docComment: null
hooks: null
attributes: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC | MODIFIER_PROTECTED_SET (2049)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p2"
default: 0
docComment: null
hooks: null
attributes: null
2: AST_PROP_GROUP
flags: MODIFIER_PUBLIC | MODIFIER_PRIVATE_SET (4097)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p3"
default: 0
docComment: null
hooks: null
attributes: null
3: AST_PROP_GROUP
flags: MODIFIER_PROTECTED | MODIFIER_PUBLIC_SET (1026)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p4"
default: 0
docComment: null
hooks: null
attributes: null
4: AST_PROP_GROUP
flags: MODIFIER_PROTECTED | MODIFIER_PROTECTED_SET (2050)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p5"
default: 0
docComment: null
hooks: null
attributes: null
5: AST_PROP_GROUP
flags: MODIFIER_PROTECTED | MODIFIER_PRIVATE_SET (4098)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p6"
default: 0
docComment: null
hooks: null
attributes: null
6: AST_PROP_GROUP
flags: MODIFIER_PRIVATE | MODIFIER_PUBLIC_SET (1028)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p7"
default: 0
docComment: null
hooks: null
attributes: null
7: AST_PROP_GROUP
flags: MODIFIER_PRIVATE | MODIFIER_PROTECTED_SET (2052)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "pp8"
default: 0
docComment: null
hooks: null
attributes: null
8: AST_PROP_GROUP
flags: MODIFIER_PRIVATE | MODIFIER_PRIVATE_SET (4100)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "p9"
default: 0
docComment: null
hooks: null
attributes: null
attributes: null
type: null
__declId: 0
20 changes: 10 additions & 10 deletions tests/metadata.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ AST_SWITCH_LIST: []
AST_CATCH_LIST: []
AST_PARAM_LIST: []
AST_CLOSURE_USES: []
AST_PROP_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_PROP_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET]
AST_CONST_DECL: []
AST_CLASS_CONST_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_CLASS_CONST_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET]
AST_NAME_LIST: []
AST_TRAIT_ADAPTATIONS: []
AST_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
Expand All @@ -51,12 +51,12 @@ AST_MATCH_ARM_LIST: []
AST_NAME: [NAME_FQ, NAME_NOT_FQ, NAME_RELATIVE]
AST_CLOSURE_VAR: [CLOSURE_USE_REF]
AST_NULLABLE_TYPE: []
AST_FUNC_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_CLOSURE: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_FUNC_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_CLOSURE: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_CLASS: (combinable) [CLASS_ABSTRACT, CLASS_FINAL, CLASS_TRAIT, CLASS_INTERFACE, CLASS_ANONYMOUS, CLASS_ENUM, CLASS_READONLY]
AST_PROPERTY_HOOK: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_PROPERTY_HOOK: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_MAGIC_CONST: [MAGIC_LINE, MAGIC_FILE, MAGIC_DIR, MAGIC_NAMESPACE, MAGIC_FUNCTION, MAGIC_METHOD, MAGIC_CLASS, MAGIC_TRAIT]
AST_TYPE: [TYPE_NULL, TYPE_FALSE, TYPE_TRUE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE, TYPE_STATIC, TYPE_MIXED, TYPE_NEVER]
AST_CALLABLE_CONVERT: []
Expand Down Expand Up @@ -90,7 +90,7 @@ AST_BREAK: []
AST_CONTINUE: []
AST_CLASS_NAME: []
AST_PROPERTY_HOOK_SHORT_BODY: []
AST_CLASS_CONST_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_CLASS_CONST_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET]
AST_DIM: (combinable) [DIM_ALTERNATIVE_SYNTAX, ENCAPS_VAR_DOLLAR_CURLY]
AST_PROP: []
AST_NULLSAFE_PROP: []
Expand All @@ -113,14 +113,14 @@ AST_SWITCH: []
AST_SWITCH_CASE: []
AST_DECLARE: []
AST_PROP_ELEM: []
AST_PROP_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_PROP_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET]
AST_CONST_ELEM: []
AST_USE_TRAIT: []
AST_TRAIT_PRECEDENCE: []
AST_METHOD_REFERENCE: []
AST_NAMESPACE: []
AST_USE_ELEM: [USE_NORMAL, USE_FUNCTION, USE_CONST]
AST_TRAIT_ALIAS: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_TRAIT_ALIAS: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, MODIFIER_PUBLIC_SET, MODIFIER_PROTECTED_SET, MODIFIER_PRIVATE_SET]
AST_GROUP_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
AST_ATTRIBUTE: []
AST_MATCH: []
Expand Down