Completed
Push — master ( 9634df...f1462e )
by Nikola
08:19
created

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