Passed
Pull Request — master (#8)
by
unknown
03:10
created

SymbolExtractor   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 86.96%

Importance

Changes 0
Metric Value
eloc 22
dl 0
loc 67
ccs 20
cts 23
cp 0.8696
rs 10
c 0
b 0
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A extract() 0 28 4
A readFile() 0 4 1
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
                $contents = $this->readFile($file);
53
54 2
                $statements = $this->parser->parse($contents);
55 1
            } catch (Error $e) {
56
                // Either not a file, file is not readable, not a PHP file or
57
                // the broken file should be detected by other tooling entirely.
58 1
                continue;
59
            }
60
61 1
            $tracker   = new SymbolTracker($filter);
62 1
            $traverser = new NodeTraverser();
63 1
            $traverser->addVisitor($tracker);
64 1
            $traverser->traverse($statements);
65
66 1
            foreach ($tracker->getSymbols() as $node) {
67 1
                $symbols[] = new Symbol($file, $node);
68
            }
69
        }
70
71 3
        return new SymbolIterator(...$symbols);
72
    }
73
74
    /**
75
     * @param \SplFileInfo $file
76
     *
77
     * @return string
78
     */
79
    private function readFile(\SplFileInfo $file): string
80
    {
81
        $handle = $file->openFile('rb');
82
        return $handle->fread($file->getSize());
83
    }
84
}
85