ClassGenerator::implementsMethod()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 12
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 27
ccs 13
cts 13
cp 1
crap 6
rs 9.2222
1
<?php
2
3
namespace Bdf\Form\Attribute\Processor\CodeGenerator;
4
5
use Nette\PhpGenerator\ClassType;
6
use Nette\PhpGenerator\Method;
7
use Nette\PhpGenerator\PhpNamespace;
8
use Nette\PhpGenerator\Printer;
9
use Nette\PhpGenerator\PsrPrinter;
10
use Nette\Utils\Type;
11
12
/**
13
 * Utility class for generate a generic class
14
 */
15
class ClassGenerator
16
{
17
    private PhpNamespace $namespace;
18
    private ClassType $class;
19
    private Printer $printer;
20
21 95
    public function __construct(PhpNamespace $namespace, ClassType $class, ?Printer $printer = null)
22
    {
23 95
        $this->namespace = $namespace;
24 95
        $this->class = $class;
25 95
        $this->printer = $printer ?? new PsrPrinter();
26
    }
27
28
    /**
29
     * Get the namespace object
30
     *
31
     * @return PhpNamespace
32
     */
33 95
    final public function namespace(): PhpNamespace
34
    {
35 95
        return $this->namespace;
36
    }
37
38
    /**
39
     * Get the current class instance
40
     *
41
     * @return ClassType
42
     */
43 9
    final public function class(): ClassType
44
    {
45 9
        return $this->class;
46
    }
47
48
    /**
49
     * Add an implemented interface on the class, and add use statement
50
     *
51
     * @param class-string $interface
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
52
     *
53
     * @return self
54
     */
55 91
    final public function implements(string $interface): self
56
    {
57 91
        $this->class->addImplement($interface);
58 91
        $this->namespace->addUse($interface);
59
60 91
        return $this;
61
    }
62
63
    /**
64
     * Implements a method of an interface, and auto-use all declared types (parameters and return type)
65
     *
66
     * @param class-string $interface The interface where the method is declared
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
67
     * @param literal-string $methodName The method name to implements
68
     *
69
     * @return Method
70
     */
71 91
    final public function implementsMethod(string $interface, string $methodName): Method
72
    {
73 91
        $method = Method::from([$interface, $methodName]);
74 91
        $method->setComment('{@inheritdoc}');
75 91
        $method->setBody(''); // Ensure that the body is not null
76
77 91
        foreach ($method->getParameters() as $parameter) {
78
            /** @var Type|null $type */
79 91
            $type = $parameter->getType(true);
80
81 91
            if ($type && $type->isClass()) {
82
                /** @psalm-suppress PossiblyNullArgument */
83 91
                $this->namespace->addUse($type->getSingleName());
0 ignored issues
show
Bug introduced by
It seems like $type->getSingleName() can also be of type null; however, parameter $name of Nette\PhpGenerator\PhpNamespace::addUse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
                $this->namespace->addUse(/** @scrutinizer ignore-type */ $type->getSingleName());
Loading history...
84
            }
85
        }
86
87
        /** @var Type|null $returnType */
88 91
        $returnType = $method->getReturnType(true);
89
90 91
        if ($returnType && $returnType->isClass()) {
91
            /** @psalm-suppress PossiblyNullArgument */
92 87
            $this->namespace->addUse($returnType->getSingleName());
93
        }
94
95 91
        $this->class->addMember($method);
96
97 91
        return $method;
98
    }
99
100
    /**
101
     * Add use statement and simplify it
102
     *
103
     * @param class-string $type Type to use and simplify
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
104
     * @param string|null $alias Use alias
105
     *
106
     * @return string
107
     */
108 73
    final public function useAndSimplifyType(string $type, ?string $alias = null): string
109
    {
110 73
        return $this->namespace->addUse($type, $alias)->simplifyType($type);
111
    }
112
113
    /**
114
     * Add use statement
115
     *
116
     * @param class-string $type Type to use
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
117
     * @param string|null $alias Use alias
118
     *
119
     * @return self
120
     */
121 13
    final public function use(string $type, ?string $alias = null): self
122
    {
123 13
        $this->namespace->addUse($type, $alias);
124
125 13
        return $this;
126
    }
127
128
    /**
129
     * Generate the class code
130
     *
131
     * @return string
132
     */
133 12
    final public function generateClass(): string
134
    {
135 12
        return $this->printer->printClass($this->class, $this->namespace);
136
    }
137
138
    /**
139
     * Get the related printer instance
140
     *
141
     * @return Printer
142
     */
143 95
    final public function printer(): Printer
144
    {
145 95
        return $this->printer;
146
    }
147
}
148