1: <?php declare(strict_types=1);
2:
3: namespace PhpParser\Builder;
4:
5: use PhpParser;
6: use PhpParser\BuilderHelpers;
7: use PhpParser\Node;
8: use PhpParser\Node\Name;
9: use PhpParser\Node\Stmt;
10:
11: class Class_ extends Declaration
12: {
13: protected $name;
14:
15: protected $extends = null;
16: protected $implements = [];
17: protected $flags = 0;
18:
19: protected $uses = [];
20: protected $constants = [];
21: protected $properties = [];
22: protected $methods = [];
23:
24: /** @var Node\AttributeGroup[] */
25: protected $attributeGroups = [];
26:
27: /**
28: * Creates a class builder.
29: *
30: * @param string $name Name of the class
31: */
32: public function __construct(string $name) {
33: $this->name = $name;
34: }
35:
36: /**
37: * Extends a class.
38: *
39: * @param Name|string $class Name of class to extend
40: *
41: * @return $this The builder instance (for fluid interface)
42: */
43: public function extend($class) {
44: $this->extends = BuilderHelpers::normalizeName($class);
45:
46: return $this;
47: }
48:
49: /**
50: * Implements one or more interfaces.
51: *
52: * @param Name|string ...$interfaces Names of interfaces to implement
53: *
54: * @return $this The builder instance (for fluid interface)
55: */
56: public function implement(...$interfaces) {
57: foreach ($interfaces as $interface) {
58: $this->implements[] = BuilderHelpers::normalizeName($interface);
59: }
60:
61: return $this;
62: }
63:
64: /**
65: * Makes the class abstract.
66: *
67: * @return $this The builder instance (for fluid interface)
68: */
69: public function makeAbstract() {
70: $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT);
71:
72: return $this;
73: }
74:
75: /**
76: * Makes the class final.
77: *
78: * @return $this The builder instance (for fluid interface)
79: */
80: public function makeFinal() {
81: $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_FINAL);
82:
83: return $this;
84: }
85:
86: public function makeReadonly() {
87: $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_READONLY);
88:
89: return $this;
90: }
91:
92: /**
93: * Adds a statement.
94: *
95: * @param Stmt|PhpParser\Builder $stmt The statement to add
96: *
97: * @return $this The builder instance (for fluid interface)
98: */
99: public function addStmt($stmt) {
100: $stmt = BuilderHelpers::normalizeNode($stmt);
101:
102: $targets = [
103: Stmt\TraitUse::class => &$this->uses,
104: Stmt\ClassConst::class => &$this->constants,
105: Stmt\Property::class => &$this->properties,
106: Stmt\ClassMethod::class => &$this->methods,
107: ];
108:
109: $class = \get_class($stmt);
110: if (!isset($targets[$class])) {
111: throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
112: }
113:
114: $targets[$class][] = $stmt;
115:
116: return $this;
117: }
118:
119: /**
120: * Adds an attribute group.
121: *
122: * @param Node\Attribute|Node\AttributeGroup $attribute
123: *
124: * @return $this The builder instance (for fluid interface)
125: */
126: public function addAttribute($attribute) {
127: $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
128:
129: return $this;
130: }
131:
132: /**
133: * Returns the built class node.
134: *
135: * @return Stmt\Class_ The built class node
136: */
137: public function getNode() : PhpParser\Node {
138: return new Stmt\Class_($this->name, [
139: 'flags' => $this->flags,
140: 'extends' => $this->extends,
141: 'implements' => $this->implements,
142: 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods),
143: 'attrGroups' => $this->attributeGroups,
144: ], $this->attributes);
145: }
146: }
147: