Code Coverage  | 
      ||||||||||
Lines  | 
       Functions and Methods  | 
       Classes and Traits  | 
      ||||||||
| Total |         | 
       98.53%  | 
       67 / 68  | 
               | 
       0.00%  | 
       0 / 1  | 
       CRAP |         | 
       0.00%  | 
       0 / 1  | 
      
| MethodReflection |         | 
       98.53%  | 
       67 / 68  | 
               | 
       0.00%  | 
       0 / 1  | 
       35 |         | 
       0.00%  | 
       0 / 1  | 
      
| parse |         | 
       98.53%  | 
       67 / 68  | 
               | 
       0.00%  | 
       0 / 1  | 
       35 | |||
| 1 | <?php | 
| 2 | /** | 
| 3 | * Pop PHP Framework (https://www.popphp.org/) | 
| 4 | * | 
| 5 | * @link https://github.com/popphp/popphp-framework | 
| 6 | * @author Nick Sagona, III <dev@noladev.com> | 
| 7 | * @copyright Copyright (c) 2009-2026 NOLA Interactive, LLC. | 
| 8 | * @license https://www.popphp.org/license New BSD License | 
| 9 | */ | 
| 10 | |
| 11 | /** | 
| 12 | * @namespace | 
| 13 | */ | 
| 14 | namespace Pop\Code\Reflection; | 
| 15 | |
| 16 | use Pop\Code\Generator; | 
| 17 | |
| 18 | /** | 
| 19 | * Method reflection code class | 
| 20 | * | 
| 21 | * @category Pop | 
| 22 | * @package Pop\Code | 
| 23 | * @author Nick Sagona, III <dev@noladev.com> | 
| 24 | * @copyright Copyright (c) 2009-2026 NOLA Interactive, LLC. | 
| 25 | * @license https://www.popphp.org/license New BSD License | 
| 26 | * @version 5.0.5 | 
| 27 | */ | 
| 28 | class MethodReflection extends AbstractReflection | 
| 29 | { | 
| 30 | |
| 31 | /** | 
| 32 | * Method to parse a method | 
| 33 | * | 
| 34 | * @param mixed $code | 
| 35 | * @param ?string $name | 
| 36 | * @return Generator\MethodGenerator | 
| 37 | */ | 
| 38 | public static function parse(mixed $code, ?string $name = null): Generator\MethodGenerator | 
| 39 | { | 
| 40 | if ($code->isProtected()) { | 
| 41 | $visibility = 'protected'; | 
| 42 | } else if ($code->isPrivate()) { | 
| 43 | $visibility = 'private'; | 
| 44 | } else { | 
| 45 | $visibility = 'public'; | 
| 46 | } | 
| 47 | |
| 48 | $docblock = null; | 
| 49 | $doc = $code->getDocComment(); | 
| 50 | if (($doc !== null) && (str_contains($doc, '/*'))) { | 
| 51 | $docblock = DocblockReflection::parse($doc); | 
| 52 | $docblock->setIndent(4); | 
| 53 | } | 
| 54 | |
| 55 | $method = new Generator\MethodGenerator($code->getName(), $visibility, $code->isStatic()); | 
| 56 | if ($docblock !== null) { | 
| 57 | $method->setDocblock($docblock); | 
| 58 | } | 
| 59 | |
| 60 | if ($code->isAbstract()) { | 
| 61 | $method->setAsAbstract(true); | 
| 62 | } else if ($code->isFinal()) { | 
| 63 | $method->setAsFinal(true); | 
| 64 | } | 
| 65 | |
| 66 | $reflectionParams = $code->getParameters(); | 
| 67 | |
| 68 | foreach ($reflectionParams as $key => $reflectionParam) { | 
| 69 | $paramName = $reflectionParam->getName(); | 
| 70 | $paramType = $reflectionParam->getType(); | 
| 71 | $paramType = (!empty($paramType) && ($paramType instanceof \ReflectionType) && | 
| 72 | method_exists($paramType, 'getName')) ? $paramType->getName() : null; | 
| 73 | |
| 74 | try { | 
| 75 | $paramValue = $reflectionParam->getDefaultValue(); | 
| 76 | } catch (\ReflectionException $e) { | 
| 77 | $paramValue = null; | 
| 78 | } | 
| 79 | |
| 80 | $method->addArgument($paramName, $paramValue, $paramType); | 
| 81 | } | 
| 82 | |
| 83 | // Parse the body if available | 
| 84 | $file = $code->getFileName(); | 
| 85 | |
| 86 | if (!empty($file) && file_exists($file)) { | 
| 87 | $lines = file($file); | 
| 88 | $startLine = $code->getStartLine() - 1; | 
| 89 | $endLine = $code->getEndLine() - 1; | 
| 90 | $length = $endLine - $startLine; | 
| 91 | $body = null; | 
| 92 | |
| 93 | if (($length > 0) && isset($lines[$startLine]) && isset($lines[$endLine])) { | 
| 94 | $lines = array_slice($lines, ($startLine + 1), $length); | 
| 95 | |
| 96 | if (preg_match('/[ ]+\}/', $lines[(count($lines) - 1)])) { | 
| 97 | unset($lines[(count($lines) - 1)]); | 
| 98 | } | 
| 99 | if (isset($lines[0]) && preg_match('/[ ]+\{/', $lines[0])) { | 
| 100 | unset($lines[0]); | 
| 101 | } | 
| 102 | |
| 103 | $lines = array_values($lines); | 
| 104 | |
| 105 | if (isset($lines[0]) && (str_starts_with($lines[0], ' '))) { | 
| 106 | $spaces = strlen($lines[0]) - strlen(ltrim($lines[0])); | 
| 107 | if ($spaces > 0) { | 
| 108 | $lines = array_map(function($value) use ($spaces) { | 
| 109 | if (substr($value, 0, $spaces) == str_repeat(' ', $spaces)) { | 
| 110 | $value = substr($value, $spaces); | 
| 111 | } | 
| 112 | return $value; | 
| 113 | }, $lines); | 
| 114 | } | 
| 115 | } | 
| 116 | |
| 117 | $body = implode('', $lines); | 
| 118 | } | 
| 119 | |
| 120 | if (!empty($body)) { | 
| 121 | $method->setBody($body); | 
| 122 | } | 
| 123 | } | 
| 124 | |
| 125 | // Get return type(s) | 
| 126 | if ($code->hasReturnType()) { | 
| 127 | $namedTypes = []; | 
| 128 | $returnTypes = $code->getReturnType(); | 
| 129 | if ($returnTypes instanceof \ReflectionUnionType) { | 
| 130 | $types = $returnTypes->getTypes(); | 
| 131 | foreach ($types as $type) { | 
| 132 | $namedTypes[] = $type->getName(); | 
| 133 | } | 
| 134 | if (($returnTypes->allowsNull()) && !in_array('null', $namedTypes)) { | 
| 135 | $namedTypes[] = 'null'; | 
| 136 | } | 
| 137 | } else if ($returnTypes instanceof \ReflectionNamedType) { | 
| 138 | $namedTypes[] = $returnTypes->getName(); | 
| 139 | if (($returnTypes->allowsNull()) && !in_array('null', $namedTypes)) { | 
| 140 | $namedTypes[] = 'null'; | 
| 141 | } | 
| 142 | } | 
| 143 | if (!empty($namedTypes)) { | 
| 144 | $method->addReturnTypes($namedTypes); | 
| 145 | } | 
| 146 | } | 
| 147 | |
| 148 | return $method; | 
| 149 | } | 
| 150 | |
| 151 | } |