Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
MethodGenerator.php
001 <?php
002 /**
003 * Zend Framework (http://framework.zend.com/)
004 *
005 * @link http://github.com/zendframework/zf2 for the canonical source repository
006 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
007 * @license http://framework.zend.com/license/new-bsd New BSD License
008 */
009
010 namespace Zend\Code\Generator;
011
012 use ReflectionMethod;
013 use Zend\Code\Reflection\MethodReflection;
014
015 use function explode;
016 use function implode;
017 use function is_array;
018 use function is_string;
019 use function method_exists;
020 use function preg_replace;
021 use function sprintf;
022 use function str_replace;
023 use function strlen;
024 use function strtolower;
025 use function substr;
026 use function trim;
027
028 class MethodGenerator extends AbstractMemberGenerator
029 {
030 /**
031 * @var DocBlockGenerator
032 */
033 protected $docBlock;
034
035 /**
036 * @var ParameterGenerator[]
037 */
038 protected $parameters = [];
039
040 /**
041 * @var string
042 */
043 protected $body;
044
045 /**
046 * @var null|TypeGenerator
047 */
048 private $returnType;
049
050 /**
051 * @var bool
052 */
053 private $returnsReference = false;
054
055 /**
056 * @param MethodReflection $reflectionMethod
057 * @return MethodGenerator
058 */
059 public static function fromReflection(MethodReflection $reflectionMethod)
060 {
061 $method = static::copyMethodSignature($reflectionMethod);
062
063 $method->setSourceContent($reflectionMethod->getContents(false));
064 $method->setSourceDirty(false);
065
066 if ($reflectionMethod->getDocComment() != '') {
067 $method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock()));
068 }
069
070 $method->setBody(static::clearBodyIndention($reflectionMethod->getBody()));
071
072 return $method;
073 }
074
075 /**
076 * Returns a MethodGenerator based on a MethodReflection with only the signature copied.
077 *
078 * This is similar to fromReflection() but without the method body and phpdoc as this is quite heavy to copy.
079 * It's for example useful when creating proxies where you normally change the method body anyway.
080 */
081 public static function copyMethodSignature(MethodReflection $reflectionMethod): MethodGenerator
082 {
083 $method = new static();
084 $declaringClass = $reflectionMethod->getDeclaringClass();
085
086 $method->setReturnType(self::extractReturnTypeFromMethodReflection($reflectionMethod));
087 $method->setFinal($reflectionMethod->isFinal());
088
089 if ($reflectionMethod->isPrivate()) {
090 $method->setVisibility(self::VISIBILITY_PRIVATE);
091 } elseif ($reflectionMethod->isProtected()) {
092 $method->setVisibility(self::VISIBILITY_PROTECTED);
093 } else {
094 $method->setVisibility(self::VISIBILITY_PUBLIC);
095 }
096
097 $method->setInterface($declaringClass->isInterface());
098 $method->setStatic($reflectionMethod->isStatic());
099 $method->setReturnsReference($reflectionMethod->returnsReference());
100 $method->setName($reflectionMethod->getName());
101
102 foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
103 $method->setParameter(ParameterGenerator::fromReflection($reflectionParameter));
104 }
105
106 return $method;
107 }
108
109 /**
110 * Identify the space indention from the first line and remove this indention
111 * from all lines
112 *
113 * @param string $body
114 *
115 * @return string
116 */
117 protected static function clearBodyIndention($body)
118 {
119 if (empty($body)) {
120 return $body;
121 }
122
123 $lines = explode("\n", $body);
124
125 $indention = str_replace(trim($lines[1]), '', $lines[1]);
126
127 foreach ($lines as $key => $line) {
128 if (substr($line, 0, strlen($indention)) == $indention) {
129 $lines[$key] = substr($line, strlen($indention));
130 }
131 }
132
133 $body = implode("\n", $lines);
134
135 return $body;
136 }
137
138 /**
139 * Generate from array
140 *
141 * @configkey name string [required] Class Name
142 * @configkey docblock string The docblock information
143 * @configkey flags int Flags, one of MethodGenerator::FLAG_ABSTRACT MethodGenerator::FLAG_FINAL
144 * @configkey parameters string Class which this class is extending
145 * @configkey body string
146 * @configkey abstract bool
147 * @configkey final bool
148 * @configkey static bool
149 * @configkey visibility string
150 *
151 * @throws Exception\InvalidArgumentException
152 * @param array $array
153 * @return MethodGenerator
154 */
155 public static function fromArray(array $array)
156 {
157 if (! isset($array['name'])) {
158 throw new Exception\InvalidArgumentException(
159 'Method generator requires that a name is provided for this object'
160 );
161 }
162
163 $method = new static($array['name']);
164 foreach ($array as $name => $value) {
165 // normalize key
166 switch (strtolower(str_replace(['.', '-', '_'], '', $name))) {
167 case 'docblock':
168 $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value);
169 $method->setDocBlock($docBlock);
170 break;
171 case 'flags':
172 $method->setFlags($value);
173 break;
174 case 'parameters':
175 $method->setParameters($value);
176 break;
177 case 'body':
178 $method->setBody($value);
179 break;
180 case 'abstract':
181 $method->setAbstract($value);
182 break;
183 case 'final':
184 $method->setFinal($value);
185 break;
186 case 'interface':
187 $method->setInterface($value);
188 break;
189 case 'static':
190 $method->setStatic($value);
191 break;
192 case 'visibility':
193 $method->setVisibility($value);
194 break;
195 case 'returntype':
196 $method->setReturnType($value);
197 break;
198 }
199 }
200
201 return $method;
202 }
203
204 /**
205 * @param string $name
206 * @param array $parameters
207 * @param int $flags
208 * @param string $body
209 * @param DocBlockGenerator|string $docBlock
210 */
211 public function __construct(
212 $name = null,
213 array $parameters = [],
214 $flags = self::FLAG_PUBLIC,
215 $body = null,
216 $docBlock = null
217 ) {
218 if ($name) {
219 $this->setName($name);
220 }
221 if ($parameters) {
222 $this->setParameters($parameters);
223 }
224 if ($flags !== self::FLAG_PUBLIC) {
225 $this->setFlags($flags);
226 }
227 if ($body) {
228 $this->setBody($body);
229 }
230 if ($docBlock) {
231 $this->setDocBlock($docBlock);
232 }
233 }
234
235 /**
236 * @param array $parameters
237 * @return MethodGenerator
238 */
239 public function setParameters(array $parameters)
240 {
241 foreach ($parameters as $parameter) {
242 $this->setParameter($parameter);
243 }
244
245 return $this;
246 }
247
248 /**
249 * @param ParameterGenerator|array|string $parameter
250 * @throws Exception\InvalidArgumentException
251 * @return MethodGenerator
252 */
253 public function setParameter($parameter)
254 {
255 if (is_string($parameter)) {
256 $parameter = new ParameterGenerator($parameter);
257 }
258
259 if (is_array($parameter)) {
260 $parameter = ParameterGenerator::fromArray($parameter);
261 }
262
263 if (! $parameter instanceof ParameterGenerator) {
264 throw new Exception\InvalidArgumentException(sprintf(
265 '%s is expecting either a string, array or an instance of %s\ParameterGenerator',
266 __METHOD__,
267 __NAMESPACE__
268 ));
269 }
270
271 $this->parameters[$parameter->getName()] = $parameter;
272
273 return $this;
274 }
275
276 /**
277 * @return ParameterGenerator[]
278 */
279 public function getParameters()
280 {
281 return $this->parameters;
282 }
283
284 /**
285 * @param string $body
286 * @return MethodGenerator
287 */
288 public function setBody($body)
289 {
290 $this->body = $body;
291 return $this;
292 }
293
294 /**
295 * @return string
296 */
297 public function getBody()
298 {
299 return $this->body;
300 }
301
302 /**
303 * @param string|null $returnType
304 *
305 * @return MethodGenerator
306 */
307 public function setReturnType($returnType = null)
308 {
309 $this->returnType = null === $returnType
310 ? null
311 : TypeGenerator::fromTypeString($returnType);
312
313 return $this;
314 }
315
316 /**
317 * @return TypeGenerator|null
318 */
319 public function getReturnType()
320 {
321 return $this->returnType;
322 }
323
324 /**
325 * @param bool $returnsReference
326 *
327 * @return MethodGenerator
328 */
329 public function setReturnsReference($returnsReference)
330 {
331 $this->returnsReference = (bool) $returnsReference;
332
333 return $this;
334 }
335
336 /**
337 * @return string
338 */
339 public function generate()
340 {
341 $output = '';
342
343 $indent = $this->getIndentation();
344
345 if (($docBlock = $this->getDocBlock()) !== null) {
346 $docBlock->setIndentation($indent);
347 $output .= $docBlock->generate();
348 }
349
350 $output .= $indent;
351
352 if ($this->isAbstract()) {
353 $output .= 'abstract ';
354 } else {
355 $output .= $this->isFinal() ? 'final ' : '';
356 }
357
358 $output .= $this->getVisibility()
359 . ($this->isStatic() ? ' static' : '')
360 . ' function '
361 . ($this->returnsReference ? '& ' : '')
362 . $this->getName() . '(';
363
364 $parameters = $this->getParameters();
365 if (! empty($parameters)) {
366 foreach ($parameters as $parameter) {
367 $parameterOutput[] = $parameter->generate();
368 }
369
370 $output .= implode(', ', $parameterOutput);
371 }
372
373 $output .= ')';
374
375 if ($this->returnType) {
376 $output .= ' : ' . $this->returnType->generate();
377 }
378
379 if ($this->isAbstract()) {
380 return $output . ';';
381 }
382
383 if ($this->isInterface()) {
384 return $output . ';';
385 }
386
387 $output .= self::LINE_FEED . $indent . '{' . self::LINE_FEED;
388
389 if ($this->body) {
390 $output .= preg_replace('#^((?![a-zA-Z0-9_-]+;).+?)$#m', $indent . $indent . '$1', trim($this->body))
391 . self::LINE_FEED;
392 }
393
394 $output .= $indent . '}' . self::LINE_FEED;
395
396 return $output;
397 }
398
399 public function __toString()
400 {
401 return $this->generate();
402 }
403
404 /**
405 * @param MethodReflection $methodReflection
406 *
407 * @return null|string
408 */
409 private static function extractReturnTypeFromMethodReflection(MethodReflection $methodReflection)
410 {
411 $returnType = method_exists($methodReflection, 'getReturnType')
412 ? $methodReflection->getReturnType()
413 : null;
414
415 if (! $returnType) {
416 return null;
417 }
418
419 if (! method_exists($returnType, 'getName')) {
420 return self::expandLiteralType((string) $returnType, $methodReflection);
421 }
422
423 return ($returnType->allowsNull() ? '?' : '')
424 . self::expandLiteralType($returnType->getName(), $methodReflection);
425 }
426
427 /**
428 * @param string $literalReturnType
429 * @param ReflectionMethod $methodReflection
430 *
431 * @return string
432 */
433 private static function expandLiteralType($literalReturnType, ReflectionMethod $methodReflection)
434 {
435 if ('self' === strtolower($literalReturnType)) {
436 return $methodReflection->getDeclaringClass()->getName();
437 }
438
439 if ('parent' === strtolower($literalReturnType)) {
440 return $methodReflection->getDeclaringClass()->getParentClass()->getName();
441 }
442
443 return $literalReturnType;
444 }
445 }
446