Completed
Push — master ( 69b695...671bd7 )
by Kirill
06:49
created

RuleResolver::analyze()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 9
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
crap 6
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\Compiler\Grammar\PP2;
11
12
use Railt\Compiler\Exception\GrammarException;
13
use Railt\Compiler\Reader\BaseRules;
14
use Railt\Io\Exception\ExternalFileException;
15
use Railt\Io\Readable;
16
use Railt\Lexer\TokenInterface;
17
use Railt\Parser\Rule\Symbol;
18
19
/**
20
 * Class RuleResolver
21
 */
22
class RuleResolver extends BaseRules implements ResolverInterface
23
{
24
    /**
25
     * @var array
26
     */
27
    private $ruleTokens = [];
28
29
    /**
30
     * @var string|null
31
     */
32
    private $current;
33
34
    /**
35
     * @var array
36
     */
37
    private $keep = [];
38
39
    /**
40
     * @var TokenResolver
41
     */
42
    private $tokens;
43
44
    /**
45
     * RuleResolver constructor.
46
     * @param TokenResolver $tokens
47
     */
48
    public function __construct(TokenResolver $tokens)
49
    {
50
        $this->tokens = $tokens;
51
    }
52
53
    /**
54
     * @param Readable $readable
55
     * @param TokenInterface $token
56
     * @throws \Railt\Io\Exception\ExternalFileException
57
     */
58
    public function resolve(Readable $readable, TokenInterface $token): void
59
    {
60
        if ($this->next($readable, $token)) {
61
            return;
62
        }
63
64
        if (! \array_key_exists($this->current, $this->ruleTokens)) {
65
            $this->ruleTokens[$this->current] = [];
66
        }
67
68
        $this->ruleTokens[$this->current][] = $token;
69
70
        $this->addFile($this->current, $readable);
71
    }
72
73
    /**
74
     * @param Readable $readable
75
     * @param TokenInterface $token
76
     * @return bool
77
     * @throws \Railt\Io\Exception\ExternalFileException
78
     */
79
    private function next(Readable $readable, TokenInterface $token): bool
80
    {
81
        if ($token->name() === 'T_NODE_DEFINITION') {
82
            $this->resolveCurrent($readable, $token);
83
            return true;
84
        }
85
86
        if ($this->current === null) {
87
            $error = \sprintf('Unprocessed production %s', $token->value(0));
88
            throw (new GrammarException($error))->throwsIn($readable, $token->offset());
89
        }
90
91
        return false;
92
    }
93
94
    /**
95
     * @param Readable $readable
96
     * @param TokenInterface $token
97
     * @throws \Railt\Io\Exception\ExternalFileException
98
     */
99
    private function resolveCurrent(Readable $readable, TokenInterface $token): void
100
    {
101
        $this->current = \trim($token->value(1), '#');
102
103
        if ($token->value(1)[0] === '#') {
104
            $this->keep[] = $this->current;
105
        }
106
107
        if ($token->value(2)) {
108
            try {
109
                $this->addDelegate($this->current, $token->value(2));
110
            } catch (ExternalFileException $e) {
111
                throw $e->throwsIn($readable, $token->offset());
112
            }
113
        }
114
    }
115
116
    /**
117
     * @return array|Symbol[]
118
     */
119
    private function analyze(): array
120
    {
121
        $analyzer = new Analyzer(parent::all(), $this->keep);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (all() instead of analyze()). Are you sure this is correct? If so, you might want to change this to $this->all().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
122
123
        foreach ($this->ruleTokens as $rule => $tokens) {
124
            $analyzer->add($rule, $tokens);
125
        }
126
127
        $this->ruleTokens = [];
128
129
        return $analyzer->getResult();
130
    }
131
132
    /**
133
     * @return array
134
     */
135
    public function all(): array
136
    {
137
       foreach ($this->analyze() as $symbol) {
138
           $this->add($symbol);
139
       }
140
141
        return parent::all();
142
    }
143
}
144