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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

MethodGenerator.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 12.01 KiB


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