Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of sebastian/lines-of-code.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace SebastianBergmann\LinesOfCode;
11
 
12
use function substr_count;
13
use PhpParser\Error;
14
use PhpParser\Lexer;
15
use PhpParser\Node;
16
use PhpParser\NodeTraverser;
17
use PhpParser\Parser;
18
use PhpParser\ParserFactory;
19
 
20
final class Counter
21
{
22
    /**
23
     * @throws RuntimeException
24
     */
25
    public function countInSourceFile(string $sourceFile): LinesOfCode
26
    {
27
        return $this->countInSourceString(file_get_contents($sourceFile));
28
    }
29
 
30
    /**
31
     * @throws RuntimeException
32
     */
33
    public function countInSourceString(string $source): LinesOfCode
34
    {
35
        $linesOfCode = substr_count($source, "\n");
36
 
37
        if ($linesOfCode === 0 && !empty($source)) {
38
            $linesOfCode = 1;
39
        }
40
 
41
        try {
42
            $nodes = $this->parser()->parse($source);
43
 
44
            assert($nodes !== null);
45
 
46
            return $this->countInAbstractSyntaxTree($linesOfCode, $nodes);
47
 
48
            // @codeCoverageIgnoreStart
49
        } catch (Error $error) {
50
            throw new RuntimeException(
51
                $error->getMessage(),
52
                (int) $error->getCode(),
53
                $error
54
            );
55
        }
56
        // @codeCoverageIgnoreEnd
57
    }
58
 
59
    /**
60
     * @param Node[] $nodes
61
     *
62
     * @throws RuntimeException
63
     */
64
    public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode
65
    {
66
        $traverser = new NodeTraverser;
67
        $visitor   = new LineCountingVisitor($linesOfCode);
68
 
69
        $traverser->addVisitor($visitor);
70
 
71
        try {
72
            /* @noinspection UnusedFunctionResultInspection */
73
            $traverser->traverse($nodes);
74
            // @codeCoverageIgnoreStart
75
        } catch (Error $error) {
76
            throw new RuntimeException(
77
                $error->getMessage(),
78
                (int) $error->getCode(),
79
                $error
80
            );
81
        }
82
        // @codeCoverageIgnoreEnd
83
 
84
        return $visitor->result();
85
    }
86
 
87
    private function parser(): Parser
88
    {
89
        return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
90
    }
91
}