1: <?php
2: namespace Pharborist\Objects;
3:
4: use Pharborist\Filter;
5: use Pharborist\FormatterFactory;
6: use Pharborist\Functions\FunctionDeclarationNode;
7: use Pharborist\Node;
8: use Pharborist\Parser;
9: use Pharborist\Settings;
10: use Pharborist\StatementBlockNode;
11: use Pharborist\Token;
12: use Pharborist\TokenNode;
13:
14: 15: 16:
17: class ClassMethodNode extends ClassStatementNode {
18: use MethodTrait;
19:
20: 21: 22:
23: protected $abstract;
24:
25: 26: 27:
28: protected $final;
29:
30: 31: 32:
33: protected $body;
34:
35: 36: 37: 38:
39: public static function create($method_name) {
40:
41: $class_node = Parser::parseSnippet("class Method {public function {$method_name}() {}}");
42: $method_node = $class_node->getStatements()[0]->remove();
43: return $method_node;
44: }
45:
46: 47: 48: 49: 50: 51:
52: public static function fromFunction(FunctionDeclarationNode $function_node) {
53: $method_name = $function_node->getName()->getText();
54: $parameters = $function_node->getParameterList()->getText();
55: $body = $function_node->getBody()->getText();
56:
57: $class_node = Parser::parseSnippet("class Method {public function {$method_name}($parameters) $body}");
58: FormatterFactory::format($class_node);
59: $method_node = $class_node->getStatements()[0]->remove();
60: return $method_node;
61: }
62:
63: 64: 65: 66: 67:
68: public function getAbstract() {
69: return $this->abstract;
70: }
71:
72: 73: 74: 75:
76: public function setAbstract($is_abstract) {
77: if ($is_abstract) {
78: if (!isset($this->abstract)) {
79: $this->abstract = Token::_abstract();
80: $this->prepend([
81: $this->abstract,
82: Token::space(),
83: ]);
84: $this->setFinal(FALSE);
85:
86: $this->getBody()->previous(Filter::isInstanceOf('\Pharborist\WhitespaceNode'))->remove();
87: $this->getBody()->replaceWith(Token::semiColon());
88: $this->body = NULL;
89: }
90: }
91: else {
92: if (isset($this->abstract)) {
93:
94: $this->abstract->next()->remove();
95:
96: $this->abstract->remove();
97:
98: $body = new StatementBlockNode();
99: $body->append([
100: Token::openBrace(),
101: Token::closeBrace(),
102: ]);
103: $this->lastChild()->replaceWith($body);
104: $this->lastChild()->before(Token::space());
105: $this->body = $body;
106: }
107: }
108: return $this;
109: }
110:
111: 112: 113: 114: 115:
116: public function getFinal() {
117: return $this->final;
118: }
119:
120: 121: 122: 123:
124: public function setFinal($is_final) {
125: if ($is_final) {
126: if (!isset($this->final)) {
127: $this->final = Token::_final();
128: $this->prepend([
129: $this->final,
130: Token::space(),
131: ]);
132: $this->setAbstract(FALSE);
133: }
134: }
135: else {
136: if (isset($this->final)) {
137:
138: $this->final->next()->remove();
139:
140: $this->final->remove();
141: }
142: }
143: return $this;
144: }
145:
146: 147: 148:
149: public function getBody() {
150: return $this->body;
151: }
152:
153: 154: 155: 156: 157:
158: public function getFullyQualifiedName() {
159:
160: $class_node = $this->closest(Filter::isInstanceOf('\Pharborist\Objects\ClassNode'));
161: return $class_node->getName()->getAbsolutePath() . '::' . $this->getName()->getText();
162: }
163:
164: protected function childInserted(Node $node) {
165: static $visibilityTypes = [T_PUBLIC, T_PROTECTED, T_PRIVATE];
166: if ($node instanceof TokenNode) {
167: if ($node->getType() === '&') {
168: $this->reference = $node;
169: }
170: elseif (in_array($node->getType(), $visibilityTypes)) {
171: $this->visibility = $node;
172: }
173: elseif ($node->getType() === T_STATIC) {
174: $this->static = $node;
175: }
176: elseif ($node->getType() === T_ABSTRACT) {
177: $this->abstract = $node;
178: }
179: elseif ($node->getType() === T_FINAL) {
180: $this->final = $node;
181: }
182: }
183: }
184: }
185: