/** * Resolve AbstractFactory * * @param ResolvedClass $resolved */ public function resolve(ResolvedClass $resolved) { $class = $resolved->getClass(); $pattern = new AbstractFactory($class->getFullname()); $resolver = new TypeResolver(); // we don't look private and non static methods $collection = (new Collection($class->getMethods()))->where(sprintf('method => method.getVisibility() == "public" and method.getState() == %s', ReflectedMethod::STATE_STATIC)); if (empty($collection)) { return; } /** @var ReflectedMethod $method */ foreach ($collection as $method) { // method instanciates at least one object $instanciated = array_unique($method->getInstanciedClasses()); if (empty($instanciated)) { continue; } foreach ($method->getReturns() as $return) { // returns an object if ($resolver->isNative($return->getType())) { continue; } // doesn't return itself (avoid singleton) if (in_array($return->getType(), array('\\self', '\\static', $class->getFullname()))) { continue; } $pattern->setCreated($return->getType()); $resolved->pushPattern($pattern); return; } } }
/** * @return array */ public function getDependencies() { // on read : compare with aliases. We cannot make it in pushDependency() => aliases aren't yet known $dependencies = array(); foreach ($this->dependencies as $name) { array_push($dependencies, $this->nameResolver->resolve($name, null)); } // returned values $resolver = new TypeResolver(); foreach ($this->returns as $return) { $name = $return->getType(); if (!$resolver->isNative($name)) { array_push($dependencies, $this->nameResolver->resolve($name, null)); } } // anonymous classes in method (inner class) foreach ($this->anonymousClasses as $c) { array_push($dependencies, $c->getParent()); $dependencies = array_merge($dependencies, $c->getDependencies()); } return array_unique($dependencies); }
/** * Extracts content of method * * @param ReflectedMethod $method * @param integer $n * @param TokenCollection $tokens * @param ReflectedClass $currentClass * @return $this */ private function extractDependencies(ReflectedMethod $method, $n, TokenCollection $tokens, ReflectedClass $currentClass = null) { // // Object creation $extractor = new CallExtractor($this->searcher, $currentClass); $start = $n; $len = sizeof($tokens, COUNT_NORMAL); for ($i = $start; $i < $len; $i++) { $token = $tokens[$i]; switch ($token->getType()) { case T_PAAMAYIM_NEKUDOTAYIM: case T_NEW: $call = $extractor->extract($i, $tokens, $currentClass); if ($call !== 'class') { // anonymous class $method->pushDependency($call); $method->pushInstanciedClass($call); } break; } } // // Parameters in Method API $resolver = new TypeResolver(); foreach ($method->getArguments() as $argument) { $name = $argument->getType(); if (strlen($name) > 0 && !$resolver->isNative($name)) { $method->pushDependency($name); } } return $this; }