Completed
Pull Request — master (#237)
by Kamil
02:50
created

ClassCodeGenerator::generateArguments()   C

Complexity

Conditions 7
Paths 1

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 26
rs 6.7273
cc 7
eloc 15
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Prophecy.
5
 * (c) Konstantin Kudryashov <[email protected]>
6
 *     Marcello Duarte <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Prophecy\Doubler\Generator;
13
14
/**
15
 * Class code creator.
16
 * Generates PHP code for specific class node tree.
17
 *
18
 * @author Konstantin Kudryashov <[email protected]>
19
 */
20
class ClassCodeGenerator
21
{
22
    /**
23
     * Generates PHP code for class node.
24
     *
25
     * @param string         $classname
26
     * @param Node\ClassNode $class
27
     *
28
     * @return string
29
     */
30
    public function generate($classname, Node\ClassNode $class)
31
    {
32
        $parts     = explode('\\', $classname);
33
        $classname = array_pop($parts);
34
        $namespace = implode('\\', $parts);
35
36
        $code = sprintf("class %s extends \%s implements %s {\n",
37
            $classname, $class->getParentClass(), implode(', ',
38
                array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces())
39
            )
40
        );
41
42
        foreach ($class->getProperties() as $name => $visibility) {
43
            $code .= sprintf("%s \$%s;\n", $visibility, $name);
44
        }
45
        $code .= "\n";
46
47
        foreach ($class->getMethods() as $method) {
48
            $code .= $this->generateMethod($method)."\n";
49
        }
50
        $code .= "\n}";
51
52
        return sprintf("namespace %s {\n%s\n}", $namespace, $code);
53
    }
54
55
    private function generateMethod(Node\MethodNode $method)
56
    {
57
        $php = sprintf("%s %s function %s%s(%s)%s {\n",
58
            $method->getVisibility(),
59
            $method->isStatic() ? 'static' : '',
60
            $method->returnsReference() ? '&':'',
61
            $method->getName(),
62
            implode(', ', $this->generateArguments($method->getArguments())),
63
            $method->hasReturnType() ? sprintf(': %s', $method->getReturnType()) : ''
64
        );
65
        $php .= $method->getCode()."\n";
66
67
        return $php.'}';
68
    }
69
70
    private function generateArguments(array $arguments)
71
    {
72
        return array_map(function (Node\ArgumentNode $argument) {
73
            $php = '';
74
75
            if ($hint = $argument->getTypeHint()) {
76
                if ('array' === $hint || 'callable' === $hint) {
77
                    $php .= $hint;
78
                } else {
79
                    $php .= '\\'.$hint;
80
                }
81
            }
82
83
            $php .= ' '.($argument->isPassedByReference() ? '&' : '');
84
85
            $php .= $argument->isVariadic() ? '...' : '';
86
87
            $php .= '$'.$argument->getName();
88
89
            if ($argument->isOptional()) {
90
                $php .= ' = '.var_export($argument->getDefault(), true);
91
            }
92
93
            return $php;
94
        }, $arguments);
95
    }
96
}
97