3 namespace Prophecy\Doubler\ClassPatch;
5 use Prophecy\Doubler\Generator\Node\ClassNode;
6 use Prophecy\Exception\Doubler\ClassCreatorException;
8 class ThrowablePatch implements ClassPatchInterface
11 * Checks if patch supports specific class node.
13 * @param ClassNode $node
16 public function supports(ClassNode $node)
18 return $this->implementsAThrowableInterface($node) && $this->doesNotExtendAThrowableClass($node);
22 * @param ClassNode $node
25 private function implementsAThrowableInterface(ClassNode $node)
27 foreach ($node->getInterfaces() as $type) {
28 if (is_a($type, 'Throwable', true)) {
37 * @param ClassNode $node
40 private function doesNotExtendAThrowableClass(ClassNode $node)
42 return !is_a($node->getParentClass(), 'Throwable', true);
46 * Applies patch to the specific class node.
48 * @param ClassNode $node
52 public function apply(ClassNode $node)
54 $this->checkItCanBeDoubled($node);
55 $this->setParentClassToException($node);
58 private function checkItCanBeDoubled(ClassNode $node)
60 $className = $node->getParentClass();
61 if ($className !== 'stdClass') {
62 throw new ClassCreatorException(
64 'Cannot double concrete class %s as well as implement Traversable',
72 private function setParentClassToException(ClassNode $node)
74 $node->setParentClass('Exception');
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');
87 * Returns patch priority, which determines when patch will be applied.
89 * @return int Priority number (higher - earlier)
91 public function getPriority()