| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | <?php/* Copyright (c) 2009 hamcrest.org *//** * Represents a single static factory method from a {@link Matcher} class. * * @todo Search method in file contents for func_get_args() to replace factoryVarArgs. */class FactoryMethod{    /**     * @var FactoryClass     */    private $class;    /**     * @var ReflectionMethod     */    private $reflector;    /**     * @var array of string     */    private $comment;    /**     * @var bool     */    private $isVarArgs;    /**     * @var array of FactoryCall     */    private $calls;    /**     * @var array FactoryParameter     */    private $parameters;    public function __construct(FactoryClass $class, ReflectionMethod $reflector)    {        $this->class = $class;        $this->reflector = $reflector;        $this->extractCommentWithoutLeadingShashesAndStars();        $this->extractFactoryNamesFromComment();        $this->extractParameters();    }    public function extractCommentWithoutLeadingShashesAndStars()    {        $this->comment = explode("\n", $this->reflector->getDocComment());        foreach ($this->comment as &$line) {            $line = preg_replace('#^\s*(/\\*+|\\*+/|\\*)\s?#', '', $line);        }        $this->trimLeadingBlankLinesFromComment();        $this->trimTrailingBlankLinesFromComment();    }    public function trimLeadingBlankLinesFromComment()    {        while (count($this->comment) > 0) {            $line = array_shift($this->comment);            if (trim($line) != '') {                array_unshift($this->comment, $line);                break;            }        }    }    public function trimTrailingBlankLinesFromComment()    {        while (count($this->comment) > 0) {            $line = array_pop($this->comment);            if (trim($line) != '') {                array_push($this->comment, $line);                break;            }        }    }    public function extractFactoryNamesFromComment()    {        $this->calls = array();        for ($i = 0; $i < count($this->comment); $i++) {            if ($this->extractFactoryNamesFromLine($this->comment[$i])) {                unset($this->comment[$i]);            }        }        $this->trimTrailingBlankLinesFromComment();    }    public function extractFactoryNamesFromLine($line)    {        if (preg_match('/^\s*@factory(\s+(.+))?$/', $line, $match)) {            $this->createCalls(                $this->extractFactoryNamesFromAnnotation(                    isset($match[2]) ? trim($match[2]) : null                )            );            return true;        }        return false;    }    public function extractFactoryNamesFromAnnotation($value)    {        $primaryName = $this->reflector->getName();        if (empty($value)) {            return array($primaryName);        }        preg_match_all('/(\.{3}|-|[a-zA-Z_][a-zA-Z_0-9]*)/', $value, $match);        $names = $match[0];        if (in_array('...', $names)) {            $this->isVarArgs = true;        }        if (!in_array('-', $names) && !in_array($primaryName, $names)) {            array_unshift($names, $primaryName);        }        return $names;    }    public function createCalls(array $names)    {        $names = array_unique($names);        foreach ($names as $name) {            if ($name != '-' && $name != '...') {                $this->calls[] = new FactoryCall($this, $name);            }        }    }    public function extractParameters()    {        $this->parameters = array();        if (!$this->isVarArgs) {            foreach ($this->reflector->getParameters() as $parameter) {                $this->parameters[] = new FactoryParameter($this, $parameter);            }        }    }    public function getParameterDeclarations()    {        if ($this->isVarArgs || !$this->hasParameters()) {            return '';        }        $params = array();        foreach ($this->parameters as /** @var $parameter FactoryParameter */                 $parameter) {            $params[] = $parameter->getDeclaration();        }        return implode(', ', $params);    }    public function getParameterInvocations()    {        if ($this->isVarArgs) {            return '';        }        $params = array();        foreach ($this->parameters as $parameter) {            $params[] = $parameter->getInvocation();        }        return implode(', ', $params);    }    public function getClass()    {        return $this->class;    }    public function getClassName()    {        return $this->class->getName();    }    public function getName()    {        return $this->reflector->name;    }    public function isFactory()    {        return count($this->calls) > 0;    }    public function getCalls()    {        return $this->calls;    }    public function acceptsVariableArguments()    {        return $this->isVarArgs;    }    public function hasParameters()    {        return !empty($this->parameters);    }    public function getParameters()    {        return $this->parameters;    }    public function getFullName()    {        return $this->getClassName() . '::' . $this->getName();    }    public function getCommentText()    {        return implode("\n", $this->comment);    }    public function getComment($indent = '')    {        $comment = $indent . '/**';        foreach ($this->comment as $line) {            $comment .= "\n" . rtrim($indent . ' * ' . $line);        }        $comment .= "\n" . $indent . ' */';        return $comment;    }}
 |