Eloquent\Phony\Mock\MockGenerator::generateMethods PHP Метод

generateMethods() приватный Метод

private generateMethods ( $methods )
    private function generateMethods($methods)
    {
        $source = '';
        foreach ($methods as $method) {
            $name = $method->name();
            $nameLower = strtolower($name);
            $nameExported = var_export($name, true);
            $methodReflector = $method->method();
            switch ($nameLower) {
                case '__construct':
                case '__destruct':
                case '__call':
                case '__callstatic':
                    continue 2;
            }
            $signature = $this->signatureInspector->signature($methodReflector);
            if ($method->isCustom()) {
                $parameterName = null;
                foreach ($signature as $parameterName => $parameter) {
                    break;
                }
                if ('phonySelf' === $parameterName) {
                    array_shift($signature);
                }
            }
            $parameterCount = count($signature);
            $variadicIndex = -1;
            $variadicReference = '';
            if (empty($signature)) {
                $argumentPacking = '';
            } else {
                $argumentPacking = "\n";
                $index = -1;
                foreach ($signature as $parameter) {
                    if ($parameter[2]) {
                        --$parameterCount;
                        $variadicIndex = ++$index;
                        $variadicReference = $parameter[1];
                    } else {
                        $argumentPacking .= "\n        if (\$argumentCount > " . ++$index . ") {\n            \$arguments[] = " . $parameter[1] . '$a' . $index . ";\n        }";
                    }
                }
            }
            if ($this->isReturnTypeSupported && $methodReflector->hasReturnType()) {
                $type = $methodReflector->getReturnType();
                $isBuiltin = $type->isBuiltin();
                if ($this->isHhvm) {
                    // @codeCoverageIgnoreStart
                    $typeString = $methodReflector->getReturnTypeText();
                    // TODO: review HHVM usage of ? prefix
                    if (0 === strpos($typeString, '?')) {
                        $typeString = '';
                    } else {
                        $genericPosition = strpos($typeString, '<');
                        if (false !== $genericPosition) {
                            $typeString = substr($typeString, 0, $genericPosition);
                        }
                    }
                    $isBuiltin = $isBuiltin && false === strpos($typeString, '\\');
                    // @codeCoverageIgnoreEnd
                } else {
                    if ($type->allowsNull()) {
                        $typeString = '?' . $type;
                        // @codeCoverageIgnore
                    } else {
                        $typeString = (string) $type;
                    }
                }
                if ('self' === $typeString) {
                    $typeString = $methodReflector->getDeclaringClass()->getName();
                }
                if ($isBuiltin) {
                    $returnType = ' : ' . $typeString;
                    // TODO: remove once PHP 7.1 is used for coverage
                    // @codeCoverageIgnoreStart
                } elseif ($this->isNullableTypeSupported && 0 === strpos($typeString, '?')) {
                    $returnType = ' : ?\\' . substr($typeString, 1);
                    // @codeCoverageIgnoreEnd
                } else {
                    $returnType = ' : \\' . $typeString;
                }
                $isVoidReturn = $isBuiltin && 'void' === $typeString;
            } else {
                $returnType = '';
                $isVoidReturn = false;
            }
            $isStatic = $method->isStatic() ? 'static ' : '';
            if ($isStatic) {
                $handle = 'self::$_staticHandle';
            } else {
                $handle = '$this->_handle';
            }
            $body = "        \$argumentCount = \\func_num_args();\n" . '        $arguments = array();' . $argumentPacking . "\n\n        for (\$i = " . $parameterCount . "; \$i < \$argumentCount; ++\$i) {\n";
            if ($variadicIndex > -1) {
                $body .= "            \$arguments[] = {$variadicReference}\$a" . "{$variadicIndex}[\$i - {$variadicIndex}];\n";
            } else {
                $body .= "            \$arguments[] = \\func_get_arg(\$i);\n";
            }
            $body .= "        }\n\n        if (!{$handle}) {\n";
            // TODO: remove once PHP 7.1 is used for coverage
            // @codeCoverageIgnoreStart
            if ($isVoidReturn) {
                $resultAssign = '';
            } else {
                // @codeCoverageIgnoreEnd
                $resultAssign = '$result = ';
            }
            if ($isStatic) {
                $body .= <<<EOD
            {$resultAssign}\\call_user_func_array(
                array(__CLASS__, 'parent::' . {$nameExported}),
                \$arguments
            );
EOD;
            } else {
                $body .= <<<EOD
            {$resultAssign}\\call_user_func_array(
                array(\$this, 'parent::' . {$nameExported}),
                \$arguments
            );
EOD;
            }
            // TODO: remove once PHP 7.1 is used for coverage
            // @codeCoverageIgnoreStart
            if ($isVoidReturn) {
                $body .= "\n\n            return;\n        }\n\n" . "        {$handle}->spy" . "(__FUNCTION__)->invokeWith(\n" . '            new \\Eloquent\\Phony\\Call\\Arguments' . "(\$arguments)\n        );";
            } else {
                // @codeCoverageIgnoreEnd
                $body .= "\n\n            return \$result;\n        }\n\n" . "        \$result = {$handle}->spy" . "(__FUNCTION__)->invokeWith(\n" . '            new \\Eloquent\\Phony\\Call\\Arguments' . "(\$arguments)\n        );\n\n" . '        return $result;';
            }
            $returnsReference = $methodReflector->returnsReference() ? '&' : '';
            $source .= "\n    " . $method->accessLevel() . ' ' . $isStatic . 'function ' . $returnsReference . $name;
            if (empty($signature)) {
                $source .= '()' . $returnType . "\n    {\n";
            } else {
                $index = -1;
                $isFirst = true;
                foreach ($signature as $parameter) {
                    if ($isFirst) {
                        $isFirst = false;
                        $source .= "(\n        ";
                    } else {
                        $source .= ",\n        ";
                    }
                    $source .= $parameter[0] . $parameter[1] . $parameter[2] . '$a' . ++$index . $parameter[3];
                }
                $source .= "\n    )" . $returnType . " {\n";
            }
            $source .= $body . "\n    }\n";
        }
        return $source;
    }