1--TEST-- 2Attributes in PHP 8.0 on classes 3--SKIPIF-- 4<?php if (PHP_VERSION_ID < 80000) die('skip PHP >= 8.0 only'); ?> 5--FILE-- 6<?php 7 8require __DIR__ . '/../util.php'; 9 10// Some edge cases in parsing attributes to compare other parsers against 11$code = <<<'PHP' 12<?php 13namespace NS; 14 15#[\SomeAttribute()] 16class X { 17 #[Attr1] 18 #[ 19 Attr2(true), # Line comment on an attribute 20 ] 21 public $prop; 22 23 #[Attr3] 24 public const CONST_WITH_ATTRIBUTE = 123; 25 26 #[Attr4, Attr5()] 27 public static function hasAttribute( 28 #[ThisIsAnAttribute, \AnotherAttribute] $parameter 29 ) {} 30} 31#[Deprecated] 32function myGlobal() {} 33PHP; 34 35echo ast_dump(ast\parse_code($code, $version=70)); 36echo "\nIn version 80\n"; 37echo ast_dump(ast\parse_code($code, $version=80)); 38--EXPECTF-- 39AST_STMT_LIST 40 0: AST_NAMESPACE 41 name: "NS" 42 stmts: null 43 1: AST_CLASS 44 name: "X" 45 docComment: null 46 extends: null 47 implements: null 48 stmts: AST_STMT_LIST 49 0: AST_PROP_GROUP 50 flags: MODIFIER_PUBLIC (%d) 51 type: null 52 props: AST_PROP_DECL 53 0: AST_PROP_ELEM 54 name: "prop" 55 default: null 56 docComment: null 57 1: AST_CLASS_CONST_DECL 58 flags: MODIFIER_PUBLIC (%d) 59 0: AST_CONST_ELEM 60 name: "CONST_WITH_ATTRIBUTE" 61 value: 123 62 docComment: null 63 2: AST_METHOD 64 flags: MODIFIER_PUBLIC | MODIFIER_STATIC (%d) 65 name: "hasAttribute" 66 docComment: null 67 params: AST_PARAM_LIST 68 0: AST_PARAM 69 type: null 70 name: "parameter" 71 default: null 72 stmts: AST_STMT_LIST 73 returnType: null 74 __declId: 0 75 __declId: 1 76 2: AST_FUNC_DECL 77 name: "myGlobal" 78 docComment: null 79 params: AST_PARAM_LIST 80 stmts: AST_STMT_LIST 81 returnType: null 82 __declId: 2 83In version 80 84AST_STMT_LIST 85 0: AST_NAMESPACE 86 name: "NS" 87 stmts: null 88 1: AST_CLASS 89 name: "X" 90 docComment: null 91 extends: null 92 implements: null 93 stmts: AST_STMT_LIST 94 0: AST_PROP_GROUP 95 flags: MODIFIER_PUBLIC (%d) 96 type: null 97 props: AST_PROP_DECL 98 0: AST_PROP_ELEM 99 name: "prop" 100 default: null 101 docComment: null 102 attributes: AST_ATTRIBUTE_LIST 103 0: AST_ATTRIBUTE_GROUP 104 0: AST_ATTRIBUTE 105 class: AST_NAME 106 flags: NAME_NOT_FQ (%d) 107 name: "Attr1" 108 args: null 109 1: AST_ATTRIBUTE_GROUP 110 0: AST_ATTRIBUTE 111 class: AST_NAME 112 flags: NAME_NOT_FQ (%d) 113 name: "Attr2" 114 args: AST_ARG_LIST 115 0: AST_CONST 116 name: AST_NAME 117 flags: NAME_NOT_FQ (%d) 118 name: "true" 119 1: AST_CLASS_CONST_GROUP 120 flags: MODIFIER_PUBLIC (%d) 121 const: AST_CLASS_CONST_DECL 122 0: AST_CONST_ELEM 123 name: "CONST_WITH_ATTRIBUTE" 124 value: 123 125 docComment: null 126 attributes: AST_ATTRIBUTE_LIST 127 0: AST_ATTRIBUTE_GROUP 128 0: AST_ATTRIBUTE 129 class: AST_NAME 130 flags: NAME_NOT_FQ (%d) 131 name: "Attr3" 132 args: null 133 2: AST_METHOD 134 flags: MODIFIER_PUBLIC | MODIFIER_STATIC (%d) 135 name: "hasAttribute" 136 docComment: null 137 params: AST_PARAM_LIST 138 0: AST_PARAM 139 type: null 140 name: "parameter" 141 default: null 142 attributes: AST_ATTRIBUTE_LIST 143 0: AST_ATTRIBUTE_GROUP 144 0: AST_ATTRIBUTE 145 class: AST_NAME 146 flags: NAME_NOT_FQ (%d) 147 name: "ThisIsAnAttribute" 148 args: null 149 1: AST_ATTRIBUTE 150 class: AST_NAME 151 flags: NAME_FQ (%d) 152 name: "AnotherAttribute" 153 args: null 154 docComment: null 155 stmts: AST_STMT_LIST 156 returnType: null 157 attributes: AST_ATTRIBUTE_LIST 158 0: AST_ATTRIBUTE_GROUP 159 0: AST_ATTRIBUTE 160 class: AST_NAME 161 flags: NAME_NOT_FQ (%d) 162 name: "Attr4" 163 args: null 164 1: AST_ATTRIBUTE 165 class: AST_NAME 166 flags: NAME_NOT_FQ (%d) 167 name: "Attr5" 168 args: AST_ARG_LIST 169 __declId: 0 170 attributes: AST_ATTRIBUTE_LIST 171 0: AST_ATTRIBUTE_GROUP 172 0: AST_ATTRIBUTE 173 class: AST_NAME 174 flags: NAME_FQ (%d) 175 name: "SomeAttribute" 176 args: AST_ARG_LIST 177 __declId: 1 178 2: AST_FUNC_DECL 179 name: "myGlobal" 180 docComment: null 181 params: AST_PARAM_LIST 182 stmts: AST_STMT_LIST 183 returnType: null 184 attributes: AST_ATTRIBUTE_LIST 185 0: AST_ATTRIBUTE_GROUP 186 0: AST_ATTRIBUTE 187 class: AST_NAME 188 flags: NAME_NOT_FQ (%d) 189 name: "Deprecated" 190 args: null 191 __declId: 2