1<?php declare(strict_types=1); 2 3namespace PhpParser\Builder; 4 5use PhpParser; 6use PhpParser\BuilderHelpers; 7use PhpParser\Modifiers; 8use PhpParser\Node; 9use PhpParser\Node\Identifier; 10use PhpParser\Node\Name; 11use PhpParser\Node\Stmt; 12use PhpParser\Node\ComplexType; 13 14class Property implements PhpParser\Builder { 15 protected string $name; 16 17 protected int $flags = 0; 18 19 protected ?Node\Expr $default = null; 20 /** @var array<string, mixed> */ 21 protected array $attributes = []; 22 /** @var null|Identifier|Name|ComplexType */ 23 protected ?Node $type = null; 24 /** @var list<Node\AttributeGroup> */ 25 protected array $attributeGroups = []; 26 /** @var list<Node\PropertyHook> */ 27 protected array $hooks = []; 28 29 /** 30 * Creates a property builder. 31 * 32 * @param string $name Name of the property 33 */ 34 public function __construct(string $name) { 35 $this->name = $name; 36 } 37 38 /** 39 * Makes the property public. 40 * 41 * @return $this The builder instance (for fluid interface) 42 */ 43 public function makePublic() { 44 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC); 45 46 return $this; 47 } 48 49 /** 50 * Makes the property protected. 51 * 52 * @return $this The builder instance (for fluid interface) 53 */ 54 public function makeProtected() { 55 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED); 56 57 return $this; 58 } 59 60 /** 61 * Makes the property private. 62 * 63 * @return $this The builder instance (for fluid interface) 64 */ 65 public function makePrivate() { 66 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE); 67 68 return $this; 69 } 70 71 /** 72 * Makes the property static. 73 * 74 * @return $this The builder instance (for fluid interface) 75 */ 76 public function makeStatic() { 77 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC); 78 79 return $this; 80 } 81 82 /** 83 * Makes the property readonly. 84 * 85 * @return $this The builder instance (for fluid interface) 86 */ 87 public function makeReadonly() { 88 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY); 89 90 return $this; 91 } 92 93 /** 94 * Makes the property abstract. Requires at least one property hook to be specified as well. 95 * 96 * @return $this The builder instance (for fluid interface) 97 */ 98 public function makeAbstract() { 99 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT); 100 101 return $this; 102 } 103 104 /** 105 * Makes the property final. 106 * 107 * @return $this The builder instance (for fluid interface) 108 */ 109 public function makeFinal() { 110 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL); 111 112 return $this; 113 } 114 115 /** 116 * Gives the property private(set) visibility. 117 * 118 * @return $this The builder instance (for fluid interface) 119 */ 120 public function makePrivateSet() { 121 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET); 122 123 return $this; 124 } 125 126 /** 127 * Gives the property protected(set) visibility. 128 * 129 * @return $this The builder instance (for fluid interface) 130 */ 131 public function makeProtectedSet() { 132 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET); 133 134 return $this; 135 } 136 137 /** 138 * Sets default value for the property. 139 * 140 * @param mixed $value Default value to use 141 * 142 * @return $this The builder instance (for fluid interface) 143 */ 144 public function setDefault($value) { 145 $this->default = BuilderHelpers::normalizeValue($value); 146 147 return $this; 148 } 149 150 /** 151 * Sets doc comment for the property. 152 * 153 * @param PhpParser\Comment\Doc|string $docComment Doc comment to set 154 * 155 * @return $this The builder instance (for fluid interface) 156 */ 157 public function setDocComment($docComment) { 158 $this->attributes = [ 159 'comments' => [BuilderHelpers::normalizeDocComment($docComment)] 160 ]; 161 162 return $this; 163 } 164 165 /** 166 * Sets the property type for PHP 7.4+. 167 * 168 * @param string|Name|Identifier|ComplexType $type 169 * 170 * @return $this 171 */ 172 public function setType($type) { 173 $this->type = BuilderHelpers::normalizeType($type); 174 175 return $this; 176 } 177 178 /** 179 * Adds an attribute group. 180 * 181 * @param Node\Attribute|Node\AttributeGroup $attribute 182 * 183 * @return $this The builder instance (for fluid interface) 184 */ 185 public function addAttribute($attribute) { 186 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute); 187 188 return $this; 189 } 190 191 /** 192 * Adds a property hook. 193 * 194 * @return $this The builder instance (for fluid interface) 195 */ 196 public function addHook(Node\PropertyHook $hook) { 197 $this->hooks[] = $hook; 198 199 return $this; 200 } 201 202 /** 203 * Returns the built class node. 204 * 205 * @return Stmt\Property The built property node 206 */ 207 public function getNode(): PhpParser\Node { 208 if ($this->flags & Modifiers::ABSTRACT && !$this->hooks) { 209 throw new PhpParser\Error('Only hooked properties may be declared abstract'); 210 } 211 212 return new Stmt\Property( 213 $this->flags !== 0 ? $this->flags : Modifiers::PUBLIC, 214 [ 215 new Node\PropertyItem($this->name, $this->default) 216 ], 217 $this->attributes, 218 $this->type, 219 $this->attributeGroups, 220 $this->hooks 221 ); 222 } 223} 224