1: <?php
2: namespace Pharborist\Functions;
3:
4: use Pharborist\CommaListNode;
5: use Pharborist\ExpressionNode;
6: use Pharborist\Filter;
7: use Pharborist\Node;
8: use Pharborist\NodeCollection;
9: use Pharborist\ParentNode;
10: use Pharborist\ParenTrait;
11: use Pharborist\StatementBlockNode;
12: use Pharborist\Token;
13: use Pharborist\TokenNode;
14:
15: 16: 17:
18: class AnonymousFunctionNode extends ParentNode implements ExpressionNode {
19: use ParenTrait;
20: use ParameterTrait;
21:
22: 23: 24:
25: protected $reference;
26:
27: 28: 29:
30: protected $lexicalUse;
31:
32: 33: 34:
35: protected $lexicalOpenParen;
36:
37: 38: 39:
40: protected $lexicalCloseParen;
41:
42: 43: 44:
45: protected $lexicalVariables;
46:
47: 48: 49:
50: protected $body;
51:
52: 53: 54:
55: public function getReference() {
56: return $this->reference;
57: }
58:
59: 60: 61: 62:
63: public function setReference($is_reference) {
64: if ($is_reference) {
65: if (!isset($this->reference)) {
66: $this->openParen->before(Token::reference());
67: }
68: }
69: else {
70: if (isset($this->reference)) {
71: $this->reference->remove();
72: }
73: }
74: return $this;
75: }
76:
77: 78: 79:
80: public function getLexicalVariableList() {
81: return $this->lexicalVariables;
82: }
83:
84: 85: 86:
87: public function getLexicalVariables() {
88: return $this->lexicalVariables->getItems();
89: }
90:
91: 92: 93:
94: public function hasLexicalVariables() {
95: return isset($this->lexicalVariables);
96: }
97:
98: 99: 100:
101: public function getLexicalUse() {
102: return $this->lexicalUse;
103: }
104:
105: 106: 107:
108: public function getLexicalOpenParen() {
109: return $this->lexicalOpenParen;
110: }
111:
112: 113: 114:
115: public function getLexicalCloseParen() {
116: return $this->lexicalCloseParen;
117: }
118:
119: 120: 121:
122: protected function createLexicalVariables() {
123: if (!$this->hasLexicalVariables()) {
124: $this->lexicalUse = Token::_use();
125: $this->lexicalOpenParen = Token::openParen();
126: $this->lexicalVariables = new CommaListNode();
127: $this->lexicalCloseParen = Token::closeParen();
128: $this->closeParen->after([
129: Token::space(),
130: $this->lexicalUse,
131: Token::space(),
132: $this->lexicalOpenParen,
133: $this->lexicalVariables,
134: $this->lexicalCloseParen,
135: ]);
136: }
137: }
138:
139: 140: 141:
142: public function appendLexicalVariable(LexicalVariableNode $variable) {
143: $this->createLexicalVariables();
144: $this->lexicalVariables->appendItem($variable);
145: }
146:
147: 148: 149:
150: public function prependLexicalVariable(LexicalVariableNode $variable) {
151: $this->createLexicalVariables();
152: $this->lexicalVariables->prependItem($variable);
153: }
154:
155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166:
167: public function insertLexicalVariable(LexicalVariableNode $variable, $index) {
168: if ($index < 0) {
169: throw new \OutOfBoundsException('index out of bounds');
170: }
171: if (!$this->hasLexicalVariables() && $index !== 0) {
172: throw new \OutOfBoundsException('index out of bounds');
173: }
174: $this->createLexicalVariables();
175: $this->lexicalVariables->insertItem($variable, $index);
176: }
177:
178: public function clearLexicalVariables() {
179: if ($this->hasLexicalVariables()) {
180: $this->lexicalUse->nextUntil(Filter::is($this->body))->remove();
181: $this->lexicalUse->remove();
182: }
183: }
184:
185: 186: 187:
188: public function getBody() {
189: return $this->body;
190: }
191:
192: protected function childInserted(Node $node) {
193: if ($node instanceof TokenNode && $node->getType() === '&') {
194: $this->reference = $node;
195: }
196: }
197: }
198: