Completed
Push — master ( 556a60...b1e8a1 )
by Nikola
02:34
created

TraitMetadata::getMethods()   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->fqcn));
0 ignored issues
show
Bug introduced by
The property fqcn does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
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 bool
67
     */
68
    public function hasTraits()
69
    {
70
        return count($this->traits) > 0;
71
    }
72
73
    /**
74
     * @return TraitMetadata[]
75
     */
76
    public function getTraits()
77
    {
78
        return $this->traits;
79
    }
80
81
    /**
82
     * @return MethodMetadata[]
83
     */
84
    public function getMethods()
85
    {
86
        return $this->methods;
87
    }
88
89
    /**
90
     * Check if trait has method, with optional trait traverse.
91
     *
92
     * @param string $name
93
     * @param bool $traverse
94
     *
95
     * @return bool
96
     */
97 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...
98
    {
99
        foreach ($this->methods as $method) {
100
101
            if ($name === $method->getName()) {
102
                return true;
103
            }
104
        }
105
106
        if ($traverse && $this->hasTraits()) {
107
108
            /**
109
             * @var TraitMetadata $trait
110
             */
111
            foreach ($this->traits as $trait) {
112
113
                if ($trait->hasMethod($name, $traverse)) {
114
                    return true;
115
                }
116
            }
117
        }
118
119
        return false;
120
    }
121
122
    /**
123
     * Check if trait has public method, with optional trait traverse.
124
     *
125
     * @param string $name
126
     * @param bool $traverse
127
     *
128
     * @return bool
129
     */
130 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...
131
    {
132
        foreach ($this->methods as $method) {
133
134
            if ($name === $method->getName()) {
135
                return $method->isPublic();
136
            }
137
        }
138
139
        if ($traverse && $this->hasTraits()) {
140
141
            /**
142
             * @var TraitMetadata $trait
143
             */
144
            foreach ($this->traits as $trait) {
145
146
                if ($trait->hasPublicMethod($name, $traverse)) {
147
                    return true;
148
                }
149
            }
150
        }
151
152
        return false;
153
    }
154
155
    /**
156
     * Get public method for trait, with optional trait traverse.
157
     *
158
     * @param string $name
159
     * @param bool $traverse
160
     *
161
     * @return MethodMetadata
162
     *
163
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
164
     */
165
    public function getPublicMethod($name, $traverse = true)
166
    {
167 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...
168
169
            if ($name === $method->getName()) {
170
171
                if ($method->isPublic()) {
172
                    return $method;
173
                }
174
175
                throw new RuntimeException(sprintf('Method "%s()" for trait "%s" exists, but it is not public.', $name, $this->name));
176
            }
177
        }
178
179 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...
180
181
            /**
182
             * @var TraitMetadata $trait
183
             */
184
            foreach ($this->traits as $trait) {
185
186
                if ($trait->hasPublicMethod($name, $traverse)) {
187
                    return $trait->getPublicMethod($name, $traverse);
188
                }
189
            }
190
        }
191
192
        throw new RuntimeException(sprintf('Method "%s()" for trait "%s" does not exists.', $name, $this->name));
193
    }
194
195
    /**
196
     * @return Trait_
197
     */
198
    public function getAst()
199
    {
200
        return $this->ast;
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function __toString()
207
    {
208
        return $this->getName();
209
    }
210
}
211