Passed
Pull Request — master (#40)
by Alexander
09:55 queued 07:23
created

ParserClassifier   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 37
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 37
ccs 16
cts 16
cp 1
rs 10
c 0
b 0
f 0
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getAvailableClasses() 0 18 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Classifier;
6
7
use PhpParser\NodeTraverser;
8
use PhpParser\NodeVisitor\NameResolver;
9
use PhpParser\Parser;
10
use PhpParser\ParserFactory;
11
12
/**
13
 * `ParserClassifier` finds classes using [`nikic/PHP-Parser`](https://github.com/nikic/PHP-Parser).
14
 * This may require performance tuning, so you may need
15
 * follow {@see https://github.com/nikic/PHP-Parser/blob/master/doc/component/Performance.markdown} instructions.
16
 */
17
final class ParserClassifier extends AbstractClassifier
18
{
19
    private Parser $parser;
20
    private NodeTraverser $nodeTraverser;
21
22 14
    public function __construct(string $directory, string ...$directories)
23
    {
24 14
        parent::__construct($directory, ...$directories);
25 14
        $this->parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
26
27 14
        $traverser = new NodeTraverser();
28 14
        $traverser->addVisitor(new NameResolver());
29
30 14
        $this->nodeTraverser = $traverser;
31
    }
32
33
    /**
34
     * @return iterable<class-string>
35
     */
36 11
    protected function getAvailableClasses(): iterable
37
    {
38 11
        $files = $this->getFiles();
39 11
        $visitor = new ParserVisitor($this->interfaces, $this->attributes, $this->parentClass);
40 11
        $this->nodeTraverser->addVisitor($visitor);
41
42 11
        foreach ($files as $file) {
43
            try {
44 11
                $nodes = $this->parser->parse($file->getContents());
45 11
                if ($nodes !== null) {
46 11
                    $this->nodeTraverser->traverse($nodes);
47
                }
48 7
            } catch (\Throwable) {
49
                // Ignore broken files or parsing errors
50
            }
51
        }
52
53 11
        return $visitor->getClassNames();
54
    }
55
}
56