예제 #1
0
 /**
  * Extract method from position
  *
  * @param int $n
  * @param TokenCollection$tokens
  * @return ReflectedMethod
  * @throws \Exception
  */
 public function extract(&$n, TokenCollection $tokens)
 {
     $declaration = $this->searcher->getUnder(array(')'), $n, $tokens);
     if (!preg_match('!function\\s+(.*)\\(\\s*(.*)!is', $declaration, $matches)) {
         throw new \Exception(sprintf("Closure detected instead of method\nDetails:\n%s", $declaration));
     }
     list(, $name, $args) = $matches;
     $method = new ReflectedMethod($name);
     $arguments = preg_split('!\\s*,\\s*!m', $args);
     foreach ($arguments as $argDecl) {
         if (0 == strlen($argDecl)) {
             continue;
         }
         $elems = preg_split('!([\\s=]+)!', $argDecl);
         $isRequired = 2 == sizeof($elems, COUNT_NORMAL);
         if (sizeof($elems, COUNT_NORMAL) == 1) {
             list($name, $type) = array_pad($elems, 2, null);
         } else {
             if ('$' == $elems[0][0]) {
                 $name = $elems[0];
                 $type = null;
                 $isRequired = false;
             } else {
                 list($type, $name) = array_pad($elems, 2, null);
             }
         }
         $argument = new ReflectedArgument($name, $type, $isRequired);
         $method->pushArgument($argument);
     }
     //
     // Body
     $this->extractContent($method, $n, $tokens);
     // Tokens
     $end = $this->searcher->getPositionOfClosingBrace($n, $tokens);
     if ($end > 0) {
         $method->setTokens($tokens->extract($n, $end));
     }
     //
     // Dependencies
     $this->extractDependencies($method, $n, $tokens);
     // returns
     $this->extractReturns($method, $method->getContent());
     // usage
     $this->extractUsage($method);
     return $method;
 }