Pull merge.
[yaffs-website] / vendor / phpspec / prophecy / src / Prophecy / Doubler / ClassPatch / ThrowablePatch.php
1 <?php
2
3 namespace Prophecy\Doubler\ClassPatch;
4
5 use Prophecy\Doubler\Generator\Node\ClassNode;
6 use Prophecy\Exception\Doubler\ClassCreatorException;
7
8 class ThrowablePatch implements ClassPatchInterface
9 {
10     /**
11      * Checks if patch supports specific class node.
12      *
13      * @param ClassNode $node
14      * @return bool
15      */
16     public function supports(ClassNode $node)
17     {
18         return $this->implementsAThrowableInterface($node) && $this->doesNotExtendAThrowableClass($node);
19     }
20
21     /**
22      * @param ClassNode $node
23      * @return bool
24      */
25     private function implementsAThrowableInterface(ClassNode $node)
26     {
27         foreach ($node->getInterfaces() as $type) {
28             if (is_a($type, 'Throwable', true)) {
29                 return true;
30             }
31         }
32
33         return false;
34     }
35
36     /**
37      * @param ClassNode $node
38      * @return bool
39      */
40     private function doesNotExtendAThrowableClass(ClassNode $node)
41     {
42         return !is_a($node->getParentClass(), 'Throwable', true);
43     }
44
45     /**
46      * Applies patch to the specific class node.
47      *
48      * @param ClassNode $node
49      *
50      * @return void
51      */
52     public function apply(ClassNode $node)
53     {
54         $this->checkItCanBeDoubled($node);
55         $this->setParentClassToException($node);
56     }
57
58     private function checkItCanBeDoubled(ClassNode $node)
59     {
60         $className = $node->getParentClass();
61         if ($className !== 'stdClass') {
62             throw new ClassCreatorException(
63                 sprintf(
64                     'Cannot double concrete class %s as well as implement Traversable',
65                     $className
66                 ),
67                 $node
68             );
69         }
70     }
71
72     private function setParentClassToException(ClassNode $node)
73     {
74         $node->setParentClass('Exception');
75
76         $node->removeMethod('getMessage');
77         $node->removeMethod('getCode');
78         $node->removeMethod('getFile');
79         $node->removeMethod('getLine');
80         $node->removeMethod('getTrace');
81         $node->removeMethod('getPrevious');
82         $node->removeMethod('getNext');
83         $node->removeMethod('getTraceAsString');
84     }
85
86     /**
87      * Returns patch priority, which determines when patch will be applied.
88      *
89      * @return int Priority number (higher - earlier)
90      */
91     public function getPriority()
92     {
93         return 100;
94     }
95 }