Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / Transformation / Transformation / ReturnTypeTransformation.php
1 <?php
2
3 /*
4  * This file is part of the Behat.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Behat\Transformation\Transformation;
12
13 use Behat\Behat\Definition\Call\DefinitionCall;
14 use Behat\Behat\Transformation\Call\TransformationCall;
15 use Behat\Behat\Transformation\SimpleArgumentTransformation;
16 use Behat\Testwork\Call\CallCenter;
17 use Behat\Testwork\Call\RuntimeCallee;
18 use Closure;
19 use ReflectionFunctionAbstract;
20 use ReflectionMethod;
21 use ReflectionParameter;
22
23 /**
24  * By-type object transformation.
25  *
26  * @author Konstantin Kudryashov <ever.zet@gmail.com>
27  */
28 final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgumentTransformation
29 {
30
31     /**
32      * {@inheritdoc}
33      */
34     static public function supportsPatternAndMethod($pattern, ReflectionMethod $method)
35     {
36         $returnClass = self::getReturnClass($method);
37
38         if (null === $returnClass) {
39             return false;
40         }
41
42         return '' === $pattern;
43     }
44
45     /**
46      * Initializes transformation.
47      *
48      * @param string      $pattern
49      * @param callable    $callable
50      * @param null|string $description
51      */
52     public function __construct($pattern, $callable, $description = null)
53     {
54         parent::__construct($callable, $description);
55     }
56
57     /**
58      * {@inheritdoc}
59      */
60     public function supportsDefinitionAndArgument(DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
61     {
62         $returnClass = self::getReturnClass($this->getReflection());
63
64         if (null === $returnClass) {
65             return false;
66         }
67
68         $parameterClass = $this->getParameterClassNameByIndex($definitionCall, $argumentIndex);
69
70         return $parameterClass === $returnClass;
71     }
72
73     /**
74      * {@inheritdoc}
75      */
76     public function transformArgument(CallCenter $callCenter, DefinitionCall $definitionCall, $argumentIndex, $argumentValue)
77     {
78         $call = new TransformationCall(
79             $definitionCall->getEnvironment(),
80             $definitionCall->getCallee(),
81             $this,
82             array($argumentValue)
83         );
84
85         $result = $callCenter->makeCall($call);
86
87         if ($result->hasException()) {
88             throw $result->getException();
89         }
90
91         return $result->getReturn();
92     }
93
94     /**
95      * {@inheritdoc}
96      */
97     public function getPriority()
98     {
99         return 80;
100     }
101
102     /**
103      * {@inheritdoc}
104      */
105     public function getPattern()
106     {
107         return null;
108     }
109
110     /**
111      * {@inheritdoc}
112      */
113     public function __toString()
114     {
115         return 'ReturnTypeTransform';
116     }
117
118     /**
119      * Extracts parameters from provided definition call.
120      *
121      * @param ReflectionFunctionAbstract $reflection
122      *
123      * @return null|string
124      */
125     static private function getReturnClass(ReflectionFunctionAbstract $reflection)
126     {
127         $type = $reflection->getReturnType();
128
129         if (null === $type || $type->isBuiltin()) {
130             return null;
131         }
132
133         return (string) $type;
134     }
135
136     /**
137      * Attempts to get definition parameter using its index (parameter position or name).
138      *
139      * @param DefinitionCall $definitionCall
140      * @param string|integer $argumentIndex
141      *
142      * @return null|string
143      */
144     private function getParameterClassNameByIndex(DefinitionCall $definitionCall, $argumentIndex)
145     {
146         $parameters = array_filter(
147             array_filter($this->getCallParameters($definitionCall),
148                 $this->hasIndex($argumentIndex)
149             ),
150             $this->isClass()
151         );
152         return count($parameters) ? current($parameters)->getClass()->getName() : null;
153     }
154
155     /**
156      * Extracts parameters from provided definition call.
157      *
158      * @param DefinitionCall $definitionCall
159      *
160      * @return ReflectionParameter[]
161      */
162     private function getCallParameters(DefinitionCall $definitionCall)
163     {
164         return $definitionCall->getCallee()->getReflection()->getParameters();
165     }
166
167     /**
168      * Returns appropriate closure for filtering parameter by index.
169      *
170      * @param string|integer $index
171      *
172      * @return Closure
173      */
174     private function hasIndex($index)
175     {
176         return is_string($index) ? $this->hasName($index) : $this->hasPosition($index);
177     }
178
179     /**
180      * Returns closure to filter parameter by name.
181      *
182      * @param string $index
183      *
184      * @return Closure
185      */
186     private function hasName($index)
187     {
188         return function (ReflectionParameter $parameter) use ($index) {
189             return $index === $parameter->getName();
190         };
191     }
192
193     /**
194      * Returns closure to filter parameter by position.
195      *
196      * @param integer $index
197      *
198      * @return Closure
199      */
200     private function hasPosition($index)
201     {
202         return function (ReflectionParameter $parameter) use ($index) {
203             return $index === $parameter->getPosition();
204         };
205     }
206
207     /**
208      * Returns closure to filter parameter by typehinted class.
209      *
210      * @return Closure
211      */
212     private function isClass()
213     {
214         return function (ReflectionParameter $parameter) {
215             return $parameter->getClass();
216         };
217     }
218 }