Rev 54 | Rev 70 | 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 | |||
43 | daniel-mar | 7 | require_once __DIR__ . '/codeexplorer_api.inc.php'; |
33 | daniel-mar | 8 | |
43 | daniel-mar | 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); |
||
27 | daniel-mar | 20 | |
43 | daniel-mar | 21 | class MyFastPHPIcon extends FastPHPIcon { |
27 | daniel-mar | 22 | |
43 | daniel-mar | 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 |
||
49 | daniel-mar | 40 | else if (($this->getType() == ICON_TYPE_TODO) ) return 16; // To-Do comment |
43 | daniel-mar | 41 | else return -1; |
42 | } |
||
37 | daniel-mar | 43 | |
43 | daniel-mar | 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)); |
||
37 | daniel-mar | 49 | } |
50 | |||
43 | daniel-mar | 51 | } |
27 | daniel-mar | 52 | |
43 | daniel-mar | 53 | class MyFastPHPCodeExplorer { |
27 | daniel-mar | 54 | |
43 | daniel-mar | 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(); |
||
29 | daniel-mar | 67 | |
43 | daniel-mar | 68 | if (!$token) { |
69 | $icon->setType(ICON_TYPE_ERROR); |
||
70 | FastPHPWriter::outputLeafNode($icon, 0, 'SYNTAX ERROR'); |
||
27 | daniel-mar | 71 | } |
72 | |||
43 | daniel-mar | 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 | } |
||
36 | daniel-mar | 84 | } |
27 | daniel-mar | 85 | |
43 | daniel-mar | 86 | $token = (!is_array($data)) ? null : $data[0]; |
87 | $value = (!is_array($data)) ? null : $data[1]; |
||
88 | $line = (!is_array($data)) ? null : $data[2]; |
||
36 | daniel-mar | 89 | |
46 | daniel-mar | 90 | if ($value == '${') $dep++; |
91 | |||
55 | daniel-mar | 92 | if ($wait_function && ($data == '{')) { |
93 | $wait_function = false; // Anonymous functions do not have a name |
||
94 | } |
||
95 | |||
43 | daniel-mar | 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 | } |
||
27 | daniel-mar | 105 | |
43 | daniel-mar | 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 | } |
||
33 | daniel-mar | 118 | |
43 | daniel-mar | 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; |
||
36 | daniel-mar | 127 | |
43 | daniel-mar | 128 | $icon->setType(ICON_TYPE_CLASS); |
129 | FastPHPWriter::outputLeafNode($icon, $line, $desc); |
||
130 | $icon->reset(); |
||
33 | daniel-mar | 131 | |
43 | daniel-mar | 132 | FastPHPWriter::outputIncreaseLevel(); |
133 | } |
||
33 | daniel-mar | 134 | |
43 | daniel-mar | 135 | if ($wait_trait && ($token == T_STRING)) { |
136 | $desc = "Trait $value\n"; |
||
137 | $wait_trait = false; |
||
138 | $levelAry[] = $dep; |
||
36 | daniel-mar | 139 | |
43 | daniel-mar | 140 | $icon->setType(ICON_TYPE_TRAIT); |
141 | FastPHPWriter::outputLeafNode($icon, $line, $desc); |
||
142 | $icon->reset(); |
||
33 | daniel-mar | 143 | |
43 | daniel-mar | 144 | FastPHPWriter::outputIncreaseLevel(); |
145 | } |
||
33 | daniel-mar | 146 | |
43 | daniel-mar | 147 | if ($wait_interface && ($token == T_STRING)) { |
148 | $desc = "Interface $value\n"; |
||
149 | $wait_interface = false; |
||
150 | $levelAry[] = $dep; |
||
33 | daniel-mar | 151 | |
43 | daniel-mar | 152 | $icon->setType(ICON_TYPE_INTERFACE); |
153 | FastPHPWriter::outputLeafNode($icon, $line, $desc); |
||
154 | $icon->reset(); |
||
33 | daniel-mar | 155 | |
43 | daniel-mar | 156 | FastPHPWriter::outputIncreaseLevel(); |
157 | } |
||
33 | daniel-mar | 158 | |
43 | daniel-mar | 159 | if ($wait_const && ($token == T_STRING)) { |
160 | $desc = "const $value\n"; |
||
161 | $wait_const = false; |
||
27 | daniel-mar | 162 | |
43 | daniel-mar | 163 | $icon->setType(ICON_TYPE_CONST); |
164 | FastPHPWriter::outputLeafNode($icon, $line, $desc); |
||
165 | $icon->reset(); |
||
166 | } |
||
33 | daniel-mar | 167 | |
43 | daniel-mar | 168 | if ((!$wait_abstract_func_list_end) && (count($levelAry) > 0) && (count($insideFuncAry) == 0) && ($token == T_VARIABLE)) { |
169 | $desc = "$value\n"; |
||
27 | daniel-mar | 170 | |
43 | daniel-mar | 171 | $icon->setType(ICON_TYPE_VAR); |
172 | FastPHPWriter::outputLeafNode($icon, $line, $desc); |
||
173 | $icon->reset(); |
||
174 | } |
||
33 | daniel-mar | 175 | |
43 | daniel-mar | 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(); |
||
29 | daniel-mar | 182 | |
43 | daniel-mar | 183 | if (($data == ';') || ($data == '{') || ($data == '}')) { |
184 | $wait_abstract_func_list_end = false; |
||
185 | $icon->reset(); |
||
186 | } |
||
27 | daniel-mar | 187 | |
43 | daniel-mar | 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 | } |
||
27 | daniel-mar | 203 | |
43 | daniel-mar | 204 | if ($token == T_CONST) { |
205 | $wait_const = true; |
||
206 | } |
||
36 | daniel-mar | 207 | |
43 | daniel-mar | 208 | if (($token == T_COMMENT) && self::isToDoDescription($value)) { |
51 | daniel-mar | 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 | } |
||
42 | daniel-mar | 220 | } |
37 | daniel-mar | 221 | } |
222 | } |
||
27 | daniel-mar | 223 | |
43 | daniel-mar | 224 | private static function isToDoDescription($comment) { |
48 | daniel-mar | 225 | return ((stripos($comment, 'TODO') !== false) || |
226 | (stripos($comment, 'BUGBUG') !== false) || |
||
227 | (stripos($comment, 'FIXME') !== false) || |
||
228 | (stripos($comment, 'XXX') !== false)); |
||
37 | daniel-mar | 229 | } |
230 | |||
43 | daniel-mar | 231 | private static function stripComment($x) { |
51 | daniel-mar | 232 | $x = trim($x); |
43 | daniel-mar | 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)); |
||
51 | daniel-mar | 236 | return $x; |
37 | daniel-mar | 237 | } |
238 | |||
239 | |||
43 | daniel-mar | 240 | private static final function array_peek($array) { |
241 | if (!isset($array[count($array)-1])) return null; |
||
242 | return $array[count($array)-1]; |
||
37 | daniel-mar | 243 | } |
43 | daniel-mar | 244 | } |
37 | daniel-mar | 245 | |
43 | daniel-mar | 246 | $parser = new MyFastPHPCodeExplorer($icon); |
247 | while (true) { |
||
248 | try { |
||
249 | $code = FastPHPReader::readCodeFromEditor(); |
||
250 | } catch (FastPHPExitSignalReceivedException $e) { |
||
251 | die(); |
||
37 | daniel-mar | 252 | } |
43 | daniel-mar | 253 | FastPHPWriter::outputHeader(); |
254 | $parser->handle($code); |
||
255 | FastPHPWriter::outputExit(); |
||
256 | FastPHPWriter::signalOutputEnd(); |
||
257 | sleep(1); |
||
27 | daniel-mar | 258 | } |