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