[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |