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