Subversion Repositories fastphp

Rev

Rev 51 | Rev 55 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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