diff --git a/README.md b/README.md
index 7a48b45..35ef082 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/ast.c b/ast.c
index e372d75..e45b874 100644
--- a/ast.c
+++ b/ast.c
@@ -117,6 +117,16 @@
# define ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (1<<1)
#endif
+#if PHP_VERSION_ID < 80400
+# define MODIFIER_PUBLIC_SET 0
+# define MODIFIER_PROTECTED_SET 0
+# define MODIFIER_PRIVATE_SET 0
+#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
@@ -289,11 +299,22 @@ static const char *closure_use_flags[] = {
AST_FLAG(MODIFIER_FINAL), \
AST_FLAG(MODIFIER_READONLY)
+#define AST_ASYMMETRIC_VISIBILITY_FLAGS \
+ AST_FLAG(MODIFIER_PUBLIC_SET), \
+ AST_FLAG(MODIFIER_PROTECTED_SET), \
+ AST_FLAG(MODIFIER_PRIVATE_SET)
+
static const char *modifier_flags[] = {
AST_MODIFIER_FLAGS,
NULL
};
+static const char *property_modifier_flags[] = {
+ AST_MODIFIER_FLAGS,
+ AST_ASYMMETRIC_VISIBILITY_FLAGS,
+ NULL
+};
+
static const char *func_flags[] = {
AST_MODIFIER_FLAGS,
AST_FLAG(FUNC_RETURNS_REF),
@@ -341,8 +362,8 @@ static const ast_flag_info flag_info[] = {
{ ZEND_AST_CLOSURE, 1, func_flags },
{ ZEND_AST_ARROW_FUNC, 1, func_flags },
{ ZEND_AST_PROPERTY_HOOK, 1, func_flags },
- { ZEND_AST_PROP_DECL, 1, modifier_flags },
- { ZEND_AST_PROP_GROUP, 1, modifier_flags },
+ { ZEND_AST_PROP_DECL, 1, property_modifier_flags },
+ { ZEND_AST_PROP_GROUP, 1, property_modifier_flags },
{ ZEND_AST_CLASS_CONST_DECL, 1, modifier_flags },
{ ZEND_AST_CLASS_CONST_GROUP, 1, modifier_flags },
{ ZEND_AST_TRAIT_ALIAS, 1, modifier_flags },
@@ -1466,6 +1487,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);
diff --git a/ast_stub.php b/ast_stub.php
index 3a6cfcd..e5e5c2a 100644
--- a/ast_stub.php
+++ b/ast_stub.php
@@ -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;
diff --git a/package.xml b/package.xml
index b5680ab..ad0363b 100644
--- a/package.xml
+++ b/package.xml
@@ -52,6 +52,7 @@
+
diff --git a/tests/asymmetric_visibility.phpt b/tests/asymmetric_visibility.phpt
new file mode 100644
index 0000000..78562ae
--- /dev/null
+++ b/tests/asymmetric_visibility.phpt
@@ -0,0 +1,134 @@
+--TEST--
+Asymmetric Visibility in php 8.4
+--SKIPIF--
+=8.4 only'); ?>
+--FILE--
+