Subversion Repositories fastphp

Rev

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