1 <?php declare(strict_types=1);
3 namespace PhpParser\Builder;
6 use PhpParser\BuilderHelpers;
8 use PhpParser\Node\Stmt;
10 class TraitUseAdaptation implements Builder
12 const TYPE_UNDEFINED = 0;
14 const TYPE_PRECEDENCE = 2;
16 /** @var int Type of building adaptation */
22 protected $modifier = null;
23 protected $alias = null;
25 protected $insteadof = [];
28 * Creates a trait use adaptation builder.
30 * @param Node\Name|string|null $trait Name of adaptated trait
31 * @param Node\Identifier|string $method Name of adaptated method
33 public function __construct($trait, $method) {
34 $this->type = self::TYPE_UNDEFINED;
36 $this->trait = is_null($trait)? null: BuilderHelpers::normalizeName($trait);
37 $this->method = BuilderHelpers::normalizeIdentifier($method);
41 * Sets alias of method.
43 * @param Node\Identifier|string $alias Alias for adaptated method
45 * @return $this The builder instance (for fluid interface)
47 public function as($alias) {
48 if ($this->type === self::TYPE_UNDEFINED) {
49 $this->type = self::TYPE_ALIAS;
52 if ($this->type !== self::TYPE_ALIAS) {
53 throw new \LogicException('Cannot set alias for not alias adaptation buider');
56 $this->alias = $alias;
61 * Sets adaptated method public.
63 * @return $this The builder instance (for fluid interface)
65 public function makePublic() {
66 $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC);
71 * Sets adaptated method protected.
73 * @return $this The builder instance (for fluid interface)
75 public function makeProtected() {
76 $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED);
81 * Sets adaptated method private.
83 * @return $this The builder instance (for fluid interface)
85 public function makePrivate() {
86 $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE);
91 * Adds overwritten traits.
93 * @param Node\Name|string ...$traits Traits for overwrite
95 * @return $this The builder instance (for fluid interface)
97 public function insteadof(...$traits) {
98 if ($this->type === self::TYPE_UNDEFINED) {
99 if (is_null($this->trait)) {
100 throw new \LogicException('Precedence adaptation must have trait');
103 $this->type = self::TYPE_PRECEDENCE;
106 if ($this->type !== self::TYPE_PRECEDENCE) {
107 throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
110 foreach ($traits as $trait) {
111 $this->insteadof[] = BuilderHelpers::normalizeName($trait);
117 protected function setModifier(int $modifier) {
118 if ($this->type === self::TYPE_UNDEFINED) {
119 $this->type = self::TYPE_ALIAS;
122 if ($this->type !== self::TYPE_ALIAS) {
123 throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
126 if (is_null($this->modifier)) {
127 $this->modifier = $modifier;
129 throw new \LogicException('Multiple access type modifiers are not allowed');
134 * Returns the built node.
136 * @return Node The built node
138 public function getNode() : Node {
139 switch ($this->type) {
140 case self::TYPE_ALIAS:
141 return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
142 case self::TYPE_PRECEDENCE:
143 return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
145 throw new \LogicException('Type of adaptation is not defined');