Example #1
0
 public function scan()
 {
     require_once $this->path;
     $ns = "";
     $_ns = "";
     $ns_bracket = false;
     $aliases = [];
     $tokens = new Tokenizer(FS::get($this->path));
     while ($tokens->valid()) {
         if ($tokens->is(T_NAMESPACE)) {
             $ns = "";
             $_ns = "";
             $tokens->next();
             if ($tokens->is(T_STRING)) {
                 $ns = $this->_parseName($tokens);
                 if ($tokens->is('{')) {
                     $tokens->skip();
                     $ns_bracket = true;
                 } else {
                     $tokens->skipIf(';');
                 }
                 $_ns = $ns . '\\';
             } elseif ($tokens->is('{')) {
                 $ns_bracket = true;
                 $tokens->next();
             }
         } elseif ($tokens->is(T_USE)) {
             do {
                 $tokens->next();
                 $name = $this->_parseName($tokens);
                 if ($tokens->is(T_AS)) {
                     $aliases[$tokens->next()->get(T_STRING)] = $name;
                     $tokens->next();
                 } else {
                     if (strpos($name, '\\') === false) {
                         $aliases[$name] = $name;
                     } else {
                         $aliases[ltrim('\\', strrchr($name, '\\'))] = $name;
                     }
                 }
             } while ($tokens->is(','));
             $tokens->need(';')->next();
         } elseif ($tokens->is(T_CONST)) {
             $name = $tokens->next()->get(T_STRING);
             $constant = new EntityConstant($_ns . $name);
             $constant->setValue(constant($_ns . $name));
             $constant->setLine($this->line($tokens->getLine()));
             $this->constants[$_ns . $name] = $constant;
             $tokens->forwardTo(';')->next();
         } elseif ($tokens->is(T_FUNCTION)) {
             $name = $tokens->next()->get(T_STRING);
             $function = new EntityFunction($_ns . $name);
             $function->setLine($this->line($tokens->getLine()));
             $function->setAliases($aliases);
             $this->parseCallable($function, new \ReflectionFunction($function->name));
             $function->setBody($tokens->forwardTo('{')->getScope());
             $tokens->next();
             $this->functions[$function->name] = $function;
         } elseif ($tokens->is(T_FINAL, T_ABSTRACT, T_INTERFACE, T_TRAIT, T_CLASS)) {
             $tokens->forwardTo(T_STRING);
             $name = $tokens->current();
             $class = new EntityClass($_ns . $name);
             $ref = new \ReflectionClass($class->name);
             $doc = $ref->getDocComment();
             //                if($name == "NamesInterface") {
             //                    drop($ref);
             //                }
             if ($ref->isInterface()) {
                 $class->addFlag(Flags::IS_INTERFACE);
             } elseif ($ref->isTrait()) {
                 $class->addFlag(Flags::IS_TRAIT);
             } else {
                 $class->addFlag(Flags::IS_CLASS);
             }
             if ($ref->isAbstract()) {
                 $class->addFlag(Flags::IS_ABSTRACT);
             } elseif ($ref->isFinal()) {
                 $class->addFlag(Flags::IS_FINAL);
             }
             if ($doc) {
                 $info = ToolKit::parseDoc($doc);
                 $class->setDescription($info['desc']);
                 $class->addOptions($info['options']);
             }
             $class->setAliases($aliases);
             $class->setLine($this->line($tokens->getLine()));
             $tokens->next();
             if ($tokens->is(T_EXTENDS)) {
                 // process 'extends' keyword
                 do {
                     $tokens->next();
                     $root = $tokens->is(T_NS_SEPARATOR);
                     $parent = $this->_parseName($tokens);
                     if ($root) {
                         // extends from root namespace
                         $class->setParent($parent, $class->isInterface());
                     } elseif (isset($aliases[$parent])) {
                         $class->setParent($aliases[$parent], $class->isInterface());
                     } else {
                         $class->setParent($_ns . $parent, $class->isInterface());
                     }
                 } while ($tokens->is(','));
             }
             if ($tokens->is(T_IMPLEMENTS)) {
                 // process 'implements' keyword
                 do {
                     $tokens->next();
                     $root = $tokens->is(T_NS_SEPARATOR);
                     $parent = $this->_parseName($tokens);
                     if ($root) {
                         // extends from root namespace
                         $class->addInterface($parent);
                     } elseif (isset($aliases[$parent])) {
                         $class->addInterface($aliases[$parent]);
                     } else {
                         $class->addInterface($_ns . $parent);
                     }
                 } while ($tokens->is(','));
             }
             $tokens->forwardTo('{')->next();
             while ($tokens->forwardTo(T_CONST, T_FUNCTION, '{', '}', T_VARIABLE) && $tokens->valid()) {
                 switch ($tokens->key()) {
                     case T_CONST:
                         $constant = new EntityConstant($class->name . '::' . $tokens->next()->get(T_STRING));
                         $constant->setValue(constant($constant->name));
                         $constant->setLine(new Line($this, $tokens->getLine()));
                         $class->addConstant($constant);
                         break;
                     case T_VARIABLE:
                         $property = new EntityProperty(ltrim($tokens->getAndNext(), '$'));
                         $ref = new \ReflectionProperty($class->name, $property->name);
                         $doc = $ref->getDocComment();
                         if ($doc) {
                             $property->setDescription(ToolKit::parseDoc($doc)['desc']);
                         }
                         if ($ref->isPrivate()) {
                             $property->addFlag(Flags::IS_PRIVATE);
                         } elseif ($ref->isProtected()) {
                             $property->addFlag(Flags::IS_PROTECTED);
                         } else {
                             $property->addFlag(Flags::IS_PUBLIC);
                         }
                         if ($ref->isStatic()) {
                             $property->addFlag(Flags::IS_STATIC);
                         }
                         if ($ref->isDefault()) {
                             $property->setValue($ref->getDeclaringClass()->getDefaultProperties()[$property->name]);
                         }
                         $class->addProperty($property);
                         break;
                     case T_FUNCTION:
                         $method = new EntityMethod($name . '::' . $tokens->next()->get(T_STRING));
                         $method->setLine($this->line($tokens->getLine()));
                         $this->parseCallable($method, $ref = new \ReflectionMethod($class->name, $method->short));
                         if ($ref->isPrivate()) {
                             $method->addFlag(Flags::IS_PRIVATE);
                         } elseif ($ref->isProtected()) {
                             $method->addFlag(Flags::IS_PROTECTED);
                         } else {
                             $method->addFlag(Flags::IS_PUBLIC);
                         }
                         if ($ref->isStatic()) {
                             $method->addFlag(Flags::IS_STATIC);
                         }
                         if ($ref->isAbstract()) {
                             $method->addFlag(Flags::IS_ABSTRACT);
                             $method->addFlag(Flags::IS_ABSTRACT_IMPLICIT);
                         } elseif ($ref->isFinal()) {
                             $method->addFlag(Flags::IS_FINAL);
                         }
                         if (isset($method->options['deprecated'])) {
                             $method->addFlag(Flags::IS_DEPRECATED);
                         }
                         $tokens->forwardTo(')')->next();
                         if ($tokens->is('{')) {
                             $method_body = $tokens->getScope();
                             $method->setBody($method_body);
                         }
                         $tokens->next();
                         $class->addMethod($method);
                         break;
                     case '{':
                         // use traits scope
                         $tokens->forwardTo('}')->next();
                         break;
                     case '}':
                         // end of class
                         $tokens->next();
                         $this->classes[$class->name] = $class;
                         break 2;
                 }
             }
         } elseif ($tokens->is('}') && $ns_bracket) {
             $tokens->next();
             $ns_bracket = false;
         } else {
             drop($tokens->curr);
             if ($tokens->valid()) {
                 throw new UnexpectedTokenException($tokens);
             }
             break;
         }
     }
 }
Example #2
0
 /**
  * Add method
  * @param EntityMethod $method
  * @return EntityMethod
  */
 public function addMethod(EntityMethod $method)
 {
     return $this->methods[$method->name] = $method->setClass($this);
 }