Subversion Repositories fastphp

Rev

Rev 41 | Rev 43 | 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. 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');
  18.  
  19. while (true) {
  20.         $code = FastNodeReader::readCodeFromEditor();
  21.  
  22.         $x = token_get_all($code);
  23.         $wait_function = false;
  24.         $wait_class = false;
  25.         $wait_trait = false;
  26.         $wait_interface = false;
  27.         $wait_abstract_func_list_end = false;
  28.         $levelAry = array();
  29.         $icon = new FastPHPIcon();
  30.         $dep = 0;
  31.         $insideFuncAry = array();
  32.  
  33.         echo FastNodeWriter::outputHeader();
  34.  
  35.         if (!$x) {
  36.                 $icon->setType(ICON_TYPE_ERROR);
  37.                 echo FastNodeWriter::outputLeafNode($icon, 1, 'SYNTAX ERROR');
  38.         }
  39.  
  40.         foreach ($x as $n => $data) {
  41.                 if ($data == '{') $dep++;
  42.                 if ($data == '}') {
  43.                         $dep--;
  44.                         if ((count($levelAry) > 0) && (array_peek($levelAry) == $dep)) {
  45.                                 array_pop($levelAry);
  46.                                 echo FastNodeWriter::outputDecreaseLevel();
  47.                         }
  48.                         if ((count($insideFuncAry) > 0) && (array_peek($insideFuncAry) == $dep)) {
  49.                                 array_pop($insideFuncAry);
  50.                         }
  51.                 }
  52.  
  53.                 $token = (!is_array($data)) ? null : $data[0];
  54.                 $value = (!is_array($data)) ? null : $data[1];
  55.                 $line  = (!is_array($data)) ? null : $data[2];
  56.  
  57.                 if ($wait_function && ($token == T_STRING)) {
  58.                         $wait_function = false;
  59.                         if ($icon->isAbstract()) {
  60.                                 $desc = "abstract function $value()";
  61.                                 $wait_abstract_func_list_end = true;
  62.                         } else {
  63.                                 $desc = "function $value()";
  64.                                 $insideFuncAry[] = $dep;
  65.                         }
  66.  
  67.                         if ($value == '__construct') { // TODO: auch eine methode mit dem namen der klasse soll eine konstruktor sein
  68.                                 $icon->setType(ICON_TYPE_CONSTRUCTOR);
  69.                         } else if ($value == '__destruct') {
  70.                                 $icon->setType(ICON_TYPE_DESTRUCTOR);
  71.                         } else if (substr($value, 0, 2) == '__') {
  72.                                 $icon->setType(ICON_TYPE_MAGICMETHOD);
  73.                         } else {
  74.                                 $icon->setType(ICON_TYPE_FUNCTION);
  75.                         }
  76.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  77.                         $icon->reset();
  78.                 }
  79.  
  80.                 if ($wait_class && ($token == T_STRING)) {
  81.                         if ($icon->isAbstract()) {
  82.                                 $desc = "Abstract Class $value\n";
  83.                         } else {
  84.                                 $desc = "Class $value\n";
  85.                         }
  86.                         $wait_class = false;
  87.                         $levelAry[] = $dep;
  88.  
  89.                         $icon->setType(ICON_TYPE_CLASS);
  90.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  91.                         $icon->reset();
  92.  
  93.                         echo FastNodeWriter::outputIncreaseLevel();
  94.                 }
  95.  
  96.                 if ($wait_trait && ($token == T_STRING)) {
  97.                         $desc = "Trait $value\n";
  98.                         $wait_trait = false;
  99.                         $levelAry[] = $dep;
  100.  
  101.                         $icon->setType(ICON_TYPE_TRAIT);
  102.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  103.                         $icon->reset();
  104.  
  105.                         echo FastNodeWriter::outputIncreaseLevel();
  106.                 }
  107.  
  108.                 if ($wait_interface && ($token == T_STRING)) {
  109.                         $desc = "Interface $value\n";
  110.                         $wait_interface = false;
  111.                         $levelAry[] = $dep;
  112.  
  113.                         $icon->setType(ICON_TYPE_INTERFACE);
  114.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  115.                         $icon->reset();
  116.  
  117.                         echo FastNodeWriter::outputIncreaseLevel();
  118.                 }
  119.  
  120.                 if ($wait_const && ($token == T_STRING)) {
  121.                         $desc = "const $value\n";
  122.                         $wait_const = false;
  123.  
  124.                         $icon->setType(ICON_TYPE_CONST);
  125.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  126.                         $icon->reset();
  127.                 }
  128.  
  129.                 if ((!$wait_abstract_func_list_end) && (count($levelAry) > 0) && (count($insideFuncAry) == 0) && ($token == T_VARIABLE)) {
  130.                         $desc = "$value\n";
  131.  
  132.                         $icon->setType(ICON_TYPE_VAR);
  133.                         echo FastNodeWriter::outputLeafNode($icon, $line, $desc);
  134.                         $icon->reset();
  135.                 }
  136.  
  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();
  143.  
  144.                 if (($data == ';') || ($data == '{') || ($data == '}')) {
  145.                         $wait_abstract_func_list_end = false;
  146.                         $icon->reset();
  147.                 }
  148.  
  149.                 if ($token == T_FUNCTION) {
  150.                         $wait_function = true;
  151.                 }
  152.                 if ($token == T_CLASS) {
  153.                         $wait_class = true;
  154.                         $dep = 0;
  155.                 }
  156.                 if ($token == T_INTERFACE) {
  157.                         $wait_interface = true;
  158.                         $dep = 0;
  159.                 }
  160.                 if ($token == T_TRAIT) {
  161.                         $wait_trait = true;
  162.                         $dep = 0;
  163.                 }
  164.  
  165.                 if ($token == T_CONST) {
  166.                         $wait_const = true;
  167.                 }
  168.  
  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));
  175.                 }
  176.         }
  177.        
  178.         echo FastNodeWriter::outputExit();
  179.  
  180.         echo FastNodeWriter::signalOutputEnd();
  181.  
  182.         sleep(1);
  183. }
  184.  
  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. }
  191.  
  192. function _iconCodeToIndex(/* FastPHPIcon */ $icon) {
  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
  210.         else                                                                                                    return -1;
  211. }
  212.  
  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;
  221.         }
  222.         public function getType() {
  223.                 return $this->type;
  224.         }
  225.  
  226.         public function setAbstract() {
  227.                 $this->abstractFinal = 'A';
  228.         }
  229.         public function isAbstract() {
  230.                 return $this->abstractFinal == 'A';
  231.         }
  232.  
  233.         public function setFinal() {
  234.                 $this->abstractFinal = 'F';
  235.         }
  236.         public function isFinal() {
  237.                 return $this->abstractFinal == 'F';
  238.         }
  239.  
  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.         }
  285. }
  286.  
  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;
  292.  
  293.                         // Signal to terminate the code explorer
  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.                         }
  297.  
  298.                         $lines[] = $f;
  299.                 }
  300.                 return implode("", $lines);
  301.         }
  302. }
  303.  
  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() {
  316.                 return "I\n";
  317.         }
  318.  
  319.         public static function outputDecreaseLevel() {
  320.                 return "D\n";
  321.         }
  322.  
  323.         public static function outputExit() {
  324.                 return "X\n";
  325.         }
  326.  
  327.         public static function signalOutputEnd() {
  328.                 return "\n".chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8)."\n";
  329.         }
  330.  
  331.         public static function outputHeader() {
  332.                 return "FAST100!";
  333.         }
  334.  
  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) {
  343.         if (substr($x, 0, 1) == '#') return trim(substr($x, 1));
  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. }
  347.  
  348.