Passed
Push — master ( 8340e9...b3c77d )
by Jan-Marten
01:43
created

SymbolExtractor::extract()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 33
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5.005

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 7
nop 2
dl 0
loc 33
ccs 16
cts 17
cp 0.9412
crap 5.005
rs 9.3888
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright MediaCT. All rights reserved.
4
 * https://www.mediact.nl
5
 */
6
7
namespace Mediact\DependencyGuard\Php;
8
9
use Mediact\DependencyGuard\Iterator\FileIteratorInterface;
10
use Mediact\DependencyGuard\Php\Filter\SymbolFilterInterface;
11
use PhpParser\Error;
12
use PhpParser\NodeTraverser;
13
use PhpParser\Parser;
14
use PhpParser\ParserFactory;
15
16
class SymbolExtractor implements SymbolExtractorInterface
17
{
18
    /** @var Parser */
19
    private $parser;
20
21
    /**
22
     * Constructor.
23
     *
24
     * @param Parser|null $parser
25
     */
26 1
    public function __construct(Parser $parser = null)
27
    {
28 1
        if ($parser === null) {
29 1
            $factory = new ParserFactory();
30 1
            $parser  = $factory->create(ParserFactory::PREFER_PHP7);
31
        }
32
33 1
        $this->parser = $parser;
34 1
    }
35
36
    /**
37
     * Extract the PHP symbols from the given files.
38
     *
39
     * @param FileIteratorInterface $files
40
     * @param SymbolFilterInterface $filter
41
     *
42
     * @return SymbolIteratorInterface
43
     */
44 3
    public function extract(
45
        FileIteratorInterface $files,
46
        SymbolFilterInterface $filter
47
    ): SymbolIteratorInterface {
48 3
        $symbols = [];
49
50 3
        foreach ($files as $file) {
51
            try {
52 2
                $handle   = $file->openFile('rb');
53 2
                $contents = $handle->fread($file->getSize());
54
55 2
                if (!$contents) { // phpstan thinks this can only return string.
56
                    continue;
57
                }
58
59 2
                $statements = $this->parser->parse($contents);
60 1
            } catch (Error $e) {
61
                // Either not a file, file is not readable, not a PHP file or
62
                // the broken file should be detected by other tooling entirely.
63 1
                continue;
64
            }
65
66 1
            $tracker   = new SymbolTracker($filter);
67 1
            $traverser = new NodeTraverser();
68 1
            $traverser->addVisitor($tracker);
69 1
            $traverser->traverse($statements);
70
71 1
            foreach ($tracker->getSymbols() as $node) {
72 1
                $symbols[] = new Symbol($file, $node);
73
            }
74
        }
75
76 3
        return new SymbolIterator(...$symbols);
77
    }
78
}
79