annotate vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php @ 19:fa3358dc1485 tip

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