Completed
Push — master ( eb9261...35316d )
by Nikola
03:46
created

TraitMetadata::getTraits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
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\Trait_;
13
use RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException;
14
use RunOpenCode\AbstractBuilder\Exception\RuntimeException;
15
use RunOpenCode\AbstractBuilder\Utils\ClassUtils;
16
17
/**
18
 * Class TraitMetadata
19
 *
20
 * @package RunOpenCode\AbstractBuilder\Ast\Metadata
21
 */
22
class TraitMetadata
23
{
24
    /**
25
     * @var string
26
     */
27
    private $name;
28
29
    /**
30
     * @var TraitMetadata[]
31
     */
32
    private $traits;
33
34
    /**
35
     * @var MethodMetadata[]
36
     */
37
    private $methods;
38
39
    /**
40
     * @var Trait_
41
     */
42
    private $ast;
43
44
    public function __construct($name, array $traits = [], array $methods = [], Trait_ $ast = null)
45
    {
46
        $this->name = $name;
47
48
        if (!ClassUtils::isClassNameValid($this->name)) {
49
            throw new InvalidArgumentException(sprintf('Provided full qualified class name "%s" is not valid PHP trait name.', $this->name));
50
        }
51
52
        $this->traits = $traits;
53
        $this->methods = $methods;
54
        $this->ast = $ast;
55
    }
56
57
    /**
58
     * @return string
59
     */
60
    public function getName()
61
    {
62
        return $this->name;
63
    }
64
65
    /**
66
     * @return string
67
     */
68
    public function getFqcn()
69
    {
70
        return '\\'.$this->name;
71
    }
72
73
    /**
74
     * @return bool
75
     */
76
    public function hasTraits()
77
    {
78
        return count($this->traits) > 0;
79
    }
80
81
    /**
82
     * @return TraitMetadata[]
83
     */
84
    public function getTraits()
85
    {
86
        return $this->traits;
87
    }
88
89
    /**
90
     * @return MethodMetadata[]
91
     */
92
    public function getMethods()
93
    {
94
        return $this->methods;
95
    }
96
97
    /**
98
     * Check if trait has method, with optional trait traverse.
99
     *
100
     * @param string $name
101
     * @param bool $traverse
102
     *
103
     * @return bool
104
     */
105 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...
106
    {
107
        foreach ($this->methods as $method) {
108
109
            if ($name === $method->getName()) {
110
                return true;
111
            }
112
        }
113
114
        if ($traverse && $this->hasTraits()) {
115
116
            /**
117
             * @var TraitMetadata $trait
118
             */
119
            foreach ($this->traits as $trait) {
120
121
                if ($trait->hasMethod($name, $traverse)) {
122
                    return true;
123
                }
124
            }
125
        }
126
127
        return false;
128
    }
129
130
    /**
131
     * Check if trait has public method, with optional trait traverse.
132
     *
133
     * @param string $name
134
     * @param bool $traverse
135
     *
136
     * @return bool
137
     */
138 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...
139
    {
140
        foreach ($this->methods as $method) {
141
142
            if ($name === $method->getName()) {
143
                return $method->isPublic();
144
            }
145
        }
146
147
        if ($traverse && $this->hasTraits()) {
148
149
            /**
150
             * @var TraitMetadata $trait
151
             */
152
            foreach ($this->traits as $trait) {
153
154
                if ($trait->hasPublicMethod($name, $traverse)) {
155
                    return true;
156
                }
157
            }
158
        }
159
160
        return false;
161
    }
162
163
    /**
164
     * Get public method for trait, with optional trait traverse.
165
     *
166
     * @param string $name
167
     * @param bool $traverse
168
     *
169
     * @return MethodMetadata
170
     *
171
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
172
     */
173
    public function getPublicMethod($name, $traverse = true)
174
    {
175 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...
176
177
            if ($name === $method->getName()) {
178
179
                if ($method->isPublic()) {
180
                    return $method;
181
                }
182
183
                throw new RuntimeException(sprintf('Method "%s()" for trait "%s" exists, but it is not public.', $name, $this->name));
184
            }
185
        }
186
187 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...
188
189
            /**
190
             * @var TraitMetadata $trait
191
             */
192
            foreach ($this->traits as $trait) {
193
194
                if ($trait->hasPublicMethod($name, $traverse)) {
195
                    return $trait->getPublicMethod($name, $traverse);
196
                }
197
            }
198
        }
199
200
        throw new RuntimeException(sprintf('Method "%s()" for trait "%s" does not exists.', $name, $this->name));
201
    }
202
203
    /**
204
     * @return Trait_
205
     */
206
    public function getAst()
207
    {
208
        return $this->ast;
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function __toString()
215
    {
216
        return $this->getName();
217
    }
218
}
219