[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Generator/ -> MethodGenerator.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Generator;
  11  
  12  use ReflectionMethod;
  13  use Zend\Code\Reflection\MethodReflection;
  14  
  15  use function explode;
  16  use function implode;
  17  use function is_array;
  18  use function is_string;
  19  use function method_exists;
  20  use function preg_replace;
  21  use function sprintf;
  22  use function str_replace;
  23  use function strlen;
  24  use function strtolower;
  25  use function substr;
  26  use function trim;
  27  
  28  class MethodGenerator extends AbstractMemberGenerator
  29  {
  30      /**
  31       * @var DocBlockGenerator
  32       */
  33      protected $docBlock;
  34  
  35      /**
  36       * @var ParameterGenerator[]
  37       */
  38      protected $parameters = [];
  39  
  40      /**
  41       * @var string
  42       */
  43      protected $body;
  44  
  45      /**
  46       * @var null|TypeGenerator
  47       */
  48      private $returnType;
  49  
  50      /**
  51       * @var bool
  52       */
  53      private $returnsReference = false;
  54  
  55      /**
  56       * @param  MethodReflection $reflectionMethod
  57       * @return MethodGenerator
  58       */
  59      public static function fromReflection(MethodReflection $reflectionMethod)
  60      {
  61          $method = static::copyMethodSignature($reflectionMethod);
  62  
  63          $method->setSourceContent($reflectionMethod->getContents(false));
  64          $method->setSourceDirty(false);
  65  
  66          if ($reflectionMethod->getDocComment() != '') {
  67              $method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock()));
  68          }
  69  
  70          $method->setBody(static::clearBodyIndention($reflectionMethod->getBody()));
  71  
  72          return $method;
  73      }
  74  
  75      /**
  76       * Returns a MethodGenerator based on a MethodReflection with only the signature copied.
  77       *
  78       * This is similar to fromReflection() but without the method body and phpdoc as this is quite heavy to copy.
  79       * It's for example useful when creating proxies where you normally change the method body anyway.
  80       */
  81      public static function copyMethodSignature(MethodReflection $reflectionMethod): MethodGenerator
  82      {
  83          $method         = new static();
  84          $declaringClass = $reflectionMethod->getDeclaringClass();
  85  
  86          $method->setReturnType(self::extractReturnTypeFromMethodReflection($reflectionMethod));
  87          $method->setFinal($reflectionMethod->isFinal());
  88  
  89          if ($reflectionMethod->isPrivate()) {
  90              $method->setVisibility(self::VISIBILITY_PRIVATE);
  91          } elseif ($reflectionMethod->isProtected()) {
  92              $method->setVisibility(self::VISIBILITY_PROTECTED);
  93          } else {
  94              $method->setVisibility(self::VISIBILITY_PUBLIC);
  95          }
  96  
  97          $method->setInterface($declaringClass->isInterface());
  98          $method->setStatic($reflectionMethod->isStatic());
  99          $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  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1