PreviewBuffer   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 13
eloc 26
c 2
b 1
f 0
dl 0
loc 92
ccs 34
cts 34
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A previewPrevious() 0 6 2
A acceptLexeme() 0 7 1
A isFinished() 0 3 2
A getPreviewSymbol() 0 7 2
A resetPreview() 0 3 1
A previewNext() 0 6 2
A __construct() 0 5 1
A getEmptyLexeme() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\Lexer\Runtime\IO;
6
7
use function array_slice;
8
9
final class PreviewBuffer implements PreviewBufferInterface
10
{
11
12
    /**
13
     * @var SymbolReaderInterface
14
     */
15
    private $input;
16
17
    /**
18
     * @var SymbolInterface[]
19
     * @psalm-var array<int,SymbolInterface>
20
     */
21
    private $buffer = [];
22
23
    /**
24
     * @var int
25
     */
26
    private $previewOffset;
27
28
    /**
29
     * @var int
30
     */
31
    private $tokenOffset;
32
33 29
    public function __construct(SymbolReaderInterface $input)
34
    {
35 29
        $this->input = $input;
36 29
        $this->tokenOffset = $input->getOffset();
37 29
        $this->previewOffset = $this->tokenOffset;
38 29
    }
39
40 10
    public function getPreviewSymbol(): SymbolInterface
41
    {
42 10
        if (!isset($this->buffer[$this->previewOffset])) {
43 5
            $this->buffer[$this->previewOffset] = $this->input->read();
44
        }
45
46 10
        return $this->buffer[$this->previewOffset];
47
    }
48
49 5
    public function resetPreview(): void
50
    {
51 5
        $this->previewOffset = $this->tokenOffset;
52 5
    }
53
54 18
    public function previewNext(): void
55
    {
56 18
        if (!isset($this->buffer[$this->previewOffset])) {
57 18
            $this->buffer[$this->previewOffset] = $this->input->read();
58
        }
59 18
        $this->previewOffset++;
60 18
    }
61
62 8
    public function previewPrevious(): void
63
    {
64 8
        if ($this->previewOffset == $this->tokenOffset) {
65 2
            throw new Exception\InvalidPreviewOffsetException($this->tokenOffset);
66
        }
67 6
        $this->previewOffset--;
68 6
    }
69
70
    /**
71
     * @return bool
72
     * @psalm-pure
73
     */
74 4
    public function isFinished(): bool
75
    {
76 4
        return !isset($this->buffer[$this->previewOffset]) && $this->input->isFinished();
77
    }
78
79 8
    public function acceptLexeme(): LexemeInterface
80
    {
81 8
        $length = $this->previewOffset - $this->tokenOffset;
82 8
        $lexeme = new Lexeme(...array_slice($this->buffer, $this->tokenOffset, $length));
83 7
        $this->tokenOffset = $this->previewOffset;
84
85 7
        return $lexeme;
86
    }
87
88
    /**
89
     * @return LexemeInterface
90
     * @psalm-pure
91
     */
92 8
    public function getEmptyLexeme(): LexemeInterface
93
    {
94 8
        if (isset($this->buffer[$this->previewOffset])) {
95 2
            $symbol = $this->buffer[$this->previewOffset];
96
97 2
            return EmptyLexeme::fromOffsets(...$symbol->getLexeme()->getStartOffsets());
98
        }
99
100 6
        return $this->input->getEmptyLexeme();
101
    }
102
}
103