/** * @param Project $project * @return \string[] */ public function analyze(Project $project) { $graph = $this->objectGraph; /** @var ParsedClass[] $classesMissingMethod */ $classesMissingMethods = new Map(function ($key) { if ($key instanceof ParsedClass) { return; } throw new MapException('Only keys of type Class_ are accepted'); }, function ($value) { if (is_array($value)) { return; } throw new MapException('Only values of type array are accepted'); }); # scan all objects (we're actually only interested in classes) foreach ($graph->getObjects() as $object) { if ($object instanceof ParsedClass) { foreach ($object->getMethods() as $method) { # and see if they've abstract methods if ($method->getMethod()->isAbstract()) { $methodName = $method->getNormalizedName(); # now find all descendant classes and see if they've implemented it $classesMissingMethod = $this->findSubtypeUntilMethodMatchesRecursive($methodName, $this->helper->findExtends($object)); # in case we found ones, store them for reporting later # note: we may find other methods in the same class later too foreach ($classesMissingMethod as $classMissingMethod) { $methods = []; if ($classesMissingMethods->exists($classMissingMethod)) { $methods = $classesMissingMethods->get($classMissingMethod); } $methods[] = $method; $classesMissingMethods->set($classMissingMethod, $methods); } } } } } /** @var ParsedClass $class */ foreach ($classesMissingMethods->keys() as $class) { $project->addReport(new AbstractMissingReport($class, $classesMissingMethods->get($class))); } }
/** * @param Project $project * @return \string[] */ public function analyze(Project $project) { $graph = $this->objectGraph; /** @var ParsedClass[] $classesMissingMethod */ $classesMissingMethods = new Map(function ($key) { if ($key instanceof ParsedClass) { return; } throw new MapException('Only keys of type Class_ are accepted'); }, function ($value) { if (is_array($value)) { return; } throw new MapException('Only values of type array are accepted'); }); # scan all objects (we're actually only interested in interfaces) foreach ($graph->getObjects() as $object) { if ($object instanceof ParsedInterface) { foreach ($object->getMethods() as $method) { # now find all classes and class from interfaces extending this # interface $classesMissingMethod = $this->findSubtypeUntilMethodMatchesRecursive($method, $this->helper->findImplements($object)); # in case we found ones, store them for reporting later # note: we may find other methods in the same class later too foreach ($classesMissingMethod as $classMissingMethod) { $methods = []; if ($classesMissingMethods->exists($classMissingMethod)) { $methods = $classesMissingMethods->get($classMissingMethod); } $methods[] = $method; $classesMissingMethods->set($classMissingMethod, $methods); } } } } /** @var ParsedClass $class */ foreach ($classesMissingMethods->keys() as $class) { $project->addReport(new InterfaceMissingReport($class, $classesMissingMethods->get($class))); } }