Пример #1
0
 /**
  * Parses PHP file.
  * @param  string
  * @return array [class => [prop => comment (or 'use' => [alias => class])]
  */
 public static function parsePhp($code)
 {
     if (XApp_Utils_Strings::match($code, '#//nette' . 'loader=(\\S*)#')) {
         return;
         // TODO: allways ignore?
     }
     $tokens = @token_get_all($code);
     $namespace = $class = $classLevel = $level = $docComment = NULL;
     $res = $uses = array();
     while (list($key, $token) = each($tokens)) {
         switch (is_array($token) ? $token[0] : $token) {
             case T_DOC_COMMENT:
                 $docComment = $token[1];
                 break;
             case T_NAMESPACE:
                 $namespace = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)) . '\\';
                 $uses = array();
                 break;
             case T_CLASS:
             case T_INTERFACE:
             case PHP_VERSION_ID < 50400 ? -1 : T_TRAIT:
                 if ($name = self::fetch($tokens, T_STRING)) {
                     $class = $namespace . $name;
                     $classLevel = $level + 1;
                     if ($docComment) {
                         $res[$class]['class'] = $docComment;
                     }
                     if ($uses) {
                         $res[$class]['use'] = $uses;
                     }
                 }
                 break;
             case T_FUNCTION:
                 self::fetch($tokens, '&');
                 if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_STRING))) {
                     $res[$class][$name] = $docComment;
                 }
                 break;
             case T_VAR:
             case T_PUBLIC:
             case T_PROTECTED:
                 self::fetch($tokens, T_STATIC);
                 if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_VARIABLE))) {
                     $res[$class][$name] = $docComment;
                 }
                 break;
             case T_USE:
                 while (!$class && ($name = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)))) {
                     if (self::fetch($tokens, T_AS)) {
                         $uses[self::fetch($tokens, T_STRING)] = ltrim($name, '\\');
                     } else {
                         $tmp = explode('\\', $name);
                         $uses[end($tmp)] = $name;
                     }
                     if (!self::fetch($tokens, ',')) {
                         break;
                     }
                 }
                 break;
             case T_CURLY_OPEN:
             case T_DOLLAR_OPEN_CURLY_BRACES:
             case '{':
                 $level++;
                 break;
             case '}':
                 if ($level === $classLevel) {
                     $class = $classLevel = NULL;
                 }
                 $level--;
                 // break omitted
             // break omitted
             case ';':
                 $docComment = NULL;
         }
     }
     return $res;
 }