AbstractParser   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 232
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 51
c 1
b 0
f 0
dl 0
loc 232
ccs 41
cts 41
cp 1
rs 10
wmc 18

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getAnnotReader() 0 3 1
A obtainDocBlock() 0 4 1
A __construct() 0 6 1
A getAnnotList() 0 3 1
A getDocBlock() 0 3 1
A getReflection() 0 3 1
A getParserManager() 0 3 1
A execAnnotReader() 0 4 1
A createAnnotObject() 0 32 4
A generateAllAnnotObject() 0 26 6
1
<?php
2
3
namespace BultonFr\Annotation\Parsers;
4
5
use Exception;
6
use Reflector;
7
use BultonFr\Annotation\Annotations\AbstractAnnotation;
8
use BultonFr\Annotation\ParserManager;
9
use BultonFr\Annotation\Parsers\Annotations\Info;
10
use BultonFr\Annotation\Parsers\Annotations\Reader as AnnotReader;
11
12
/**
13
 * Abstract class for all classes which parse a part of a class
14
 * to find annotation into it.
15
 *
16
 * @package BultonFr\Annotation
17
 */
18
abstract class AbstractParser
19
{
20
    /**
21
     * @const EXCEP_CLASS_NOT_FOUND Exception code if the class for an
22
     * annotation is not found
23
     *
24
     * @see README.md for code format
25
     */
26
    const EXCEP_CLASS_NOT_FOUND = 302001;
27
28
    /**
29
     * @const EXCEP_NO_EXTENDS_ABSTRACT_ANNOTATION Exception code if the
30
     * annotation object not have AbstractAnnotation into his parents.
31
     *
32
     * @see README.md for code format
33
     */
34
    const EXCEP_NO_EXTENDS_ABSTRACT_ANNOTATION = 302002;
35
36
    /**
37
     * The parser manager system
38
     *
39
     * @var \BultonFr\Annotation\ParserManager
40
     */
41
    protected $parserManager;
42
43
    /**
44
     * The Reflection object for the readed item
45
     *
46
     * @var \Reflector
47
     */
48
    protected $reflection;
49
50
    /**
51
     * The annotation reader system
52
     *
53
     * @var \BultonFr\Annotation\Parsers\Annotations\Reader|null
54
     */
55
    protected $annotReader;
56
57
    /**
58
     * The docblock content of the parsed item
59
     *
60
     * @var string
61
     */
62
    protected $docBlock = '';
63
64
    /**
65
     * The list of annotation object.
66
     *
67
     * @var array
68
     */
69
    protected $annotList = [];
70
71
    /**
72
     * Construct
73
     *
74
     * @param ParserManager $parserManager
75
     * @param Reflector $reflection
76
     */
77
    public function __construct(
78
        ParserManager $parserManager,
79
        Reflector $reflection
80
    ) {
81 1
        $this->parserManager = $parserManager;
82 1
        $this->reflection    = $reflection;
83 1
    }
84
85
    /**
86
     * Run the parser
87
     *
88
     * @return void
89
     */
90
    abstract public function run();
91
92
    /**
93
     * Get the parser manager system
94
     *
95
     * @return \BultonFr\Annotation\ParserManager
96
     */
97
    public function getParserManager(): ParserManager
98
    {
99 1
        return $this->parserManager;
100
    }
101
102
    /**
103
     * Get the Reflection object for the readed item
104
     *
105
     * @return \Reflector
106
     */
107
    public function getReflection(): Reflector
108
    {
109 1
        return $this->reflection;
110
    }
111
112
    /**
113
     * Get the annotation reader system
114
     *
115
     * @return \BultonFr\Annotation\Parsers\Annotations\Reader|null
116
     */
117
    public function getAnnotReader(): ?AnnotReader
118
    {
119 1
        return $this->annotReader;
120
    }
121
122
    /**
123
     * Get the docblock content of the parsed item
124
     *
125
     * @return string
126
     */
127
    public function getDocBlock(): string
128
    {
129 1
        return $this->docBlock;
130
    }
131
132
    /**
133
     * Get the value of annotList
134
     */
135
    public function getAnnotList(): array
136
    {
137 1
        return $this->annotList;
138
    }
139
140
    /**
141
     * Obtain the docblock content for the parsed item
142
     *
143
     * @return string
144
     */
145
    public function obtainDocBlock(): string
146
    {
147 1
        $this->docBlock = $this->reflection->getDocComment();
0 ignored issues
show
Bug introduced by
The method getDocComment() does not exist on Reflector. It seems like you code against a sub-type of said class. However, the method does not exist in ReflectionExtension or ReflectionZendExtension or ReflectionParameter. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

147
        /** @scrutinizer ignore-call */ 
148
        $this->docBlock = $this->reflection->getDocComment();
Loading history...
148 1
        return $this->docBlock;
149
    }
150
151
    /**
152
     * Instanciate and use the annotation reader to parse the docblock and
153
     * generate a list of Annotations\Info object which contain data about
154
     * each annotation find.
155
     *
156
     * @return void
157
     */
158
    protected function execAnnotReader()
159
    {
160 1
        $this->annotReader = new AnnotReader;
161 1
        $this->annotReader->parse($this->obtainDocBlock());
162 1
    }
163
164
    /**
165
     * Read the list of Annotations\Info object, create the final
166
     * object for each annotation find (with the method createAnnotObject),
167
     * and save it into the property $annotList.
168
     *
169
     * Nota: Annotation AddNS will not be added to this list
170
     *
171
     * @param string $itemName The name of the currently parsed item
172
     *
173
     * @return void
174
     */
175
    protected function generateAllAnnotObject(string $itemName)
176
    {
177 1
        $allAnnotList = $this->annotReader->getAnnotationList();
0 ignored issues
show
Bug introduced by
The method getAnnotationList() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

177
        /** @scrutinizer ignore-call */ 
178
        $allAnnotList = $this->annotReader->getAnnotationList();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
178
179 1
        foreach ($allAnnotList as $annotName => $annotList) {
180 1
            if ($annotName === 'AddNS') {
181 1
                continue;
182
            }
183
184 1
            if (array_key_exists($annotName, $this->annotList) === false) {
185 1
                $this->annotList[$annotName] = [];
186
            }
187
188 1
            foreach ($annotList as $annotInfo) {
189 1
                $annotObj = $this->createAnnotObject(
190 1
                    $itemName,
191
                    $annotName,
192
                    $annotInfo
193
                );
194
195 1
                if (method_exists($annotObj, '__toString')) {
196 1
                    $keyValue = $annotObj->__toString();
197
198 1
                    $this->annotList[$annotName][$keyValue] = $annotObj;
199
                } else {
200 1
                    $this->annotList[$annotName][] = $annotObj;
201
                }
202
            }
203
        }
204 1
    }
205
206
    /**
207
     * Instanciate the dedicated annotation object for the readed annotation
208
     *
209
     * @param string $itemName The name of the currently parsed item
210
     * @param string $className The dedicated class name for this annotation
211
     * @param Info $annotInfo Info about the readed annotation
212
     *
213
     * @return AbstractAnnotation
214
     *
215
     * @throws Exception If there is a problem with the dedicated class for
216
     * the readed annotation.
217
     */
218
    protected function createAnnotObject(
219
        string $itemName,
220
        string $className,
221
        Info $annotInfo
222
    ): AbstractAnnotation {
223 1
        $nsList = $this->parserManager->getImportedNS();
224
225 1
        if (isset($nsList[$className])) {
226 1
            $className = $nsList[$className];
227
        }
228
        
229 1
        if (class_exists($className) === false) {
230 1
            throw new Exception(
231 1
                'No class found for namespace '.$className.', please use AddNS annotation to add the class',
232 1
                static::EXCEP_CLASS_NOT_FOUND
233
            );
234
        }
235
        
236 1
        $annotation = new $className(
237 1
            $this->parserManager->getReader(),
238
            $itemName,
239
            $annotInfo
240
        );
241
242 1
        if ($annotation instanceof AbstractAnnotation === false) {
243 1
            throw new Exception(
244 1
                'The annotation class must extends of AbstractAnnotation.',
245 1
                static::EXCEP_NO_EXTENDS_ABSTRACT_ANNOTATION
246
            );
247
        }
248
        
249 1
        return $annotation;
250
    }
251
}
252