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 node a for a literal value. 166 * 167 * @param Expr|bool|null|int|float|string|array $value $value 168 * 169 * @return Expr 170 */ 171 public function val($value) : Expr { 172 return BuilderHelpers::normalizeValue($value); 173 } 174 175 /** 176 * Creates variable node. 177 * 178 * @param string|Expr $name Name 179 * 180 * @return Expr\Variable 181 */ 182 public function var($name) : Expr\Variable { 183 if (!\is_string($name) && !$name instanceof Expr) { 184 throw new \LogicException('Variable name must be string or Expr'); 185 } 186 187 return new Expr\Variable($name); 188 } 189 190 /** 191 * Normalizes an argument list. 192 * 193 * Creates Arg nodes for all arguments and converts literal values to expressions. 194 * 195 * @param array $args List of arguments to normalize 196 * 197 * @return Arg[] 198 */ 199 public function args(array $args) : array { 200 $normalizedArgs = []; 201 foreach ($args as $arg) { 202 if ($arg instanceof Arg) { 203 $normalizedArgs[] = $arg; 204 } else { 205 $normalizedArgs[] = new Arg(BuilderHelpers::normalizeValue($arg)); 206 } 207 } 208 return $normalizedArgs; 209 } 210 211 /** 212 * Creates a function call node. 213 * 214 * @param string|Name|Expr $name Function name 215 * @param array $args Function arguments 216 * 217 * @return Expr\FuncCall 218 */ 219 public function funcCall($name, array $args = []) : Expr\FuncCall { 220 return new Expr\FuncCall( 221 BuilderHelpers::normalizeNameOrExpr($name), 222 $this->args($args) 223 ); 224 } 225 226 /** 227 * Creates a method call node. 228 * 229 * @param Expr $var Variable the method is called on 230 * @param string|Identifier|Expr $name Method name 231 * @param array $args Method arguments 232 * 233 * @return Expr\MethodCall 234 */ 235 public function methodCall(Expr $var, $name, array $args = []) : Expr\MethodCall { 236 return new Expr\MethodCall( 237 $var, 238 BuilderHelpers::normalizeIdentifierOrExpr($name), 239 $this->args($args) 240 ); 241 } 242 243 /** 244 * Creates a static method call node. 245 * 246 * @param string|Name|Expr $class Class name 247 * @param string|Identifier|Expr $name Method name 248 * @param array $args Method arguments 249 * 250 * @return Expr\StaticCall 251 */ 252 public function staticCall($class, $name, array $args = []) : Expr\StaticCall { 253 return new Expr\StaticCall( 254 BuilderHelpers::normalizeNameOrExpr($class), 255 BuilderHelpers::normalizeIdentifierOrExpr($name), 256 $this->args($args) 257 ); 258 } 259 260 /** 261 * Creates an object creation node. 262 * 263 * @param string|Name|Expr $class Class name 264 * @param array $args Constructor arguments 265 * 266 * @return Expr\New_ 267 */ 268 public function new($class, array $args = []) : Expr\New_ { 269 return new Expr\New_( 270 BuilderHelpers::normalizeNameOrExpr($class), 271 $this->args($args) 272 ); 273 } 274 275 /** 276 * Creates a constant fetch node. 277 * 278 * @param string|Name $name Constant name 279 * 280 * @return Expr\ConstFetch 281 */ 282 public function constFetch($name) : Expr\ConstFetch { 283 return new Expr\ConstFetch(BuilderHelpers::normalizeName($name)); 284 } 285 286 /** 287 * Creates a property fetch node. 288 * 289 * @param Expr $var Variable holding object 290 * @param string|Identifier|Expr $name Property name 291 * 292 * @return Expr\PropertyFetch 293 */ 294 public function propertyFetch(Expr $var, $name) : Expr\PropertyFetch { 295 return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name)); 296 } 297 298 /** 299 * Creates a class constant fetch node. 300 * 301 * @param string|Name|Expr $class Class name 302 * @param string|Identifier $name Constant name 303 * 304 * @return Expr\ClassConstFetch 305 */ 306 public function classConstFetch($class, $name): Expr\ClassConstFetch { 307 return new Expr\ClassConstFetch( 308 BuilderHelpers::normalizeNameOrExpr($class), 309 BuilderHelpers::normalizeIdentifier($name) 310 ); 311 } 312 313 /** 314 * Creates nested Concat nodes from a list of expressions. 315 * 316 * @param Expr|string ...$exprs Expressions or literal strings 317 * 318 * @return Concat 319 */ 320 public function concat(...$exprs) : Concat { 321 $numExprs = count($exprs); 322 if ($numExprs < 2) { 323 throw new \LogicException('Expected at least two expressions'); 324 } 325 326 $lastConcat = $this->normalizeStringExpr($exprs[0]); 327 for ($i = 1; $i < $numExprs; $i++) { 328 $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i])); 329 } 330 return $lastConcat; 331 } 332 333 /** 334 * @param string|Expr $expr 335 * @return Expr 336 */ 337 private function normalizeStringExpr($expr) : Expr { 338 if ($expr instanceof Expr) { 339 return $expr; 340 } 341 342 if (\is_string($expr)) { 343 return new String_($expr); 344 } 345 346 throw new \LogicException('Expected string or Expr'); 347 } 348} 349