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