Passed
Pull Request — master (#38)
by Rustam
02:33
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 13
    public function __construct(string $directory, string ...$directories)
23
    {
24 13
        parent::__construct($directory, ...$directories);
25 13
        $this->parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
26
27 13
        $traverser = new NodeTraverser();
28 13
        $traverser->addVisitor(new NameResolver());
29
30 13
        $this->nodeTraverser = $traverser;
31
    }
32
33
    /**
34
     * @return iterable<class-string>
35
     */
36 10
    protected function getAvailableClasses(): iterable
37
    {
38 10
        $files = $this->getFiles();
39 10
        $visitor = new ParserVisitor($this->interfaces, $this->attributes, $this->parentClass);
40 10
        $this->nodeTraverser->addVisitor($visitor);
41
42 10
        foreach ($files as $file) {
43
            try {
44 10
                $nodes = $this->parser->parse($file->getContents());
45 10
                if ($nodes !== null) {
46 10
                    $this->nodeTraverser->traverse($nodes);
47
                }
48 7
            } catch (\Throwable) {
49
                // Ignore broken files or parsing errors
50
            }
51
        }
52
53 10
        return $visitor->getClassNames();
54
    }
55
}
56