Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/fastphp/trunk/codeexplorer.php
Revision: 55
Committed: Thu Aug 15 14:22:52 2019 UTC (7 months, 2 weeks ago) by daniel-marschall
File size: 9509 byte(s)
Log Message:
Better solution for removing anonymous functions from the treeview

File Contents

# Content
1 <?php
2
3 // TODO: show full signature of each element?
4
5 error_reporting(0);
6
7 require_once __DIR__ . '/codeexplorer_api.inc.php';
8
9 define('ICON_TYPE_FUNCTION', 1);
10 define('ICON_TYPE_CONSTRUCTOR', 2);
11 define('ICON_TYPE_DESTRUCTOR', 3);
12 define('ICON_TYPE_MAGICMETHOD', 4);
13 define('ICON_TYPE_CLASS', 5);
14 define('ICON_TYPE_TRAIT', 6);
15 define('ICON_TYPE_INTERFACE', 7);
16 define('ICON_TYPE_VAR', 8);
17 define('ICON_TYPE_CONST', 9);
18 define('ICON_TYPE_TODO', 10);
19 define('ICON_TYPE_ERROR', 11);
20
21 class MyFastPHPIcon extends FastPHPIcon {
22
23 public function imageIndex() {
24 if (($this->getType() == ICON_TYPE_CLASS) && (!$this->isAbstract())) return 0; // class
25 else if (($this->getType() == ICON_TYPE_CLASS) && ( $this->isAbstract())) return 1; // abstract class
26 else if (($this->getType() == ICON_TYPE_INTERFACE) ) return 2; // interface
27 else if (($this->getType() == ICON_TYPE_TRAIT) ) return 3; // trait
28 else if (($this->getType() == ICON_TYPE_CONST) && ($this->isPrivate()) ) return 4; // private const
29 else if (($this->getType() == ICON_TYPE_VAR) && ($this->isPrivate()) ) return 5; // private var
30 else if (($this->isMethod()) && ($this->isPrivate()) && (!$this->isAbstract())) return 6; // private function
31 else if (($this->isMethod()) && ($this->isPrivate()) && ( $this->isAbstract())) return 7; // private abstract function
32 else if (($this->getType() == ICON_TYPE_CONST) && ($this->isProtected()) ) return 8; // protected const
33 else if (($this->getType() == ICON_TYPE_VAR) && ($this->isProtected()) ) return 9; // protected var
34 else if (($this->isMethod()) && ($this->isProtected()) && (!$this->isAbstract())) return 10; // protected function
35 else if (($this->isMethod()) && ($this->isProtected()) && ( $this->isAbstract())) return 11; // protected abstract function
36 else if (($this->getType() == ICON_TYPE_CONST) && ($this->isPublic()) ) return 12; // public const
37 else if (($this->getType() == ICON_TYPE_VAR) && ($this->isPublic()) ) return 13; // public var
38 else if (($this->isMethod()) && ($this->isPublic()) && (!$this->isAbstract())) return 14; // public function
39 else if (($this->isMethod()) && ($this->isPublic()) && ( $this->isAbstract())) return 15; // public abstract function
40 else if (($this->getType() == ICON_TYPE_TODO) ) return 16; // To-Do comment
41 else return -1;
42 }
43
44 public function isMethod() {
45 return (($this->getType() == ICON_TYPE_FUNCTION) ||
46 ($this->getType() == ICON_TYPE_CONSTRUCTOR) ||
47 ($this->getType() == ICON_TYPE_DESTRUCTOR) ||
48 ($this->getType() == ICON_TYPE_MAGICMETHOD));
49 }
50
51 }
52
53 class MyFastPHPCodeExplorer {
54
55 public function handle($code) {
56 $token = token_get_all($code);
57 $wait_function = false;
58 $wait_const = false;
59 $wait_class = false;
60 $wait_trait = false;
61 $icon = new MyFastPHPIcon();
62 $wait_interface = false;
63 $wait_abstract_func_list_end = false;
64 $levelAry = array();
65 $dep = 0;
66 $insideFuncAry = array();
67
68 if (!$token) {
69 $icon->setType(ICON_TYPE_ERROR);
70 FastPHPWriter::outputLeafNode($icon, 0, 'SYNTAX ERROR');
71 }
72
73 foreach ($token as $data) {
74 if ($data == '{') $dep++;
75 if ($data == '}') {
76 $dep--;
77 if ((count($levelAry) > 0) && (self::array_peek($levelAry) == $dep)) {
78 array_pop($levelAry);
79 FastPHPWriter::outputDecreaseLevel();
80 }
81 if ((count($insideFuncAry) > 0) && (self::array_peek($insideFuncAry) == $dep)) {
82 array_pop($insideFuncAry);
83 }
84 }
85
86 $token = (!is_array($data)) ? null : $data[0];
87 $value = (!is_array($data)) ? null : $data[1];
88 $line = (!is_array($data)) ? null : $data[2];
89
90 if ($value == '${') $dep++;
91
92 if ($wait_function && ($data == '{')) {
93 $wait_function = false; // Anonymous functions do not have a name
94 }
95
96 if ($wait_function && ($token == T_STRING)) {
97 $wait_function = false;
98 if ($icon->isAbstract()) {
99 $desc = "abstract function $value()";
100 $wait_abstract_func_list_end = true;
101 } else {
102 $desc = "function $value()";
103 $insideFuncAry[] = $dep;
104 }
105
106 if ($value == '__construct') { // TODO: auch eine methode mit dem namen der klasse soll eine konstruktor sein
107 $icon->setType(ICON_TYPE_CONSTRUCTOR);
108 } else if ($value == '__destruct') {
109 $icon->setType(ICON_TYPE_DESTRUCTOR);
110 } else if (substr($value, 0, 2) == '__') {
111 $icon->setType(ICON_TYPE_MAGICMETHOD);
112 } else {
113 $icon->setType(ICON_TYPE_FUNCTION);
114 }
115 FastPHPWriter::outputLeafNode($icon, $line, $desc);
116 $icon->reset();
117 }
118
119 if ($wait_class && ($token == T_STRING)) {
120 if ($icon->isAbstract()) {
121 $desc = "Abstract Class $value\n";
122 } else {
123 $desc = "Class $value\n";
124 }
125 $wait_class = false;
126 $levelAry[] = $dep;
127
128 $icon->setType(ICON_TYPE_CLASS);
129 FastPHPWriter::outputLeafNode($icon, $line, $desc);
130 $icon->reset();
131
132 FastPHPWriter::outputIncreaseLevel();
133 }
134
135 if ($wait_trait && ($token == T_STRING)) {
136 $desc = "Trait $value\n";
137 $wait_trait = false;
138 $levelAry[] = $dep;
139
140 $icon->setType(ICON_TYPE_TRAIT);
141 FastPHPWriter::outputLeafNode($icon, $line, $desc);
142 $icon->reset();
143
144 FastPHPWriter::outputIncreaseLevel();
145 }
146
147 if ($wait_interface && ($token == T_STRING)) {
148 $desc = "Interface $value\n";
149 $wait_interface = false;
150 $levelAry[] = $dep;
151
152 $icon->setType(ICON_TYPE_INTERFACE);
153 FastPHPWriter::outputLeafNode($icon, $line, $desc);
154 $icon->reset();
155
156 FastPHPWriter::outputIncreaseLevel();
157 }
158
159 if ($wait_const && ($token == T_STRING)) {
160 $desc = "const $value\n";
161 $wait_const = false;
162
163 $icon->setType(ICON_TYPE_CONST);
164 FastPHPWriter::outputLeafNode($icon, $line, $desc);
165 $icon->reset();
166 }
167
168 if ((!$wait_abstract_func_list_end) && (count($levelAry) > 0) && (count($insideFuncAry) == 0) && ($token == T_VARIABLE)) {
169 $desc = "$value\n";
170
171 $icon->setType(ICON_TYPE_VAR);
172 FastPHPWriter::outputLeafNode($icon, $line, $desc);
173 $icon->reset();
174 }
175
176 if ($token == T_PRIVATE) $icon->setPrivate();
177 if ($token == T_PROTECTED) $icon->setProtected();
178 if ($token == T_PUBLIC) $icon->setPublic();
179 if ($token == T_ABSTRACT) $icon->setAbstract();
180 if ($token == T_FINAL) $icon->setFinal();
181 if ($token == T_STATIC) $icon->setStatic();
182
183 if (($data == ';') || ($data == '{') || ($data == '}')) {
184 $wait_abstract_func_list_end = false;
185 $icon->reset();
186 }
187
188 if ($token == T_FUNCTION) {
189 $wait_function = true;
190 }
191 if ($token == T_CLASS) {
192 $wait_class = true;
193 $dep = 0;
194 }
195 if ($token == T_INTERFACE) {
196 $wait_interface = true;
197 $dep = 0;
198 }
199 if ($token == T_TRAIT) {
200 $wait_trait = true;
201 $dep = 0;
202 }
203
204 if ($token == T_CONST) {
205 $wait_const = true;
206 }
207
208 if (($token == T_COMMENT) && self::isToDoDescription($value)) {
209 $comment_lines = explode("\n", trim($value));
210 foreach ($comment_lines as $line_no => $comment_line) {
211 if (self::isToDoDescription($comment_line)) {
212 // Because a To-Do-entry can stand everywhere (e.g. between a "private" and a "function" keyword)
213 // we shall not alter the $icon instance
214 $todoIcon = clone $icon;
215 $todoIcon->setType(ICON_TYPE_TODO);
216 FastPHPWriter::outputLeafNode($todoIcon, $line+$line_no, self::stripComment($comment_line));
217 unset($todoIcon);
218 }
219 }
220 }
221 }
222 }
223
224 private static function isToDoDescription($comment) {
225 return ((stripos($comment, 'TODO') !== false) ||
226 (stripos($comment, 'BUGBUG') !== false) ||
227 (stripos($comment, 'FIXME') !== false) ||
228 (stripos($comment, 'XXX') !== false));
229 }
230
231 private static function stripComment($x) {
232 $x = trim($x);
233 if (substr($x, 0, 1) == '#') return trim(substr($x, 1));
234 if (substr($x, 0, 2) == '//') return trim(substr($x, 2));
235 if (substr($x, 0, 2) == '/*') return trim(substr($x, 2, strlen($x)-4));
236 return $x;
237 }
238
239
240 private static final function array_peek($array) {
241 if (!isset($array[count($array)-1])) return null;
242 return $array[count($array)-1];
243 }
244 }
245
246 $parser = new MyFastPHPCodeExplorer($icon);
247 while (true) {
248 try {
249 $code = FastPHPReader::readCodeFromEditor();
250 } catch (FastPHPExitSignalReceivedException $e) {
251 die();
252 }
253 FastPHPWriter::outputHeader();
254 $parser->handle($code);
255 FastPHPWriter::outputExit();
256 FastPHPWriter::signalOutputEnd();
257 sleep(1);
258 }