/** * Extract infos from file * * @param $filename * @return Result */ public function extract($filename) { $result = new Result(); $tokens = $this->tokenizer->tokenize($filename); $nameResolver = new NameResolver(); // default current values $class = $interface = $function = $method = null; // $mapOfAliases = array(); $len = sizeof($tokens, COUNT_NORMAL); for ($n = 0; $n < $len; $n++) { $token = $tokens[$n]; switch ($token->getType()) { case T_USE: $alias = $this->extractors->alias->extract($n, $tokens); if (null !== $alias->name && null !== $alias->alias) { $nameResolver->pushAlias($alias); } break; case T_NAMESPACE: $namespace = '\\' . $this->searcher->getFollowingName($n, $tokens); $this->extractors->class->setNamespace($namespace); $this->extractors->interface->setNamespace($namespace); break; case T_INTERFACE: $class = $this->extractors->interface->extract($n, $tokens); $class->setNameResolver($nameResolver); // push class AND in global AND in local class map $this->result->pushClass($class); $result->pushClass($class); break; case T_EXTENDS: $i = $n; $parent = $this->searcher->getFollowingName($i, $tokens); $class->setParent(trim($parent)); break; case T_CLASS: $class = $this->extractors->class->extract($n, $tokens); $class->setNameResolver($nameResolver); // push class AND in global AND in local class map $this->result->pushClass($class); $result->pushClass($class); break; case T_FUNCTION: if ($class) { // avoid closure $next = $tokens[$n + 1]; if (T_WHITESPACE != $next->getType()) { continue; } $method = $this->extractors->method->extract($n, $tokens); $method->setNameResolver($nameResolver); $class->pushMethod($method); } break; } } return $result; }
/** * Extract class from position * * @param $n * @param TokenCollection $tokens * @return ReflectedClass */ public function extract(&$n, TokenCollection $tokens) { // is abstract ? $prev = $this->searcher->getPrevious($n, $tokens); $isAbstract = $prev && T_ABSTRACT === $prev->getType(); $classname = $this->searcher->getFollowingName($n, $tokens); $class = new ReflectedClass($this->namespace, trim($classname)); $class->setAbstract($isAbstract); return $class; }
/** * Extract dependency from call * * @param $n * @param TokenCollection $tokens * @return string * @throws \LogicException */ public function extract(&$n, TokenCollection $tokens) { $token = $tokens[$n]; switch ($token->getType()) { case T_PAAMAYIM_NEKUDOTAYIM: $prev = $n - 1; return $this->searcher->getUnder(array('::'), $prev, $tokens); break; case T_NEW: return $this->searcher->getFollowingName($n, $tokens); break; } throw new \LogicException('Classname of call not found'); }
/** * Extract class from position * * @param $n * @param TokenCollection $tokens * @return ReflectedClass */ public function extract(&$n, TokenCollection $tokens) { // is PHP7 ? $previous = $tokens->get($n - 2); if ($previous && T_NEW === $previous->getType()) { // anonymous class $class = new ReflectedAnonymousClass($this->namespace, 'class@anonymous'); return $class; } // is abstract ? $prev = $this->searcher->getPrevious($n, $tokens); $isAbstract = $prev && T_ABSTRACT === $prev->getType(); $classname = $this->searcher->getFollowingName($n, $tokens); $class = new ReflectedClass($this->namespace, trim($classname)); $class->setAbstract($isAbstract); return $class; }
/** * Extract dependency from call * * @param $n * @param TokenCollection $tokens * @return string * @throws \LogicException */ public function extract(&$n, TokenCollection $tokens) { $token = $tokens[$n]; switch ($token->getType()) { case T_PAAMAYIM_NEKUDOTAYIM: $prev = $n - 1; $value = $this->searcher->getUnder(array('::'), $prev, $tokens); if ($value === 'parent') { $extendPosition = $this->searcher->getExtendPostition($tokens); $parentName = $this->searcher->getFollowingName($extendPosition, $tokens); return $parentName; } if ($value === 'self' || $value === 'static') { $extendPosition = $this->searcher->getClassNamePosition($tokens); $className = $this->searcher->getFollowingName($extendPosition, $tokens); return $className; } return $value; case T_NEW: return $this->searcher->getFollowingName($n, $tokens); } throw new \LogicException('Classname of call not found'); }
/** * Extract dependency from call * * @param $n * @param TokenCollection $tokens * @return string * @throws \LogicException */ public function extract(&$n, TokenCollection $tokens) { $token = $tokens[$n]; $call = null; switch ($token->getType()) { case T_PAAMAYIM_NEKUDOTAYIM: $prev = $n - 1; $value = $this->searcher->getUnder(array('::'), $prev, $tokens); switch (true) { case $value == 'parent' && $this->currentClass: return $this->currentClass->getParent(); case $value == 'parent': // we try to get the name of the parent class $extendPosition = $this->searcher->getExtendPosition($tokens, $n); return $this->searcher->getFollowingName($extendPosition, $tokens); case ($value == 'static' || $value === 'self') && $this->currentClass: return $this->currentClass->getFullname(); case $value == 'static' || $value === 'self': $extendPosition = $this->searcher->getClassNamePosition($tokens); return $this->searcher->getFollowingName($extendPosition, $tokens); default: return $value; } case T_NEW: $call = $this->searcher->getFollowingName($n, $tokens); if (preg_match('!^(\\w+)!', $call, $matches)) { // fixes PHP 5.4: (new MyClass)->foo() $call = $matches[1]; } break; } if (null === $call) { throw new \LogicException('Classname of call not found'); } return $call; }
/** * Extract infos from file * * @param TokenCollection $tokens * @return Result */ public function extract($tokens) { $result = new Result(); $nameResolver = new NameResolver(); // default current values $class = $interface = $function = $namespace = $method = null; $len = sizeof($tokens, COUNT_NORMAL); $endAnonymous = 0; $mainContextClass = null; // class containing a anonymous class for ($n = 0; $n < $len; $n++) { if ($mainContextClass && $n > $endAnonymous) { // anonymous class is finished. We back to parent class // methods will be added to the main class now $class = $mainContextClass; $mainContextClass = null; } $token = $tokens[$n]; switch ($token->getType()) { case T_USE: $alias = $this->extractors->alias->extract($n, $tokens); if (null !== $alias->name && null !== $alias->alias) { $nameResolver->pushAlias($alias); } break; case T_NAMESPACE: $namespace = '\\' . $this->searcher->getFollowingName($n, $tokens); $this->extractors->class->setNamespace($namespace); $this->extractors->interface->setNamespace($namespace); break; case T_INTERFACE: $class = $this->extractors->interface->extract($n, $tokens); $class->setNameResolver($nameResolver); // push class AND in global AND in local class map $this->result->pushClass($class); $result->pushClass($class); break; case T_EXTENDS: $i = $n; $parent = $this->searcher->getFollowingName($i, $tokens); $class->setParent(trim($parent)); break; case T_IMPLEMENTS: $i = $n + 1; $contracts = $this->searcher->getUnder(array('{'), $i, $tokens); $contracts = explode(',', $contracts); $contracts = array_map('trim', $contracts); $class->setInterfaces($contracts); break; case T_CLASS: $i = $n; // avoid MyClass::class syntax if ($this->searcher->isPrecededBy(T_DOUBLE_COLON, $i, $tokens, 1)) { continue; } $c = $this->extractors->class->extract($n, $tokens); $c->setNameResolver($nameResolver); // push class AND in global AND in local class map $this->result->pushClass($c); $result->pushClass($c); // PHP 7 and inner classes if ($c instanceof ReflectedAnonymousClass) { // avoid to consider anonymous class as main class $p = $n; $endAnonymous = $this->searcher->getPositionOfClosingBrace($p, $tokens); $mainContextClass = $class; // add anonymous class in method if ($method) { $method->pushAnonymousClass($c); } } $class = $c; break; case T_FUNCTION: if ($class) { // avoid closure $next = $tokens[$n + 1]; if (T_WHITESPACE != $next->getType()) { continue; } $method = $this->extractors->method->extract($n, $tokens, $class); $method->setNamespace($namespace); $class->pushMethod($method); } break; } } return $result; }
/** * Extract class from position * * @param $n * @param TokenCollection $tokens * @return ReflectedInterface */ public function extract(&$n, TokenCollection $tokens) { $classname = $this->searcher->getFollowingName($n, $tokens); return new ReflectedInterface($this->namespace, trim($classname)); }