Exemplo n.º 1
0
    /**
     * Parses the method definition (@method), and extract
     *
     * This should ideally all be extracted to a dedicated parser component. There is
     * no point in keeping this hidden away in here.
     *
     * @param string $def
     *
     * @return null|Method
     */
    private function parseCommentMethodDef($def)
    {
        // We use some half-assed regular expression, and hope that it will work out.
        // To bad that there is no well defined structure, and also no well written
        // parser :-(
        if (!preg_match('/
                # Syntax: [return type] [name]([type] [parameter], [...]) [<description>]
                # Possible Type Name
                (?:([^\\s]+)\\s+)?

                # Method Name (must be followed by "()")
                ([^\\s(]+)

                # Arguments
                \\(([^)]*)\\)

                /xs', $def, $match)) {
            $this->logger->warning(sprintf('Could not parse @method tag "%s".', $def));
            return null;
        }
        list(, $typeName, $methodName, $arguments) = $match;
        $method = new Method($methodName);
        if (!empty($typeName) && null !== ($returnType = $this->commentParser->tryGettingType($typeName))) {
            $method->setReturnType($returnType);
        }
        $arguments = trim($arguments);
        if (empty($arguments)) {
            return $method;
        }
        foreach (explode(',', $arguments) as $i => $argument) {
            if (!preg_match('/(?:([^\\s]+)\\s+)?\\$?([^\\s,]+)/', $argument, $match)) {
                $this->logger->warning(sprintf('Could not parse argument "%s" of @method "%s"; skipping all further arguments.', $argument, $method->getName()));
                break;
            }
            $parameter = new \Scrutinizer\PhpAnalyzer\Model\MethodParameter($match[2], $i);
            if (!empty($match[1]) && null !== ($paramType = $this->commentParser->tryGettingType($match[1]))) {
                $parameter->setPhpType($paramType);
            }
            $method->addParameter($parameter);
        }
        return $method;
    }
 /**
  * @group foreach
  */
 public function testForeach3()
 {
     $this->registry->registerClass($foo = new Clazz('Foo'));
     $foo->setTypeRegistry($this->registry);
     $foo->addImplementedInterface('Iterator');
     $foo->addMethod($current = new Method('current'));
     $current->setReturnType($this->registry->getClassOrCreate('Bar'));
     $this->assuming('y', 'object<Foo>');
     $this->inMethod('$x = $i = null; foreach ($y as $i => $x);');
     $this->verify('x', $this->createNullableType('object<Bar>'));
     $this->verify('i', $this->createNullableType('integer|string'));
 }