Passed
Push — master ( 93b753...7b55bb )
by Edward
03:55
created

TokenMatcherTemplate.php$0 ➔ isVisitedTransition()   A

Complexity

Conditions 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
dl 0
loc 9
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
namespace Remorhaz\UniLex\Lexer;
4
5
use Remorhaz\UniLex\Exception;
6
use Remorhaz\UniLex\IO\CharBufferInterface;
7
use Remorhaz\UniLex\IO\TokenExtractInterface;
8
9
abstract class TokenMatcherTemplate implements TokenMatcherInterface
10
{
11
12
    private $token;
13
14
    private $mode = self::DEFAULT_MODE;
15
16
    /**
17
     * @return Token
18
     * @throws Exception
19
     */
20
    public function getToken(): Token
21
    {
22
        if (!isset($this->token)) {
23
            throw new Exception("Token is not defined");
24
        }
25
26
        return $this->token;
27
    }
28
29
    protected function createContext(
30
        CharBufferInterface $buffer,
31
        TokenFactoryInterface $tokenFactory
32
    ): TokenMatcherContextInterface {
33
        $onConstruct = function (): void {
34
            unset($this->token);
35
        };
36
        $onSetNewToken = function (int $tokenType) use ($tokenFactory): void {
37
            $this->token = $tokenFactory->createToken($tokenType);
38
        };
39
        $onGetToken = function (): Token {
40
            return $this->getToken();
41
        };
42
        $onSetMode = function (string $mode): void {
43
            $this->mode = $mode;
44
        };
45
        $onGetMode = function (): string {
46
            return $this->mode;
47
        };
48
49
        return new class (
50
            $buffer,
51
            $onConstruct,
52
            $onSetNewToken,
53
            $onGetToken,
54
            $onSetMode,
55
            $onGetMode
56
        ) implements TokenMatcherContextInterface {
57
58
            private $buffer;
59
60
            private $onSetNewToken;
61
62
            private $onGetToken;
63
64
            private $onSetMode;
65
66
            private $onGetMode;
67
68
            private $visitedTransitions = [];
69
70
            public function __construct(
71
                CharBufferInterface $buffer,
72
                callable $onConstruct,
73
                callable $onSetNewToken,
74
                callable $onGetToken,
75
                callable $onSetMode,
76
                callable $onGetMode
77
            ) {
78
                $this->buffer = $buffer;
79
                $this->onSetNewToken = $onSetNewToken;
80
                $this->onGetToken = $onGetToken;
81
                $this->onSetMode = $onSetMode;
82
                $this->onGetMode = $onGetMode;
83
                call_user_func($onConstruct);
84
            }
85
86
            public function setNewToken(int $tokenType): TokenMatcherContextInterface
87
            {
88
                call_user_func($this->onSetNewToken, $tokenType);
89
90
                return $this;
91
            }
92
93
            /**
94
             * @param string $name
95
             * @param        $value
96
             * @return TokenMatcherContextInterface
97
             */
98
            public function setTokenAttribute(string $name, $value): TokenMatcherContextInterface
99
            {
100
                $this
101
                    ->getToken()
102
                    ->setAttribute($name, $value);
103
104
                return $this;
105
            }
106
107
            public function getToken(): Token
108
            {
109
                return call_user_func($this->onGetToken);
110
            }
111
112
            public function getBuffer(): CharBufferInterface
113
            {
114
                return $this->buffer;
115
            }
116
117
            public function getSymbolString(): string
118
            {
119
                $buffer = $this->getBuffer();
120
                if ($buffer instanceof TokenExtractInterface) {
121
                    return $buffer->getTokenAsString();
122
                }
123
                throw new Exception("Extracting strings is not supported by buffer");
124
            }
125
126
            public function getSymbolList(): array
127
            {
128
                $buffer = $this->getBuffer();
129
                if ($buffer instanceof TokenExtractInterface) {
130
                    return $buffer->getTokenAsArray();
131
                }
132
                throw new Exception("Extracting arrays is not supported by buffer");
133
            }
134
135
            public function getMode(): string
136
            {
137
                return call_user_func($this->onGetMode);
138
            }
139
140
            public function setMode(string $mode): TokenMatcherContextInterface
141
            {
142
                call_user_func($this->onSetMode, $mode);
143
144
                return $this;
145
            }
146
147
            public function visitTransition(string $hash): void
148
            {
149
                $this->visitedTransitions[$hash] = true;
150
            }
151
152
            public function isVisitedTransition(string ...$hashes): bool
153
            {
154
                foreach ($hashes as $hash) {
155
                    if (isset($this->visitedTransitions[$hash])) {
156
                        return true;
157
                    }
158
                }
159
160
                return false;
161
            }
162
        };
163
    }
164
}
165