ProjectParser::obtainClassList()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace bultonFr\MethodsHeaderGenerator;
4
5
/**
6
 * Usefull to improve performence when we parse a big project. All classes
7
 * already parsed are saved, so not need to re-parse it again.
8
 * 
9
 * Parse all class from composer autoloader list.
10
 * To have the full list, run a "composer update" with "-o" argument.
11
 */
12
class ProjectParser
13
{
14
    /**
15
     * @var string $vendorDir Path to the composer vendor dir
16
     */
17
    protected $vendorDir = '';
18
    
19
    /**
20
     * @var \Composer\Autoload\ClassLoader|null $composerLoader Composer
21
     * auto-loader
22
     */
23
    protected $composerLoader;
24
    
25
    /**
26
     * @var \bultonFr\MethodsHeaderGenerator\ClassParser[] $classes All classes who
27
     * are already parsed
28
     */
29
    protected $classes = [];
30
    
31
    /**
32
     * @var string[] $nsToParse All namespace to parse (should start by him)
33
     */
34
    protected $nsToParse;
35
    
36
    /**
37
     * @var string[] $nsToIgnore All namespace to ignore (should start by him)
38
     */
39
    protected $nsToIgnore;
40
    
41
    /**
42
     * Construct
43
     * Convert nsToParse and nsToIgnore to array if need.
44
     * Obtain the composer loader.
45
     * 
46
     * @param string $vendorDir Path to the composer vendor dir
47
     * @param string[]|string $nsToParse All namespace to parse
48
     *  (should start by him)
49
     * @param string[]|string $nsToIgnore All namespace to ignore
50
     *  (should start by him)
51
     */
52
    public function __construct($vendorDir, $nsToParse, $nsToIgnore = [])
53
    {
54
        $this->vendorDir = $vendorDir;
55
        
56
        if (!is_array($nsToParse)) {
57
            $nsToParse = [$nsToParse];
58
        }
59
        if (!is_array($nsToIgnore)) {
60
            $nsToIgnore = [$nsToIgnore];
61
        }
62
        
63
        $this->nsToParse  = $nsToParse;
64
        $this->nsToIgnore = $nsToIgnore;
65
        
66
        $this->obtainComposerLoader();
67
    }
68
    
69
    /**
70
     * Getter accessor to property vendorDir
71
     * 
72
     * @return string
73
     */
74
    public function getVendorDir()
75
    {
76
        return $this->vendorDir;
77
    }
78
79
    /**
80
     * Getter accessor to property composerLoader
81
     * 
82
     * @return \Composer\Autoload\ClassLoader|null
83
     */
84
    public function getComposerLoader()
85
    {
86
        return $this->composerLoader;
87
    }
88
89
    /**
90
     * Getter accessor to property classes
91
     * 
92
     * @return \bultonFr\MethodsHeaderGenerator\ClassParser[]
93
     */
94
    public function getClasses()
95
    {
96
        return $this->classes;
97
    }
98
99
    /**
100
     * Getter accessor to property nsToParse
101
     * 
102
     * @return string[]
103
     */
104
    public function getNsToParse()
105
    {
106
        return $this->nsToParse;
107
    }
108
109
    /**
110
     * Getter accessor to property nsToIgnore
111
     * 
112
     * @return string[]
113
     */
114
    public function getNsToIgnore()
115
    {
116
        return $this->nsToIgnore;
117
    }
118
    
119
    /**
120
     * Check if a class exist into the list
121
     * 
122
     * @param string $className The class name we want to check
123
     * 
124
     * @return bool
125
     */
126
    public function hasClasses($className)
127
    {
128
        return isset($this->classes[$className]);
129
    }
130
    
131
    /**
132
     * Return the ClassParser object for a class name
133
     * 
134
     * @param string $className The class name for which obtain the ClassParser
135
     * 
136
     * @return \bultonFr\MethodsHeaderGenerator\ClassParser
137
     * 
138
     * @throws \Exception If the class not exist into the list
139
     */
140
    public function getClassesByName($className)
141
    {
142
        if ($this->hasClasses($className) === false) {
143
            throw new \Exception('Class not found');
144
        }
145
        
146
        return $this->classes[$className];
147
    }
148
    
149
    /**
150
     * Add a new class to the list
151
     * 
152
     * @param \bultonFr\MethodsHeaderGenerator\ClassParser $parser The ClassParser
153
     * object to add
154
     * 
155
     * @return void
156
     */
157
    public function addToClasses(ClassParser $parser)
158
    {
159
        $className                 = $parser->getClassName();
160
        $this->classes[$className] = $parser;
161
    }
162
    
163
    /**
164
     * Obtain the composer loader
165
     * Into this own method to allow people to extends this class to not use
166
     * composer to obtain the class list.
167
     * 
168
     * @return void
169
     */
170
    protected function obtainComposerLoader()
171
    {
172
        $this->composerLoader = require($this->vendorDir.'/autoload.php');
173
    }
174
    
175
    /**
176
     * Obtain the class list from the composer class map
177
     * Into this own method to allow people to extends this class to not use
178
     * composer to obtain the class list.
179
     * 
180
     * @return void
181
     */
182
    protected function obtainClassList()
183
    {
184
        return $this->composerLoader->getClassMap();
0 ignored issues
show
Bug introduced by
The method getClassMap() 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

184
        return $this->composerLoader->/** @scrutinizer ignore-call */ getClassMap();

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...
Bug Best Practice introduced by
The expression return $this->composerLoader->getClassMap() returns the type array which is incompatible with the documented return type void.
Loading history...
185
    }
186
    
187
    /**
188
     * Read the class list, check namespace to know if the class should be
189
     * parsed or not, and run the parser if allowed.
190
     * 
191
     * @return string
192
     */
193
    public function run()
194
    {
195
        $classMap = $this->obtainClassList();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $classMap is correct as $this->obtainClassList() targeting bultonFr\MethodsHeaderGe...rser::obtainClassList() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
196
        $output   = '';
197
        
198
        foreach ($classMap as $className => $classFilePath) {
0 ignored issues
show
Bug introduced by
The expression $classMap of type void is not traversable.
Loading history...
199
            if ($this->isIgnoredNS($className) === true) {
200
                continue;
201
            }
202
            
203
            if ($this->hasClasses($className)) {
204
                $parser = $this->getClassesByName($className);
205
            } else {
206
                $parser = new ClassParser($className, $this);
207
                $this->addToClasses($parser);
208
            }
209
            
210
            $parser->run();
211
            
212
            $output .= $parser."\n\n";
213
        }
214
        
215
        return $output;
216
    }
217
    
218
    /**
219
     * Check if a class should be parsed or not from this name (with namespace)
220
     * Use properties nsToIgnore and nsToParse to know.
221
     * 
222
     * @param string $className The class name to check, with namespace
223
     * 
224
     * @return boolean
225
     */
226
    protected function isIgnoredNS($className) {
227
        foreach ($this->nsToIgnore as $toIgnore) {
228
            if (strpos($className, $toIgnore) === 0) {
229
                return true;
230
            }
231
        }
232
        
233
        foreach ($this->nsToParse as $toParse) {
234
            if (strpos($className, $toParse) === 0) {
235
                return false;
236
            }
237
        }
238
        
239
        return true;
240
    }
241
}
242