Pull merge.
[yaffs-website] / vendor / phpspec / prophecy / src / Prophecy / Doubler / ClassPatch / TraversablePatch.php
1 <?php
2
3 /*
4  * This file is part of the Prophecy.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *     Marcello Duarte <marcello.duarte@gmail.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Prophecy\Doubler\ClassPatch;
13
14 use Prophecy\Doubler\Generator\Node\ClassNode;
15 use Prophecy\Doubler\Generator\Node\MethodNode;
16
17 /**
18  * Traversable interface patch.
19  * Forces classes that implement interfaces, that extend Traversable to also implement Iterator.
20  *
21  * @author Konstantin Kudryashov <ever.zet@gmail.com>
22  */
23 class TraversablePatch implements ClassPatchInterface
24 {
25     /**
26      * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate.
27      *
28      * @param ClassNode $node
29      *
30      * @return bool
31      */
32     public function supports(ClassNode $node)
33     {
34         if (in_array('Iterator', $node->getInterfaces())) {
35             return false;
36         }
37         if (in_array('IteratorAggregate', $node->getInterfaces())) {
38             return false;
39         }
40
41         foreach ($node->getInterfaces() as $interface) {
42             if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) {
43                 continue;
44             }
45             if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) {
46                 continue;
47             }
48             if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) {
49                 continue;
50             }
51
52             return true;
53         }
54
55         return false;
56     }
57
58     /**
59      * Forces class to implement Iterator interface.
60      *
61      * @param ClassNode $node
62      */
63     public function apply(ClassNode $node)
64     {
65         $node->addInterface('Iterator');
66
67         $node->addMethod(new MethodNode('current'));
68         $node->addMethod(new MethodNode('key'));
69         $node->addMethod(new MethodNode('next'));
70         $node->addMethod(new MethodNode('rewind'));
71         $node->addMethod(new MethodNode('valid'));
72     }
73
74     /**
75      * Returns patch priority, which determines when patch will be applied.
76      *
77      * @return int Priority number (higher - earlier)
78      */
79     public function getPriority()
80     {
81         return 100;
82     }
83 }