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