Reflection::getModifierNames()   D
last analyzed

Complexity

Conditions 14
Paths 128

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 14.0525

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
rs 4.7877
ccs 29
cts 31
cp 0.9355
cc 14
eloc 24
nc 128
nop 1
crap 14.0525

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
namespace Benoth\StaticReflection\Reflection;
4
5
abstract class Reflection implements \Reflector
6
{
7
    const IS_STATIC            = 1;
8
    const IS_ABSTRACT          = 2;
9
    const IS_FINAL             = 4;
10
    const IS_IMPLICIT_ABSTRACT = 16;
11
    const IS_EXPLICIT_ABSTRACT = 32;
12
    const IS_PUBLIC            = 256;
13
    const IS_PROTECTED         = 512;
14
    const IS_PRIVATE           = 1024;
15
    const IS_DEPRECATED        = 262144;
16
17
    /**
18
     * @type string
19
     */
20
    protected $name;
21
22
    /**
23
     * @type string
24
     */
25
    protected $fileName;
26
27
    /**
28
     * @type int
29
     */
30
    protected $startLine;
31
32
    /**
33
     * @type int
34
     */
35
    protected $endLine;
36
37
    /**
38
     * Constructs a new Reflection object.
39
     *
40
     * @param string $name The fully qualified name
41
     */
42 1101
    public function __construct($name)
43
    {
44 1101
        $this->name = $name;
45 1101
    }
46
47
    /**
48
     * Gets the fully qualified entity name (with the namespace).
49
     *
50
     * @return string
51
     */
52 963
    public function getName()
53
    {
54 963
        return $this->name;
55
    }
56
57
    /**
58
     * Gets the short name of the entity (without the namespace).
59
     *
60
     * @return string
61
     */
62 1101
    public function getShortName()
63
    {
64 1101
        $parts = explode('\\', $this->name);
65
66 1101
        return end($parts);
67
    }
68
69
    /**
70
     * Gets the namespace name.
71
     *
72
     * @return string
73
     */
74 12
    public function getNamespaceName()
75
    {
76 12
        $parts = explode('\\', $this->name);
77 12
        array_pop($parts);
78
79 12
        return implode('\\', $parts);
80
    }
81
82
    /**
83
     * Checks if this entity is defined in a namespace.
84
     *
85
     * @return bool
86
     */
87 6
    public function inNamespace()
88
    {
89 6
        return strlen($this->getNamespaceName()) > 0;
90
    }
91
92
    /**
93
     * Gets the filename of the file in which the class has been defined.
94
     *
95
     * @return string
96
     */
97 1065
    public function getFileName()
98
    {
99 1065
        return $this->fileName;
100
    }
101
102
    /**
103
     * Get the starting line number.
104
     *
105
     * @return int
106
     */
107 6
    public function getStartLine()
108
    {
109 6
        return $this->startLine;
110
    }
111
112
    /**
113
     * Get the ending line number.
114
     *
115
     * @return int
116
     */
117
    public function getEndLine()
118
    {
119
        return $this->endLine;
120
    }
121
122
    /**
123
     * Gets a ReflectionExtension object for the extension which defined the entity.
124
     *
125
     * @return \ReflectionExtension|null Null for user defined
126
     */
127
    public function getExtension()
128
    {
129
        return;
130
    }
131
132
    /**
133
     * Gets the name of the extension which defined the entity.
134
     *
135
     * @return string|bool Extension name or false for user defined
136
     */
137
    public function getExtensionName()
138
    {
139
        return false;
140
    }
141
142
    /**
143
     * Returns a bitfield of the access modifiers for this class.
144
     *
145
     * @return int Bitmask of modifier constants
146
     */
147 12
    public function getModifiers()
148
    {
149 12
        $modifiers = 0;
150
151 12
        if (method_exists($this, 'isStatic') && $this->isStatic()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isStatic() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\...ection\ReflectionMethod, Benoth\StaticReflection\...tion\ReflectionProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
152 6
            $modifiers |= static::IS_STATIC;
153 6
        }
154 12
        if (method_exists($this, 'isAbstract') && $this->isAbstract()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isAbstract() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\Reflection\ReflectionClass, Benoth\StaticReflection\...ection\ReflectionMethod. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
155 6
            $modifiers |= static::IS_ABSTRACT;
156 6
        }
157 12
        if (method_exists($this, 'isFinal') && $this->isFinal()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isFinal() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\Reflection\ReflectionClass, Benoth\StaticReflection\...ection\ReflectionMethod, Benoth\StaticReflection\Reflection\ReflectionTrait. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
158 6
            $modifiers |= static::IS_FINAL;
159 6
        }
160
161 12
        if (method_exists($this, 'isPublic') && $this->isPublic()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isPublic() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\...ection\ReflectionMethod, Benoth\StaticReflection\...tion\ReflectionProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
162 12
            $modifiers |= static::IS_PUBLIC;
163 12
        } elseif (method_exists($this, 'isProtected') && $this->isProtected()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isProtected() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\...ection\ReflectionMethod, Benoth\StaticReflection\...tion\ReflectionProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
164 12
            $modifiers |= static::IS_PROTECTED;
165 12
        } elseif (method_exists($this, 'isPrivate') && $this->isPrivate()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Benoth\StaticReflection\Reflection\Reflection as the method isPrivate() does only exist in the following sub-classes of Benoth\StaticReflection\Reflection\Reflection: Benoth\StaticReflection\...ection\ReflectionMethod, Benoth\StaticReflection\...tion\ReflectionProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
166 6
            $modifiers |= static::IS_PRIVATE;
167 6
        }
168
169 12
        return $modifiers;
170
    }
171
172
    /**
173
     * Returns the string representation of the Reflection object.
174
     *
175
     * @return string
176
     */
177
    public function __toString()
178
    {
179
        return static::export($this, true);
180
    }
181
182
    /**
183
     * Exports a reflected class.
184
     *
185
     * @param \Reflector $argument The reflection to export.
186
     * @param bool       $return   Setting to true will return the export, otherwise will emitt it.
187
     *
188
     * @return string|void
189
     */
190
    public static function export(\Reflector $argument, $return = false)
191
    {
192
        // @todo Implement export()
193
        // @see https://github.com/Roave/BetterReflection/blob/f8adf4865fa635166cf91a544882deab0cf5b7e6/src/Reflection/ReflectionClass.php#L96
194
        throw new \ReflectionException('Not implemented yet');
195
    }
196
197
    /**
198
     * Gets modifiers names.
199
     *
200
     * @param int $modifiers
201
     *
202
     * @return array An array of modifier names
203
     */
204 6
    public static function getModifierNames($modifiers)
205
    {
206 6
        $isAbstract         = ($modifiers & static::IS_ABSTRACT) === static::IS_ABSTRACT;
207 6
        $isFinal            = ($modifiers & static::IS_FINAL) === static::IS_FINAL;
208 6
        $isStatic           = ($modifiers & static::IS_STATIC) === static::IS_STATIC;
209 6
        $isExplicitAbstract = ($modifiers & static::IS_EXPLICIT_ABSTRACT) === static::IS_EXPLICIT_ABSTRACT;
210 6
        $isPublic           = ($modifiers & static::IS_PUBLIC) === static::IS_PUBLIC;
211 6
        $isProtected        = ($modifiers & static::IS_PROTECTED) === static::IS_PROTECTED;
212 6
        $isPrivate          = ($modifiers & static::IS_PRIVATE) === static::IS_PRIVATE;
213
214 6
        $returns = [];
215 6
        if ($isAbstract) {
216 3
            $returns[] = 'abstract';
217 3
        }
218 6
        if ($isFinal) {
219 3
            $returns[] = 'final';
220 3
        }
221 6
        if ($isStatic) {
222 3
            $returns[] = 'static';
223 3
        }
224 6
        if ($isExplicitAbstract) {
225
            $returns[] = 'abstract';
226
        }
227 6
        if ($isPublic && !$isProtected && !$isPrivate) {
228 6
            $returns[] = 'public';
229 6
        }
230 6
        if (!$isPublic && $isProtected && !$isPrivate) {
231 6
            $returns[] = 'protected';
232 6
        }
233 6
        if (!$isPublic && !$isProtected && $isPrivate) {
234 3
            $returns[] = 'private';
235 3
        }
236
237 6
        return array_unique($returns);
238
    }
239
240
    /**
241
     * Sets the filename of the file in which the class has been defined.
242
     *
243
     * @internal
244
     *
245
     * @param string $fileName
246
     *
247
     * @return self
248
     */
249 1101
    public function setFilename($fileName)
250
    {
251 1101
        $this->fileName = $fileName;
252
253 1101
        return $this;
254
    }
255
256
    /**
257
     * Set the starting line number.
258
     *
259
     * @internal
260
     *
261
     * @param int $startLine
262
     *
263
     * @return self
264
     */
265 1101
    public function setStartLine($startLine)
266
    {
267 1101
        $this->startLine = $startLine;
268
269 1101
        return $this;
270
    }
271
272
    /**
273
     * Set the starting line number.
274
     *
275
     * @internal
276
     *
277
     * @param int $endLine
278
     *
279
     * @return self
280
     */
281 1101
    public function setEndLine($endLine)
282
    {
283 1101
        $this->endLine = $endLine;
284
285 1101
        return $this;
286
    }
287
}
288