Subversion Repositories fastphp

Rev

Rev 55 | Rev 74 | 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.                 $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. }
  259.