1<?php declare(strict_types=1); 2 3namespace PhpParser; 4 5use PhpParser\Node\Arg; 6use PhpParser\Node\Expr; 7use PhpParser\Node\Expr\BinaryOp\Concat; 8use PhpParser\Node\Identifier; 9use PhpParser\Node\Name; 10use PhpParser\Node\Scalar\String_; 11use PhpParser\Node\Stmt\Use_; 12 13class BuilderFactory { 14 /** 15 * Creates an attribute node. 16 * 17 * @param string|Name $name Name of the attribute 18 * @param array $args Attribute named arguments 19 */ 20 public function attribute($name, array $args = []): Node\Attribute { 21 return new Node\Attribute( 22 BuilderHelpers::normalizeName($name), 23 $this->args($args) 24 ); 25 } 26 27 /** 28 * Creates a namespace builder. 29 * 30 * @param null|string|Node\Name $name Name of the namespace 31 * 32 * @return Builder\Namespace_ The created namespace builder 33 */ 34 public function namespace($name): Builder\Namespace_ { 35 return new Builder\Namespace_($name); 36 } 37 38 /** 39 * Creates a class builder. 40 * 41 * @param string $name Name of the class 42 * 43 * @return Builder\Class_ The created class builder 44 */ 45 public function class(string $name): Builder\Class_ { 46 return new Builder\Class_($name); 47 } 48 49 /** 50 * Creates an interface builder. 51 * 52 * @param string $name Name of the interface 53 * 54 * @return Builder\Interface_ The created interface builder 55 */ 56 public function interface(string $name): Builder\Interface_ { 57 return new Builder\Interface_($name); 58 } 59 60 /** 61 * Creates a trait builder. 62 * 63 * @param string $name Name of the trait 64 * 65 * @return Builder\Trait_ The created trait builder 66 */ 67 public function trait(string $name): Builder\Trait_ { 68 return new Builder\Trait_($name); 69 } 70 71 /** 72 * Creates an enum builder. 73 * 74 * @param string $name Name of the enum 75 * 76 * @return Builder\Enum_ The created enum builder 77 */ 78 public function enum(string $name): Builder\Enum_ { 79 return new Builder\Enum_($name); 80 } 81 82 /** 83 * Creates a trait use builder. 84 * 85 * @param Node\Name|string ...$traits Trait names 86 * 87 * @return Builder\TraitUse The created trait use builder 88 */ 89 public function useTrait(...$traits): Builder\TraitUse { 90 return new Builder\TraitUse(...$traits); 91 } 92 93 /** 94 * Creates a trait use adaptation builder. 95 * 96 * @param Node\Name|string|null $trait Trait name 97 * @param Node\Identifier|string $method Method name 98 * 99 * @return Builder\TraitUseAdaptation The created trait use adaptation builder 100 */ 101 public function traitUseAdaptation($trait, $method = null): Builder\TraitUseAdaptation { 102 if ($method === null) { 103 $method = $trait; 104 $trait = null; 105 } 106 107 return new Builder\TraitUseAdaptation($trait, $method); 108 } 109 110 /** 111 * Creates a method builder. 112 * 113 * @param string $name Name of the method 114 * 115 * @return Builder\Method The created method builder 116 */ 117 public function method(string $name): Builder\Method { 118 return new Builder\Method($name); 119 } 120 121 /** 122 * Creates a parameter builder. 123 * 124 * @param string $name Name of the parameter 125 * 126 * @return Builder\Param The created parameter builder 127 */ 128 public function param(string $name): Builder\Param { 129 return new Builder\Param($name); 130 } 131 132 /** 133 * Creates a property builder. 134 * 135 * @param string $name Name of the property 136 * 137 * @return Builder\Property The created property builder 138 */ 139 public function property(string $name): Builder\Property { 140 return new Builder\Property($name); 141 } 142 143 /** 144 * Creates a function builder. 145 * 146 * @param string $name Name of the function 147 * 148 * @return Builder\Function_ The created function builder 149 */ 150 public function function(string $name): Builder\Function_ { 151 return new Builder\Function_($name); 152 } 153 154 /** 155 * Creates a namespace/class use builder. 156 * 157 * @param Node\Name|string $name Name of the entity (namespace or class) to alias 158 * 159 * @return Builder\Use_ The created use builder 160 */ 161 public function use($name): Builder\Use_ { 162 return new Builder\Use_($name, Use_::TYPE_NORMAL); 163 } 164 165 /** 166 * Creates a function use builder. 167 * 168 * @param Node\Name|string $name Name of the function to alias 169 * 170 * @return Builder\Use_ The created use function builder 171 */ 172 public function useFunction($name): Builder\Use_ { 173 return new Builder\Use_($name, Use_::TYPE_FUNCTION); 174 } 175 176 /** 177 * Creates a constant use builder. 178 * 179 * @param Node\Name|string $name Name of the const to alias 180 * 181 * @return Builder\Use_ The created use const builder 182 */ 183 public function useConst($name): Builder\Use_ { 184 return new Builder\Use_($name, Use_::TYPE_CONSTANT); 185 } 186 187 /** 188 * Creates a class constant builder. 189 * 190 * @param string|Identifier $name Name 191 * @param Node\Expr|bool|null|int|float|string|array $value Value 192 * 193 * @return Builder\ClassConst The created use const builder 194 */ 195 public function classConst($name, $value): Builder\ClassConst { 196 return new Builder\ClassConst($name, $value); 197 } 198 199 /** 200 * Creates an enum case builder. 201 * 202 * @param string|Identifier $name Name 203 * 204 * @return Builder\EnumCase The created use const builder 205 */ 206 public function enumCase($name): Builder\EnumCase { 207 return new Builder\EnumCase($name); 208 } 209 210 /** 211 * Creates node a for a literal value. 212 * 213 * @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value 214 */ 215 public function val($value): Expr { 216 return BuilderHelpers::normalizeValue($value); 217 } 218 219 /** 220 * Creates variable node. 221 * 222 * @param string|Expr $name Name 223 */ 224 public function var($name): Expr\Variable { 225 if (!\is_string($name) && !$name instanceof Expr) { 226 throw new \LogicException('Variable name must be string or Expr'); 227 } 228 229 return new Expr\Variable($name); 230 } 231 232 /** 233 * Normalizes an argument list. 234 * 235 * Creates Arg nodes for all arguments and converts literal values to expressions. 236 * 237 * @param array $args List of arguments to normalize 238 * 239 * @return list<Arg> 240 */ 241 public function args(array $args): array { 242 $normalizedArgs = []; 243 foreach ($args as $key => $arg) { 244 if (!($arg instanceof Arg)) { 245 $arg = new Arg(BuilderHelpers::normalizeValue($arg)); 246 } 247 if (\is_string($key)) { 248 $arg->name = BuilderHelpers::normalizeIdentifier($key); 249 } 250 $normalizedArgs[] = $arg; 251 } 252 return $normalizedArgs; 253 } 254 255 /** 256 * Creates a function call node. 257 * 258 * @param string|Name|Expr $name Function name 259 * @param array $args Function arguments 260 */ 261 public function funcCall($name, array $args = []): Expr\FuncCall { 262 return new Expr\FuncCall( 263 BuilderHelpers::normalizeNameOrExpr($name), 264 $this->args($args) 265 ); 266 } 267 268 /** 269 * Creates a method call node. 270 * 271 * @param Expr $var Variable the method is called on 272 * @param string|Identifier|Expr $name Method name 273 * @param array $args Method arguments 274 */ 275 public function methodCall(Expr $var, $name, array $args = []): Expr\MethodCall { 276 return new Expr\MethodCall( 277 $var, 278 BuilderHelpers::normalizeIdentifierOrExpr($name), 279 $this->args($args) 280 ); 281 } 282 283 /** 284 * Creates a static method call node. 285 * 286 * @param string|Name|Expr $class Class name 287 * @param string|Identifier|Expr $name Method name 288 * @param array $args Method arguments 289 */ 290 public function staticCall($class, $name, array $args = []): Expr\StaticCall { 291 return new Expr\StaticCall( 292 BuilderHelpers::normalizeNameOrExpr($class), 293 BuilderHelpers::normalizeIdentifierOrExpr($name), 294 $this->args($args) 295 ); 296 } 297 298 /** 299 * Creates an object creation node. 300 * 301 * @param string|Name|Expr $class Class name 302 * @param array $args Constructor arguments 303 */ 304 public function new($class, array $args = []): Expr\New_ { 305 return new Expr\New_( 306 BuilderHelpers::normalizeNameOrExpr($class), 307 $this->args($args) 308 ); 309 } 310 311 /** 312 * Creates a constant fetch node. 313 * 314 * @param string|Name $name Constant name 315 */ 316 public function constFetch($name): Expr\ConstFetch { 317 return new Expr\ConstFetch(BuilderHelpers::normalizeName($name)); 318 } 319 320 /** 321 * Creates a property fetch node. 322 * 323 * @param Expr $var Variable holding object 324 * @param string|Identifier|Expr $name Property name 325 */ 326 public function propertyFetch(Expr $var, $name): Expr\PropertyFetch { 327 return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name)); 328 } 329 330 /** 331 * Creates a class constant fetch node. 332 * 333 * @param string|Name|Expr $class Class name 334 * @param string|Identifier|Expr $name Constant name 335 */ 336 public function classConstFetch($class, $name): Expr\ClassConstFetch { 337 return new Expr\ClassConstFetch( 338 BuilderHelpers::normalizeNameOrExpr($class), 339 BuilderHelpers::normalizeIdentifierOrExpr($name) 340 ); 341 } 342 343 /** 344 * Creates nested Concat nodes from a list of expressions. 345 * 346 * @param Expr|string ...$exprs Expressions or literal strings 347 */ 348 public function concat(...$exprs): Concat { 349 $numExprs = count($exprs); 350 if ($numExprs < 2) { 351 throw new \LogicException('Expected at least two expressions'); 352 } 353 354 $lastConcat = $this->normalizeStringExpr($exprs[0]); 355 for ($i = 1; $i < $numExprs; $i++) { 356 $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i])); 357 } 358 return $lastConcat; 359 } 360 361 /** 362 * @param string|Expr $expr 363 */ 364 private function normalizeStringExpr($expr): Expr { 365 if ($expr instanceof Expr) { 366 return $expr; 367 } 368 369 if (\is_string($expr)) { 370 return new String_($expr); 371 } 372 373 throw new \LogicException('Expected string or Expr'); 374 } 375} 376