Passed
Push — master ( ad0973...f9c297 )
by Kacper
02:48
created

GreedyParser   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 16
c 4
b 1
f 0
lcom 1
cbo 6
dl 0
loc 117
rs 10
ccs 58
cts 58
cp 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setLanguage() 0 3 1
B process() 0 22 5
A handleStart() 0 10 2
C handleEnd() 0 46 8
1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2016, 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\Parser\Token\LanguageToken;
21
use Kadet\Highlighter\Parser\Token\MetaToken;
22
use Kadet\Highlighter\Parser\Token\Token;
23
use Kadet\Highlighter\Utils\ArrayHelper;
24
25
class GreedyParser implements ParserInterface
26
{
27
    /**
28
     * @var array
29
     */
30
    private $_context;
31
32
    /**
33
     * @var Result
34
     */
35
    private $_result;
36
37
    /**
38
     * @var TokenIterator
39
     */
40
    private $_iterator;
41
42
    /**
43
     * @var LanguageToken
44
     */
45
    private $_start;
46
47
    /**
48
     * @var Language
49
     */
50
    private $_language;
51
52 16
    public function setLanguage(Language $language) {
53 16
        $this->_language = $language;
54 16
    }
55
56
    /**
57
     * @param TokenIterator $tokens
58
     *
59
     * @return Result
60
     */
61 11
    public function process(TokenIterator $tokens) {
62
        // Reset variables to default state
63 11
        $this->_start    = $tokens->current();
64 11
        $this->_context  = [];
65 11
        $this->_result   = new Result($tokens->getSource(), [
66 11
            $this->_start
67 11
        ]);
68 11
        $this->_iterator = $tokens;
69
70
        /** @var Token $token */
71 11
        for ($tokens->next(); $tokens->valid(); $tokens->next()) {
72 11
            $token = $tokens->current();
73
74 11
            if ($token->isValid($this->_language, $this->_context)) {
75 11
                if(($token->isStart() ? $this->handleStart($token) : $this->handleEnd($token)) === false) {
76 11
                    break;
77
                };
78 10
            }
79 10
        }
80
81 11
        return $this->_result;
82
    }
83
84 10
    protected function handleStart(Token $token) {
85 10
        if ($token instanceof LanguageToken) {
86 2
            $this->_result->merge($token->getInjected()->parse($this->_iterator));
87 2
        } else {
88 10
            $this->_result->append($token);
89 10
            $this->_context[$this->_iterator->key()] = $token->name;
90
        }
91
92 10
        return true;
93
    }
94
95 11
    protected function handleEnd(Token $token) {
96 11
        $start = $token->getStart();
97
        
98 11
        if ($token instanceof LanguageToken && $token->getLanguage() === $this->_language) {
99 11
            $this->_start->setEnd($token);
100
101 11
            if ($this->_start->postProcess) {
102 1
                $source = substr($this->_iterator->getSource(), $this->_start->pos, $this->_start->getLength());
103
104 1
                $tokens = $this->_start->getInjected()->tokenize(
105 1
                    $source, $this->_result, $this->_start->pos, Language::EMBEDDED_BY_PARENT
1 ignored issue
show
Documentation introduced by
$this->_result is of type object<Kadet\Highlighter\Parser\Result>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
106 1
                );
107 1
                $this->_result = $this->_start->getInjected()->parse($tokens);
108 1
            }
109
110
            # closing unclosed tokens
111 11
            foreach (array_reverse($this->_context) as $hash => $name) {
112 1
                $end = new Token([$name, 'pos' => $token->pos]);
113 1
                $this->_iterator[$hash]->setEnd($end);
114 1
                $this->_result[] = $end;
115 11
            }
116
117 11
            $this->_result[] = $token;
118 11
            return false;
119
        } else {
120 9
            if ($start) {
121 8
                unset($this->_context[spl_object_hash($start)]);
122 8
            } else {
123 1
                $start = ArrayHelper::find(array_reverse($this->_context), function ($k, $v) use ($token) {
124 1
                    return $v === $token->closedBy;
125 1
                });
126
127 1
                if ($start !== false) {
128 1
                    $token->setStart($this->_iterator[$start]);
129 1
                    unset($this->_context[$start]);
130 1
                    $start = $this->_iterator[$start];
131 1
                }
132
            }
133
134 9
            if (!$start instanceof MetaToken) {
135 9
                $this->_result[] = $token;
136 9
            }
137
        }
138
139 9
        return true;
140
    }
141
}