BuilderFactory.php 11 KB

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