TraitUseAdaptation.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php declare(strict_types=1);
  2. namespace PhpParser\Builder;
  3. use PhpParser\Builder;
  4. use PhpParser\BuilderHelpers;
  5. use PhpParser\Node;
  6. use PhpParser\Node\Stmt;
  7. class TraitUseAdaptation implements Builder
  8. {
  9. const TYPE_UNDEFINED = 0;
  10. const TYPE_ALIAS = 1;
  11. const TYPE_PRECEDENCE = 2;
  12. /** @var int Type of building adaptation */
  13. protected $type;
  14. protected $trait;
  15. protected $method;
  16. protected $modifier = null;
  17. protected $alias = null;
  18. protected $insteadof = [];
  19. /**
  20. * Creates a trait use adaptation builder.
  21. *
  22. * @param Node\Name|string|null $trait Name of adaptated trait
  23. * @param Node\Identifier|string $method Name of adaptated method
  24. */
  25. public function __construct($trait, $method) {
  26. $this->type = self::TYPE_UNDEFINED;
  27. $this->trait = is_null($trait)? null: BuilderHelpers::normalizeName($trait);
  28. $this->method = BuilderHelpers::normalizeIdentifier($method);
  29. }
  30. /**
  31. * Sets alias of method.
  32. *
  33. * @param Node\Identifier|string $alias Alias for adaptated method
  34. *
  35. * @return $this The builder instance (for fluid interface)
  36. */
  37. public function as($alias) {
  38. if ($this->type === self::TYPE_UNDEFINED) {
  39. $this->type = self::TYPE_ALIAS;
  40. }
  41. if ($this->type !== self::TYPE_ALIAS) {
  42. throw new \LogicException('Cannot set alias for not alias adaptation buider');
  43. }
  44. $this->alias = $alias;
  45. return $this;
  46. }
  47. /**
  48. * Sets adaptated method public.
  49. *
  50. * @return $this The builder instance (for fluid interface)
  51. */
  52. public function makePublic() {
  53. $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC);
  54. return $this;
  55. }
  56. /**
  57. * Sets adaptated method protected.
  58. *
  59. * @return $this The builder instance (for fluid interface)
  60. */
  61. public function makeProtected() {
  62. $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED);
  63. return $this;
  64. }
  65. /**
  66. * Sets adaptated method private.
  67. *
  68. * @return $this The builder instance (for fluid interface)
  69. */
  70. public function makePrivate() {
  71. $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE);
  72. return $this;
  73. }
  74. /**
  75. * Adds overwritten traits.
  76. *
  77. * @param Node\Name|string ...$traits Traits for overwrite
  78. *
  79. * @return $this The builder instance (for fluid interface)
  80. */
  81. public function insteadof(...$traits) {
  82. if ($this->type === self::TYPE_UNDEFINED) {
  83. if (is_null($this->trait)) {
  84. throw new \LogicException('Precedence adaptation must have trait');
  85. }
  86. $this->type = self::TYPE_PRECEDENCE;
  87. }
  88. if ($this->type !== self::TYPE_PRECEDENCE) {
  89. throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
  90. }
  91. foreach ($traits as $trait) {
  92. $this->insteadof[] = BuilderHelpers::normalizeName($trait);
  93. }
  94. return $this;
  95. }
  96. protected function setModifier(int $modifier) {
  97. if ($this->type === self::TYPE_UNDEFINED) {
  98. $this->type = self::TYPE_ALIAS;
  99. }
  100. if ($this->type !== self::TYPE_ALIAS) {
  101. throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
  102. }
  103. if (is_null($this->modifier)) {
  104. $this->modifier = $modifier;
  105. } else {
  106. throw new \LogicException('Multiple access type modifiers are not allowed');
  107. }
  108. }
  109. /**
  110. * Returns the built node.
  111. *
  112. * @return Node The built node
  113. */
  114. public function getNode() : Node {
  115. switch ($this->type) {
  116. case self::TYPE_ALIAS:
  117. return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
  118. case self::TYPE_PRECEDENCE:
  119. return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
  120. default:
  121. throw new \LogicException('Type of adaptation is not defined');
  122. }
  123. }
  124. }