Passed
Push — master ( 0d52c3...1ee19c )
by Kacper
02:45
created

Token::dump()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
ccs 0
cts 0
cp 0
rs 9.2
cc 4
eloc 10
nc 3
nop 1
crap 20
1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2015, Some right reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp: [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Highlighter\Parser\Token;
17
18
use Kadet\Highlighter\Language\Language;
19
use Kadet\Highlighter\Parser\Rule;
20
use Kadet\Highlighter\Parser\Validator\Validator;
21
use Kadet\Highlighter\Utils\Helper;
22
23
class Token
24
{
25
    const NAME  = null;
26
    const START = 0x1;
27
    const END   = 0x2;
28
29
    protected static $_id = 0;
30
31
    public $pos;
32
    public $name;
33
    public $closedBy;
34
    public $index = 1;
35
    public $id;
36
37
    # region >>> cache
38
    /**
39
     * @var Token|null|false
40
     */
41
    protected $_end;
42
43
    /**
44
     * @var Token|null|false
45
     */
46
    protected $_start;
47
48
    /** @var Rule */
49
    protected $_rule;
50
    protected $_valid;
51
    protected $_length;
52
    # endregion
53
54
    /**
55
     * Token constructor.
56
     *
57
     * @param array $options
58
     */
59 52
    public function __construct(array $options)
60
    {
61 52
        if (isset($options[0])) {
62 39
            $this->name     = $options[0];
63 39
            $this->closedBy = $this->name;
64 39
        }
65
66 52
        if (isset($options['pos'])) {
67 49
            $this->pos = $options['pos'];
68 49
        }
69
70 52
        if (isset($options['index'])) {
71 6
            $this->index = $options['index'];
72 6
        }
73
74 52
        if (isset($options['start'])) {
75 2
            $this->setStart($options['start']);
76 2
        }
77
78 52
        if (isset($options['rule'])) {
79 19
            $this->setRule($options['rule']);
80 19
        } else {
81 34
            $this->setRule(new Rule());
82
        }
83
84 52
        if (isset($options['end'])) {
85 42
            $this->setEnd($options['end']);
86 42
        }
87
88 52
        if (isset($options['closed-by'])) {
89
            $this->closedBy = $options['closed-by'];
90
        }
91
92 52
        $this->id = ++self::$_id;
93 52
    }
94
95 13
    public static function compare(Token $a, Token $b)
96
    {
97 13
        $multiplier = $a->isEnd() ? -1 : 1;
98
99 13
        if (($a->isStart() && $b->isEnd()) || ($a->isEnd() && $b->isStart())) {
100 1
            if ($a->getStart() == $b) {
101 1
                return 1;
102 1
            } elseif ($a->getEnd() == $b) {
103
                return -1;
104
            } else {
105 1
                return $multiplier;
106
            }
107 12
        } elseif (($rule = Helper::cmp($b->_rule->priority, $a->_rule->priority)) !== 0) {
108 10
            return $multiplier*$rule;
109 5
        } elseif (($rule = Helper::cmp($b->index, $a->index)) !== 0) {
110 1
            return $multiplier*$rule;
111
        } else {
112 4
            return $multiplier*($a->id < $b->id ? -1 : 1);
113
        }
114
    }
115
116 35
    public function isStart()
117
    {
118 35
        return $this->_start === null;
119
    }
120
121 33
    public function isEnd()
122
    {
123 33
        return $this->_end === null;
124
    }
125
126 16
    public function isValid(Language $language, $context = null)
127
    {
128 16
        if ($this->_valid === null) {
129 15
            $this->validate($language, $context);
130 15
        }
131
132 16
        return $this->_valid;
133
    }
134
135 11
    protected function validate(Language $language, $context)
136
    {
137 11
        $this->setValid(
138 11
            $language === $this->_rule->language &&
139 11
            $this->_rule->validator->validate($context, $this->isEnd() ? [$this->name => Validator::CONTEXT_IN] : [])
140 11
        );
141 11
    }
142
143 15
    public function setValid($valid = true)
144
    {
145 15
        $this->_valid = $valid;
146
147 15
        if ($this->_end) {
148 12
            $this->_end->_valid = $this->_valid;
149 15
        } elseif ($this->_start) {
150 12
            $this->_start->_valid = $this->_valid;
151 12
        }
152 15
    }
153
154
    /**
155
     * @return mixed
156
     */
157 29
    public function getStart()
158
    {
159 29
        return $this->_start;
160
    }
161
162
    /**
163
     * @param Token|null|false $start
164
     */
165 3 View Code Duplication
    public function setStart($start = null)
166
    {
167 3
        $this->_end   = null;
168 3
        $this->_start = $start;
169
170 3
        if ($start instanceof Token) {
171 2
            $this->_start->_length = null;
172 2
            $start->_end = $this;
173 2
        }
174 3
    }
175
176
    /**
177
     * @return Token|null
178
     */
179 40
    public function getEnd()
180
    {
181 40
        return $this->_end;
182
    }
183
184
    /**
185
     * @param Token|null|false $end
186
     */
187 42 View Code Duplication
    public function setEnd($end = null)
188
    {
189 42
        $this->_start  = null;
190 42
        $this->_end    = $end;
191 42
        $this->_length = null;
192
193 42
        if ($end instanceof Token) {
194 42
            $end->_start = $this;
195 42
        }
196 42
    }
197
198
    /**
199
     * @return Rule
200
     */
201 16
    public function getRule()
202
    {
203 16
        return $this->_rule;
204
    }
205
206
    /**
207
     * @param Rule $rule
208
     */
209 52
    public function setRule(Rule $rule)
210
    {
211 52
        $this->_rule = $rule;
212 52
    }
213
214 2
    public function getLength()
215
    {
216 2
        if ($this->_length === null) {
217 2
            $this->_length = $this->_end === null ? 0 : $this->_end->pos - $this->pos;
218 2
        }
219
220 2
        return $this->_length;
221
    }
222
223 11
    public function __get($name)
224
    {
225 11
        return $this->getRule()->$name;
226
    }
227
}
228