Completed
Push — master ( 536f4c...b2c699 )
by Kacper
02:31
created

Token::compare()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 2 Features 0
Metric Value
c 6
b 2
f 0
dl 0
loc 22
rs 5.9012
cc 11
eloc 11
nc 12
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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;
17
18
19
use Kadet\Highlighter\Language\Language;
20
use Kadet\Highlighter\Utils\Helper;
21
use Kadet\Highlighter\Utils\StringHelper;
22
23
class Token
24
{
25
    const NAME = null;
26
27
    protected static $_id = 0;
28
29
    public $pos;
30
    public $name;
31
    public $index = 1;
32
33
    /**
34
     * @var Token
35
     */
36
    protected $_end;
37
38
    /**
39
     * @var Token
40
     */
41
    protected $_start;
42
43
    /** @var Rule */
44
    protected $_rule;
45
46
    protected $_valid;
47
    protected $_length;
48
49
    public $id;
50
51
    /**
52
     * Token constructor.
53
     */
54
    public function __construct(array $options)
55
    {
56
        // Name
57
        if (isset($options[0])) {
58
            $this->name = $options[0];
59
        }
60
61
        if (isset($options['pos'])) {
62
            $this->pos = $options['pos'];
63
        }
64
65
        if (isset($options['index'])) {
66
            $this->index = $options['index'];
67
        }
68
69
        if (isset($options['start'])) {
70
            $this->setStart($options['start']);
71
        }
72
73
        if (isset($options['rule'])) {
74
            $this->setRule($options['rule']);
75
        }
76
77
        if (isset($options['end'])) {
78
            $this->setEnd($options['end']);
79
        }
80
81
        $this->id = ++self::$_id;
82
83
        if (isset($options['length'])) {
84
            new static([$this->name, 'pos' => $this->pos + $options['length'], 'start' => $this, 'rule' => $this->getRule()]);
85
        }
86
    }
87
88
    public static function compare(Token $a, Token $b)
89
    {
90
        if ($a->pos === $b->pos) {
91
            $multiplier = $a->isEnd() ? -1 : 1;
92
93
            if (($rule = Helper::cmp($b->_rule->getPriority(), $a->_rule->getPriority())) !== 0) {
94
                return $multiplier*$rule;
95
            }
96
97
            if (($a->isStart() && !$b->isStart()) || ($a->isEnd() && !$b->isEnd())) {
98
                return $multiplier;
99
            }
100
101
            if (($rule = Helper::cmp($b->index, $a->index)) !== 0) {
102
                return $multiplier*$rule;
103
            }
104
105
            return $multiplier*($a->id < $b->id ? -1 : 1);
106
        }
107
108
        return ($a->pos > $b->pos) ? 1 : -1;
109
    }
110
111
    public function isStart()
112
    {
113
        return $this->_start === null && !($this->_rule instanceof CloseRule);
114
    }
115
116
    public function isEnd()
117
    {
118
        return $this->_end === null && !($this->_rule instanceof OpenRule);
119
    }
120
121
    public function isValid(Language $language, $context = null)
122
    {
123
        if ($this->_valid === null) {
124
            $this->validate($language, $context);
125
        }
126
127
        return $this->_valid;
128
    }
129
130
    protected function validate(Language $language, $context)
131
    {
132
        $this->setValid(
133
            $language === $this->_rule->getLanguage() &&
134
            $this->_rule->validateContext($context, $this->isEnd() ? [$this->name => Rule::CONTEXT_IN] : [])
135
        );
136
    }
137
138
    public function setValid($valid = true)
139
    {
140
        $this->_valid = $valid;
141
142
        if ($this->_end !== null) {
143
            $this->_end->_valid = $this->_valid;
144
        } elseif ($this->_start !== null) {
145
            $this->_start->_valid = $this->_valid;
146
        }
147
    }
148
149
    /**
150
     * @return mixed
151
     */
152
    public function getStart()
153
    {
154
        return $this->_start;
155
    }
156
157
    /**
158
     * @param Token $start
159
     */
160 View Code Duplication
    public function setStart(Token $start = null)
161
    {
162
        $this->_end = null;
163
        $this->_start = $start;
164
165
        if ($start !== null) {
166
            $this->_start->_end = $this;
167
        }
168
    }
169
170
    /**
171
     * @return Token|null
172
     */
173
    public function getEnd()
174
    {
175
        return $this->_end;
176
    }
177
178
    /**
179
     * @param Token $end
180
     */
181 View Code Duplication
    public function setEnd(Token $end = null)
182
    {
183
        $this->_start = null;
184
        $this->_end = $end;
185
        $this->_length = null;
186
187
        if ($end !== null) {
188
            $this->_end->_start = $this;
189
        }
190
    }
191
192
    /**
193
     * @return Rule
194
     */
195
    public function getRule()
196
    {
197
        return $this->_rule;
198
    }
199
200
    /**
201
     * @param Rule $rule
202
     */
203
    public function setRule(Rule $rule)
204
    {
205
        $this->_rule = $rule;
206
    }
207
208
    public function getLength()
209
    {
210
        if ($this->_length === null) {
211
            $this->_length = $this->_end === null ? 0 : $this->_end->pos - $this->pos;
212
        }
213
214
        return $this->_length;
215
    }
216
217
    public function dump($text = null)
218
    {
219
        $pos = StringHelper::positionToLine($text, $this->pos);
220
        $pos = $pos['line'] . ':' . $pos['pos'];
221
222
        if ($this->isStart()) {
223
            $result = "Start ({$this->name}) $pos";
224
            if ($text !== null && $this->_end !== null) {
225
                $result .= "  \x02" . substr($text, $this->pos, $this->_end->pos - $this->pos) . "\x03";
226
            }
227
        } else {
228
            $result = "End ({$this->name}) $pos";
229
        }
230
231
        return $result;
232
    }
233
}