Passed
Pull Request — master (#38)
by Rustam
02:20
created

PhpParserClassifier::getAvailableClasses()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 2
b 0
f 0
nc 3
nop 0
dl 0
loc 14
ccs 9
cts 9
cp 1
crap 3
rs 10
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
 * `PhpParserClassifier` finds classes using the `nikic/PHP-Parser` package and this may require performance tuning, so
14
 * you may need follow {@see https://github.com/nikic/PHP-Parser/blob/master/doc/component/Performance.markdown} instructions.
15
 */
16
final class PhpParserClassifier extends AbstractClassifier
17
{
18
    private Parser $parser;
19
    private NodeTraverser $nodeTraverser;
20
21 13
    public function __construct(string $directory, string ...$directories)
22
    {
23 13
        parent::__construct($directory, ...$directories);
24 13
        $this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
25
26 13
        $traverser = new NodeTraverser();
27 13
        $traverser->addVisitor(new NameResolver());
28
29 13
        $this->nodeTraverser = $traverser;
30
    }
31
32
    /**
33
     * @return iterable<class-string>
34
     */
35 10
    protected function getAvailableClasses(): iterable
36
    {
37 10
        $files = $this->getFiles();
38 10
        $visitor = new ClassifierVisitor($this->interfaces, $this->attributes, $this->parentClass);
39 10
        $this->nodeTraverser->addVisitor($visitor);
40
41 10
        foreach ($files as $file) {
42 10
            $nodes = $this->parser->parse($file->getContents());
43 10
            if ($nodes !== null) {
44 10
                $this->nodeTraverser->traverse($nodes);
45
            }
46
        }
47
48 10
        yield from new \ArrayIterator($visitor->getClassNames());
49
    }
50
}
51