4 * This file is part of the Prophecy.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6 * Marcello Duarte <marcello.duarte@gmail.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Prophecy\Doubler\ClassPatch;
14 use Prophecy\Doubler\Generator\Node\ClassNode;
15 use Prophecy\Doubler\Generator\Node\MethodNode;
16 use Prophecy\PhpDocumentor\ClassAndInterfaceTagRetriever;
17 use Prophecy\PhpDocumentor\MethodTagRetrieverInterface;
20 * Discover Magical API using "@method" PHPDoc format.
22 * @author Thomas Tourlourat <thomas@tourlourat.com>
23 * @author Kévin Dunglas <dunglas@gmail.com>
24 * @author Théo FIDRY <theo.fidry@gmail.com>
26 class MagicCallPatch implements ClassPatchInterface
28 private $tagRetriever;
30 public function __construct(MethodTagRetrieverInterface $tagRetriever = null)
32 $this->tagRetriever = null === $tagRetriever ? new ClassAndInterfaceTagRetriever() : $tagRetriever;
38 * @param ClassNode $node
42 public function supports(ClassNode $node)
48 * Discover Magical API
50 * @param ClassNode $node
52 public function apply(ClassNode $node)
54 $types = array_filter($node->getInterfaces(), function ($interface) {
55 return 0 !== strpos($interface, 'Prophecy\\');
57 $types[] = $node->getParentClass();
59 foreach ($types as $type) {
60 $reflectionClass = new \ReflectionClass($type);
62 while ($reflectionClass) {
63 $tagList = $this->tagRetriever->getTagList($reflectionClass);
65 foreach ($tagList as $tag) {
66 $methodName = $tag->getMethodName();
68 if (empty($methodName)) {
72 if (!$reflectionClass->hasMethod($methodName)) {
73 $methodNode = new MethodNode($methodName);
74 $methodNode->setStatic($tag->isStatic());
75 $node->addMethod($methodNode);
79 $reflectionClass = $reflectionClass->getParentClass();
85 * Returns patch priority, which determines when patch will be applied.
87 * @return integer Priority number (higher - earlier)
89 public function getPriority()