Completed
Push — master ( 705e4f...72d2b6 )
by Nikola
02:18
created

ClassMetadata::getPublicMethod()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 33
Code Lines 13

Duplication

Lines 23
Ratio 69.7 %

Code Coverage

Tests 5
CRAP Score 39.2005

Importance

Changes 0
Metric Value
dl 23
loc 33
ccs 5
cts 13
cp 0.3846
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 13
nc 12
nop 2
crap 39.2005

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of the Abstract builder package, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\AbstractBuilder\Ast\Metadata;
11
12
use PhpParser\Node\Stmt\Class_;
13
use RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException;
14
use RunOpenCode\AbstractBuilder\Exception\RuntimeException;
15
use RunOpenCode\AbstractBuilder\Utils\ClassUtils;
16
17
/**
18
 * Class ClassMetadata
19
 *
20
 * @package RunOpenCode\AbstractBuilder\Ast\Metadata
21
 */
22
class ClassMetadata
23
{
24
    /**
25
     * @var string
26
     */
27
    private $name;
28
29
    /**
30
     * @var ClassMetadata
31
     */
32
    private $parent;
33
34
    /**
35
     * @var TraitMetadata[]
36
     */
37
    private $traits;
38
39
    /**
40
     * @var bool
41
     */
42
    private $final;
43
44
    /**
45
     * @var bool
46
     */
47
    private $abstract;
48
49
    /**
50
     * @var MethodMetadata[]
51
     */
52
    private $methods;
53
54
    /**
55
     * @var Class_
56
     */
57
    private $ast;
58
59
    /**
60
     * ClassMetadata constructor.
61
     *
62
     * @param string $name
63
     * @param ClassMetadata|null $parent
64
     * @param bool $final
65
     * @param bool $abstract
66
     * @param MethodMetadata[] $methods
67
     * @param Class_ $ast
68
     */
69 2
    public function __construct($name, ClassMetadata $parent = null, array $traits = [], $final = false, $abstract = false, array $methods = [], Class_ $ast = null)
70
    {
71 2
        $this->name = $name;
72
73 2
        if (!ClassUtils::isClassNameValid($this->name)) {
74
            throw new InvalidArgumentException(sprintf('Provided class name "%s" is not valid PHP class name.', $this->name));
75
        }
76
77 2
        $this->parent = $parent;
78 2
        $this->traits = $traits;
79 2
        $this->final = $final;
80 2
        $this->abstract = $abstract;
81 2
        $this->methods = $methods;
82 2
        $this->ast = $ast;
83 2
    }
84
85
    /**
86
     * @return string
87
     */
88 1
    public function getName()
89
    {
90 1
        return $this->name;
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    public function getFqcn()
97
    {
98
        return '\\'.$this->name;
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    public function getShortName()
105
    {
106
        return end($parts = explode('\\', $this->name));
0 ignored issues
show
Bug introduced by
$parts = explode('\\', $this->name) cannot be passed to end() as the parameter $array expects a reference.
Loading history...
107
    }
108
109
    /**
110
     * @return bool
111
     */
112
    public function isAutoloadable()
113
    {
114
        return class_exists($this->getName(), true);
115
    }
116
117
    /**
118
     * Check if class inherits some other class.
119
     *
120
     * @return bool
121
     */
122 1
    public function hasParent()
123
    {
124 1
        return null !== $this->parent;
125
    }
126
127
    /**
128
     * @return ClassMetadata|null
129
     */
130 1
    public function getParent()
131
    {
132 1
        return $this->parent;
133
    }
134
135
    /**
136
     * @return bool
137
     */
138 1
    public function hasTraits()
139
    {
140 1
        return count($this->traits) > 0;
141
    }
142
143
    /**
144
     * @return TraitMetadata[]
145
     */
146
    public function getTraits()
147
    {
148
        return $this->traits;
149
    }
150
151
    /**
152
     * @return bool
153
     */
154
    public function isFinal()
155
    {
156
        return $this->final;
157
    }
158
159
    /**
160
     * @return bool
161
     */
162
    public function isAbstract()
163
    {
164
        return $this->abstract;
165
    }
166
167
    /**
168
     * @return MethodMetadata[]
169
     */
170
    public function getMethods()
171
    {
172
        return $this->methods;
173
    }
174
175
    /**
176
     * Check if class has method, with optional inheritance tree and trait traverse.
177
     *
178
     * @param string $name
179
     * @param bool $traverse
180
     *
181
     * @return bool
182
     */
183 View Code Duplication
    public function hasMethod($name, $traverse = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
    {
185
        foreach ($this->methods as $method) {
186
187
            if ($name === $method->getName()) {
188
                return true;
189
            }
190
        }
191
192
        if ($traverse && $this->hasTraits()) {
193
194
            /**
195
             * @var TraitMetadata $trait
196
             */
197
            foreach ($this->traits as $trait) {
198
199
                if ($trait->hasMethod($name, $traverse)) {
200
                    return true;
201
                }
202
            }
203
        }
204
205
206
        if ($traverse && $this->hasParent()) {
207
            return $this->getParent()->hasMethod($name, $traverse);
208
        }
209
210
        return false;
211
    }
212
213
    /**
214
     * Check if class has public method, with optional inheritance tree and trait traverse.
215
     *
216
     * @param string $name
217
     * @param bool $traverse
218
     *
219
     * @return bool
220
     */
221 1 View Code Duplication
    public function hasPublicMethod($name, $traverse = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
    {
223 1
        foreach ($this->methods as $method) {
224
225 1
            if ($name === $method->getName()) {
226 1
                return $method->isPublic();
227
            }
228
        }
229
230 1
        if ($traverse && $this->hasTraits()) {
231
232
            /**
233
             * @var TraitMetadata $trait
234
             */
235
            foreach ($this->traits as $trait) {
236
237
                if ($trait->hasPublicMethod($name, $traverse)) {
238
                    return true;
239
                }
240
            }
241
        }
242
243 1
        if ($traverse && $this->hasParent()) {
244
            return $this->getParent()->hasPublicMethod($name, $traverse);
245
        }
246
247 1
        return false;
248
    }
249
250
    /**
251
     * Get public method for class, with optional inheritance tree and trait traverse.
252
     *
253
     * @param string $name
254
     * @param bool $traverse
255
     *
256
     * @return MethodMetadata
257
     *
258
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
259
     */
260 1
    public function getPublicMethod($name, $traverse = true)
261
    {
262 1 View Code Duplication
        foreach ($this->methods as $method) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
264 1
            if ($name === $method->getName()) {
265
266 1
                if ($method->isPublic()) {
267 1
                    return $method;
268
                }
269
270
                throw new RuntimeException(sprintf('Method "%s()" for class "%s" exists, but it is not public.', $name, $this->name));
271
            }
272
        }
273
274 View Code Duplication
        if ($traverse && $this->hasTraits()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
276
            /**
277
             * @var TraitMetadata $trait
278
             */
279
            foreach ($this->traits as $trait) {
280
281
                if ($trait->hasPublicMethod($name, $traverse)) {
282
                    return $trait->getPublicMethod($name, $traverse);
283
                }
284
            }
285
        }
286
287
        if ($traverse && $this->hasParent() && $this->getParent()->hasPublicMethod($name, $traverse)) {
288
            return $this->getParent()->getPublicMethod($name, $traverse);
289
        }
290
291
        throw new RuntimeException(sprintf('Method "%s()" for class "%s" does not exists.', $name, $this->name));
292
    }
293
294
    /**
295
     * @return Class_
296
     */
297
    public function getAst()
298
    {
299
        return $this->ast;
300
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305
    public function __toString()
306
    {
307
        return $this->getName();
308
    }
309
}
310