Rev 41 | Rev 43 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
27 | daniel-mar | 1 | <?php |
2 | |||
36 | daniel-mar | 3 | // TODO: show full signature of each element? |
4 | |||
27 | daniel-mar | 5 | error_reporting(0); |
6 | |||
36 | daniel-mar | 7 | define('ICON_TYPE_FUNCTION', 'FUN'); |
8 | define('ICON_TYPE_CONSTRUCTOR', 'CST'); |
||
9 | define('ICON_TYPE_DESTRUCTOR', 'DST'); |
||
10 | define('ICON_TYPE_MAGICMETHOD', 'MAG'); |
||
11 | define('ICON_TYPE_CLASS', 'CLS'); |
||
12 | define('ICON_TYPE_TRAIT', 'TRA'); |
||
13 | define('ICON_TYPE_INTERFACE', 'INT'); |
||
14 | define('ICON_TYPE_VAR', 'VAR'); |
||
15 | define('ICON_TYPE_CONST', 'CON'); |
||
16 | define('ICON_TYPE_TODO', 'TDO'); |
||
17 | define('ICON_TYPE_ERROR', 'ERR'); |
||
33 | daniel-mar | 18 | |
27 | daniel-mar | 19 | while (true) { |
37 | daniel-mar | 20 | $code = FastNodeReader::readCodeFromEditor(); |
27 | daniel-mar | 21 | |
22 | $x = token_get_all($code); |
||
23 | $wait_function = false; |
||
24 | $wait_class = false; |
||
33 | daniel-mar | 25 | $wait_trait = false; |
26 | $wait_interface = false; |
||
27 | $wait_abstract_func_list_end = false; |
||
28 | $levelAry = array(); |
||
37 | daniel-mar | 29 | $icon = new FastPHPIcon(); |
27 | daniel-mar | 30 | $dep = 0; |
33 | daniel-mar | 31 | $insideFuncAry = array(); |
27 | daniel-mar | 32 | |
37 | daniel-mar | 33 | echo FastNodeWriter::outputHeader(); |
34 | |||
35 | if (!$x) { |
||
36 | $icon->setType(ICON_TYPE_ERROR); |
||
37 | echo FastNodeWriter::outputLeafNode($icon, 1, 'SYNTAX ERROR'); |
||
38 | } |
||
39 | |||
27 | daniel-mar | 40 | foreach ($x as $n => $data) { |
41 | if ($data == '{') $dep++; |
||
42 | if ($data == '}') { |
||
43 | $dep--; |
||
33 | daniel-mar | 44 | if ((count($levelAry) > 0) && (array_peek($levelAry) == $dep)) { |
45 | array_pop($levelAry); |
||
37 | daniel-mar | 46 | echo FastNodeWriter::outputDecreaseLevel(); |
29 | daniel-mar | 47 | } |
33 | daniel-mar | 48 | if ((count($insideFuncAry) > 0) && (array_peek($insideFuncAry) == $dep)) { |
49 | array_pop($insideFuncAry); |
||
50 | } |
||
27 | daniel-mar | 51 | } |
52 | |||
29 | daniel-mar | 53 | $token = (!is_array($data)) ? null : $data[0]; |
54 | $value = (!is_array($data)) ? null : $data[1]; |
||
33 | daniel-mar | 55 | $line = (!is_array($data)) ? null : $data[2]; |
27 | daniel-mar | 56 | |
57 | if ($wait_function && ($token == T_STRING)) { |
||
33 | daniel-mar | 58 | $wait_function = false; |
37 | daniel-mar | 59 | if ($icon->isAbstract()) { |
33 | daniel-mar | 60 | $desc = "abstract function $value()"; |
36 | daniel-mar | 61 | $wait_abstract_func_list_end = true; |
33 | daniel-mar | 62 | } else { |
63 | $desc = "function $value()"; |
||
36 | daniel-mar | 64 | $insideFuncAry[] = $dep; |
27 | daniel-mar | 65 | } |
29 | daniel-mar | 66 | |
67 | if ($value == '__construct') { // TODO: auch eine methode mit dem namen der klasse soll eine konstruktor sein |
||
37 | daniel-mar | 68 | $icon->setType(ICON_TYPE_CONSTRUCTOR); |
29 | daniel-mar | 69 | } else if ($value == '__destruct') { |
37 | daniel-mar | 70 | $icon->setType(ICON_TYPE_DESTRUCTOR); |
29 | daniel-mar | 71 | } else if (substr($value, 0, 2) == '__') { |
37 | daniel-mar | 72 | $icon->setType(ICON_TYPE_MAGICMETHOD); |
29 | daniel-mar | 73 | } else { |
37 | daniel-mar | 74 | $icon->setType(ICON_TYPE_FUNCTION); |
29 | daniel-mar | 75 | } |
37 | daniel-mar | 76 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
77 | $icon->reset(); |
||
27 | daniel-mar | 78 | } |
79 | |||
80 | if ($wait_class && ($token == T_STRING)) { |
||
37 | daniel-mar | 81 | if ($icon->isAbstract()) { |
82 | $desc = "Abstract Class $value\n"; |
||
36 | daniel-mar | 83 | } else { |
37 | daniel-mar | 84 | $desc = "Class $value\n"; |
36 | daniel-mar | 85 | } |
27 | daniel-mar | 86 | $wait_class = false; |
33 | daniel-mar | 87 | $levelAry[] = $dep; |
27 | daniel-mar | 88 | |
37 | daniel-mar | 89 | $icon->setType(ICON_TYPE_CLASS); |
90 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
||
91 | $icon->reset(); |
||
36 | daniel-mar | 92 | |
37 | daniel-mar | 93 | echo FastNodeWriter::outputIncreaseLevel(); |
27 | daniel-mar | 94 | } |
95 | |||
33 | daniel-mar | 96 | if ($wait_trait && ($token == T_STRING)) { |
97 | $desc = "Trait $value\n"; |
||
98 | $wait_trait = false; |
||
99 | $levelAry[] = $dep; |
||
100 | |||
37 | daniel-mar | 101 | $icon->setType(ICON_TYPE_TRAIT); |
102 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
||
103 | $icon->reset(); |
||
36 | daniel-mar | 104 | |
37 | daniel-mar | 105 | echo FastNodeWriter::outputIncreaseLevel(); |
33 | daniel-mar | 106 | } |
107 | |||
108 | if ($wait_interface && ($token == T_STRING)) { |
||
109 | $desc = "Interface $value\n"; |
||
110 | $wait_interface = false; |
||
111 | $levelAry[] = $dep; |
||
112 | |||
37 | daniel-mar | 113 | $icon->setType(ICON_TYPE_INTERFACE); |
114 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
||
115 | $icon->reset(); |
||
36 | daniel-mar | 116 | |
37 | daniel-mar | 117 | echo FastNodeWriter::outputIncreaseLevel(); |
33 | daniel-mar | 118 | } |
119 | |||
120 | if ($wait_const && ($token == T_STRING)) { |
||
121 | $desc = "const $value\n"; |
||
122 | $wait_const = false; |
||
123 | |||
37 | daniel-mar | 124 | $icon->setType(ICON_TYPE_CONST); |
125 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
||
126 | $icon->reset(); |
||
33 | daniel-mar | 127 | } |
128 | |||
129 | if ((!$wait_abstract_func_list_end) && (count($levelAry) > 0) && (count($insideFuncAry) == 0) && ($token == T_VARIABLE)) { |
||
130 | $desc = "$value\n"; |
||
131 | |||
37 | daniel-mar | 132 | $icon->setType(ICON_TYPE_VAR); |
133 | echo FastNodeWriter::outputLeafNode($icon, $line, $desc); |
||
134 | $icon->reset(); |
||
33 | daniel-mar | 135 | } |
136 | |||
37 | daniel-mar | 137 | if ($token == T_PRIVATE) $icon->setPrivate(); |
138 | if ($token == T_PROTECTED) $icon->setProtected(); |
||
139 | if ($token == T_PUBLIC) $icon->setPublic(); |
||
140 | if ($token == T_ABSTRACT) $icon->setAbstract(); |
||
141 | if ($token == T_FINAL) $icon->setFinal(); |
||
142 | if ($token == T_STATIC) $icon->setStatic(); |
||
27 | daniel-mar | 143 | |
33 | daniel-mar | 144 | if (($data == ';') || ($data == '{') || ($data == '}')) { |
145 | $wait_abstract_func_list_end = false; |
||
37 | daniel-mar | 146 | $icon->reset(); |
33 | daniel-mar | 147 | } |
148 | |||
27 | daniel-mar | 149 | if ($token == T_FUNCTION) { |
150 | $wait_function = true; |
||
151 | } |
||
152 | if ($token == T_CLASS) { |
||
153 | $wait_class = true; |
||
154 | $dep = 0; |
||
155 | } |
||
36 | daniel-mar | 156 | if ($token == T_INTERFACE) { |
157 | $wait_interface = true; |
||
158 | $dep = 0; |
||
159 | } |
||
33 | daniel-mar | 160 | if ($token == T_TRAIT) { |
161 | $wait_trait = true; |
||
162 | $dep = 0; |
||
163 | } |
||
27 | daniel-mar | 164 | |
33 | daniel-mar | 165 | if ($token == T_CONST) { |
166 | $wait_const = true; |
||
167 | } |
||
168 | |||
37 | daniel-mar | 169 | if (($token == T_COMMENT) && _isToDoDescription($value)) { |
170 | // Because a TO-DO-entry can stand everywhere (e.g. between a "private" and a "function") |
||
171 | // we shall not alter the $icon instance |
||
172 | $todoIcon = clone $icon; |
||
173 | $todoIcon->setType(ICON_TYPE_TODO); |
||
174 | echo FastNodeWriter::outputLeafNode($todoIcon, $line, strip_comment($value)); |
||
27 | daniel-mar | 175 | } |
176 | } |
||
177 | |||
37 | daniel-mar | 178 | echo FastNodeWriter::outputExit(); |
29 | daniel-mar | 179 | |
37 | daniel-mar | 180 | echo FastNodeWriter::signalOutputEnd(); |
27 | daniel-mar | 181 | |
182 | sleep(1); |
||
183 | } |
||
184 | |||
37 | daniel-mar | 185 | function _isToDoDescription($comment) { |
186 | return ((stripos($value, 'TODO') !== false) || |
||
187 | (stripos($value, 'BUGBUG') !== false) || |
||
188 | (stripos($value, 'FIXME') !== false) || |
||
189 | (stripos($value, 'XXX') !== false)); |
||
190 | } |
||
36 | daniel-mar | 191 | |
37 | daniel-mar | 192 | function _iconCodeToIndex(/* FastPHPIcon */ $icon) { |
38 | daniel-mar | 193 | if (($icon->getType() == ICON_TYPE_CLASS) && (!$icon->isAbstract())) return 0; // class |
194 | else if (($icon->getType() == ICON_TYPE_CLASS) && ( $icon->isAbstract())) return 1; // abstract class |
||
195 | else if (($icon->getType() == ICON_TYPE_INTERFACE) ) return 2; // interface |
||
196 | else if (($icon->getType() == ICON_TYPE_TRAIT) ) return 3; // trait |
||
197 | else if (($icon->getType() == ICON_TYPE_CONST) && ($icon->isPrivate()) ) return 4; // private const |
||
198 | else if (($icon->getType() == ICON_TYPE_VAR) && ($icon->isPrivate()) ) return 5; // private var |
||
199 | else if (($icon->isMethod()) && ($icon->isPrivate()) && (!$icon->isAbstract())) return 6; // private function |
||
200 | else if (($icon->isMethod()) && ($icon->isPrivate()) && ( $icon->isAbstract())) return 7; // private abstract function |
||
201 | else if (($icon->getType() == ICON_TYPE_CONST) && ($icon->isProtected()) ) return 8; // protected const |
||
202 | else if (($icon->getType() == ICON_TYPE_VAR) && ($icon->isProtected()) ) return 9; // protected var |
||
203 | else if (($icon->isMethod()) && ($icon->isProtected()) && (!$icon->isAbstract())) return 10; // protected function |
||
204 | else if (($icon->isMethod()) && ($icon->isProtected()) && ( $icon->isAbstract())) return 11; // protected abstract function |
||
205 | else if (($icon->getType() == ICON_TYPE_CONST) && ($icon->isPublic()) ) return 12; // public const |
||
206 | else if (($icon->getType() == ICON_TYPE_VAR) && ($icon->isPublic()) ) return 13; // public var |
||
207 | else if (($icon->isMethod()) && ($icon->isPublic()) && (!$icon->isAbstract())) return 14; // public function |
||
208 | else if (($icon->isMethod()) && ($icon->isPublic()) && ( $icon->isAbstract())) return 15; // public abstract function |
||
209 | else if (($icon->getType() == ICON_TYPE_TODO) ) return 16; // ToDo comment |
||
37 | daniel-mar | 210 | else return -1; |
211 | } |
||
36 | daniel-mar | 212 | |
37 | daniel-mar | 213 | class FastPHPIcon { |
214 | private $type; // ICON_TYPE_* |
||
215 | private $visibility; // 1=private, 2=protected, 3=public(default) |
||
216 | private $abstractFinal; // 'A', 'F', ''(default) |
||
217 | private $static; // true, false(default) |
||
218 | |||
219 | public function setType($type) { |
||
220 | $this->type = $type; |
||
36 | daniel-mar | 221 | } |
37 | daniel-mar | 222 | public function getType() { |
223 | return $this->type; |
||
224 | } |
||
36 | daniel-mar | 225 | |
37 | daniel-mar | 226 | public function setAbstract() { |
227 | $this->abstractFinal = 'A'; |
||
228 | } |
||
229 | public function isAbstract() { |
||
230 | return $this->abstractFinal == 'A'; |
||
231 | } |
||
36 | daniel-mar | 232 | |
37 | daniel-mar | 233 | public function setFinal() { |
234 | $this->abstractFinal = 'F'; |
||
235 | } |
||
236 | public function isFinal() { |
||
237 | return $this->abstractFinal == 'F'; |
||
238 | } |
||
27 | daniel-mar | 239 | |
37 | daniel-mar | 240 | public function setStatic() { |
241 | $this->static = true; |
||
242 | } |
||
243 | public function isStatic() { |
||
244 | return $this->static; |
||
245 | } |
||
246 | |||
247 | public function setPrivate() { |
||
248 | $this->visibility = 1; |
||
249 | } |
||
250 | public function isPrivate() { |
||
251 | return $this->visibility == 1; |
||
252 | } |
||
253 | |||
254 | public function setProtected() { |
||
255 | $this->visibility = 2; |
||
256 | } |
||
257 | public function isProtected() { |
||
258 | return $this->visibility == 2; |
||
259 | } |
||
260 | |||
261 | public function setPublic() { |
||
262 | $this->visibility = 3; |
||
263 | } |
||
264 | public function isPublic() { |
||
265 | return $this->visibility == 3; |
||
266 | } |
||
267 | |||
268 | public function isMethod() { |
||
269 | return (($this->type == ICON_TYPE_FUNCTION) || |
||
270 | ($this->type == ICON_TYPE_CONSTRUCTOR) || |
||
271 | ($this->type == ICON_TYPE_DESTRUCTOR) || |
||
272 | ($this->type == ICON_TYPE_MAGICMETHOD)); |
||
273 | } |
||
274 | |||
275 | public function reset() { |
||
276 | $this->type = null; |
||
277 | $this->visibility = 3; |
||
278 | $this->abstractFinal = ''; |
||
279 | $this->static = false; |
||
280 | } |
||
281 | |||
282 | public function __construct() { |
||
283 | $this->reset(); |
||
284 | } |
||
27 | daniel-mar | 285 | } |
286 | |||
37 | daniel-mar | 287 | class FastNodeReader { |
288 | public static function readCodeFromEditor() { |
||
289 | $lines = array(); |
||
290 | while ($f = fgets(STDIN)){ |
||
291 | if (trim($f) == chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8)) break; |
||
41 | daniel-mar | 292 | |
293 | // Signal to terminate the code explorer |
||
42 | daniel-mar | 294 | if (trim($f) == chr(8).chr(7).chr(6).chr(5).chr(4).chr(3).chr(2).chr(1)) { |
295 | die("\n".chr(8).chr(7).chr(6).chr(5).chr(4).chr(3).chr(2).chr(1)."\n"); |
||
296 | } |
||
41 | daniel-mar | 297 | |
37 | daniel-mar | 298 | $lines[] = $f; |
299 | } |
||
300 | return implode("", $lines); |
||
301 | } |
||
27 | daniel-mar | 302 | } |
303 | |||
37 | daniel-mar | 304 | class FastNodeWriter { |
305 | |||
306 | public static function outputLeafNode(/* FastPHPIcon */ $icon, $lineNo, $description) { |
||
307 | $imageindex = _iconCodeToIndex($icon); |
||
308 | return 'N'.($imageindex == -1 ? '____' : sprintf('%04s', $imageindex)). |
||
309 | sprintf('%08s', $lineNo). |
||
310 | sprintf('%04s', strlen(trim($description))). |
||
311 | trim($description). |
||
312 | "\n"; |
||
313 | } |
||
314 | |||
315 | public static function outputIncreaseLevel() { |
||
42 | daniel-mar | 316 | return "I\n"; |
37 | daniel-mar | 317 | } |
318 | |||
319 | public static function outputDecreaseLevel() { |
||
42 | daniel-mar | 320 | return "D\n"; |
37 | daniel-mar | 321 | } |
322 | |||
323 | public static function outputExit() { |
||
42 | daniel-mar | 324 | return "X\n"; |
37 | daniel-mar | 325 | } |
326 | |||
327 | public static function signalOutputEnd() { |
||
42 | daniel-mar | 328 | return "\n".chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8)."\n"; |
37 | daniel-mar | 329 | } |
330 | |||
331 | public static function outputHeader() { |
||
332 | return "FAST100!"; |
||
333 | } |
||
334 | |||
27 | daniel-mar | 335 | } |
336 | |||
337 | function array_peek($array) { |
||
338 | if (!isset($array[count($array)-1])) return null; |
||
339 | return $array[count($array)-1]; |
||
340 | } |
||
341 | |||
342 | function strip_comment($x) { |
||
29 | daniel-mar | 343 | if (substr($x, 0, 1) == '#') return trim(substr($x, 1)); |
27 | daniel-mar | 344 | if (substr($x, 0, 2) == '//') return trim(substr($x, 2)); |
345 | if (substr($x, 0, 2) == '/*') return trim(substr($x, 2, strlen($x)-4)); |
||
346 | } |
||
29 | daniel-mar | 347 |