1: <?php declare(strict_types=1);
2:
3: namespace PhpParser\Builder;
4:
5: use PhpParser;
6: use PhpParser\BuilderHelpers;
7: use PhpParser\Modifiers;
8: use PhpParser\Node;
9: use PhpParser\Node\Identifier;
10: use PhpParser\Node\Name;
11: use PhpParser\Node\Stmt;
12: use PhpParser\Node\ComplexType;
13:
14: class 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: