1: <?php
2: namespace Pharborist\Functions;
3:
4: use Pharborist\ExpressionNode;
5: use Pharborist\Filter;
6: use Pharborist\Namespaces\NameNode;
7: use Pharborist\Node;
8: use Pharborist\ParentNode;
9: use Pharborist\Token;
10: use Pharborist\TokenNode;
11: use Pharborist\Variables\VariableNode;
12:
13: 14: 15:
16: class ParameterNode extends ParentNode {
17: 18: 19:
20: protected $typeHint;
21:
22: 23: 24:
25: protected $reference;
26:
27: 28: 29:
30: protected $variadic;
31:
32: 33: 34:
35: protected $name;
36:
37: 38: 39:
40: protected $value;
41:
42: 43: 44: 45: 46: 47: 48:
49: public static function create($parameter_name) {
50: $parameter_name = '$' . ltrim($parameter_name, '$');
51: $parameter_node = new ParameterNode();
52: $parameter_node->append(new VariableNode(T_VARIABLE, $parameter_name));
53: return $parameter_node;
54: }
55:
56: 57: 58:
59: protected function childInserted(Node $node) {
60: if ($node instanceof TokenNode) {
61: if ($node->getType() === T_ARRAY || $node->getType() === T_CALLABLE) {
62: $this->typeHint = $node;
63: }
64: elseif ($node->getType() === '&') {
65: $this->reference = $node;
66: }
67: elseif ($node->getType() === T_ELLIPSIS) {
68: $this->variadic = $node;
69: }
70: elseif ($node instanceof VariableNode) {
71: $this->name = $node;
72: }
73: elseif ($node instanceof ExpressionNode) {
74: $this->value = $node;
75: }
76: }
77: elseif ($node instanceof NameNode) {
78: $this->typeHint = $node;
79: }
80: elseif ($node instanceof ExpressionNode) {
81: $this->value = $node;
82: }
83: }
84:
85: 86: 87: 88: 89:
90: public function getFunction() {
91: return $this->closest(Filter::isInstanceOf(
92: 'Pharborist\Functions\FunctionDeclarationNode',
93: 'Pharborist\Objects\ClassMethodNode',
94: 'Pharborist\Objects\InterfaceMethodNode',
95: 'Pharborist\Functions\AnonymousFunctionNode'
96: ));
97: }
98:
99: 100: 101:
102: public function getTypeHint() {
103: return $this->typeHint;
104: }
105:
106: 107: 108: 109:
110: public function setTypeHint($type_hint) {
111: if (is_string($type_hint)) {
112: $type = $type_hint;
113: switch ($type) {
114: case 'array':
115: $type_hint = Token::_array();
116: break;
117: case 'callable':
118: $type_hint = Token::_callable();
119: break;
120: default:
121: $type_hint = new NameNode();
122: $type_hint->append(Token::identifier($type));
123: break;
124: }
125: }
126: if (isset($this->typeHint)) {
127: $this->typeHint->replaceWith($type_hint);
128: }
129: else {
130: $this->prepend([
131: $type_hint,
132: Token::space(),
133: ]);
134: }
135: return $this;
136: }
137:
138: 139: 140:
141: public function getReference() {
142: return $this->reference;
143: }
144:
145: 146: 147: 148:
149: public function setReference($is_reference) {
150: if ($is_reference) {
151: if (!isset($this->reference)) {
152: $this->name->before(Token::reference());
153: }
154: }
155: else {
156: if (isset($this->reference)) {
157: $this->reference->remove();
158: }
159: }
160: return $this;
161: }
162:
163: 164: 165:
166: public function getVariadic() {
167: return $this->variadic;
168: }
169:
170: 171: 172: 173:
174: public function setVariadic($is_variadic) {
175: if ($is_variadic) {
176: if (!isset($this->variadic)) {
177: $this->name->before(Token::splat());
178: }
179: }
180: else {
181: if (isset($this->variadic)) {
182: $this->variadic->remove();
183: }
184: }
185: }
186:
187: 188: 189: 190:
191: public function isVariadic() {
192: return isset($this->variadic);
193: }
194:
195: 196: 197:
198: public function isOptional() {
199: return isset($this->value);
200: }
201:
202: 203: 204:
205: public function isRequired() {
206: return !isset($this->value);
207: }
208:
209: 210: 211:
212: public function getVariable() {
213: return $this->name;
214: }
215:
216: 217: 218: 219:
220: public function getName() {
221: return ltrim($this->getVariable()->getText(), '$');
222: }
223:
224: 225: 226: 227: 228: 229: 230: 231: 232:
233: public function setName($name, $rewrite = FALSE) {
234: $original_name = $this->name->getText();
235:
236: $this->name->setName($name);
237:
238: if ($rewrite) {
239: $this
240: ->getFunction()
241: ->find(Filter::isInstanceOf('\Pharborist\Variables\VariableNode'))
242: ->filter(function(VariableNode $node) use ($original_name) {
243: return $node->getText() === $original_name;
244: })
245: ->each(function(VariableNode $node) use ($name) {
246: $node->setText('$' . $name);
247: });
248: }
249:
250: return $this;
251: }
252:
253: 254: 255:
256: public function getValue() {
257: return $this->value;
258: }
259:
260: 261: 262: 263:
264: public function setValue($node) {
265: if ($node === NULL) {
266: if (isset($this->value)) {
267: $this->value->previousUntil(Filter::isInstanceOf('\Pharborist\Variables\VariableNode'))->remove();
268: $this->value->remove();
269: }
270: }
271: else {
272: if (isset($this->value)) {
273:
274: $this->value->replaceWith($node);
275: }
276: else {
277: $this->append([
278: Token::space(),
279: Token::assign(),
280: Token::space(),
281: $node,
282: ]);
283: }
284: }
285: return $this;
286: }
287:
288: 289: 290: 291: 292: 293:
294: public function getDocBlockTag() {
295: $doc_comment = $this->getFunction()->getDocComment();
296: return $doc_comment->getParameter($this->name->getText());
297: }
298: }
299: