TokenStream   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 158
Duplicated Lines 12.66 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 74.13%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 20
loc 158
ccs 43
cts 58
cp 0.7413
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A __toString() 0 4 1
A next() 10 10 2
A rewind() 0 5 1
B seek() 0 28 6
A prev() 10 10 2
A expectPrev() 0 18 4
A splice() 0 7 1
A position() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace uuf6429\ExpressionLanguage;
4
5
use InvalidArgumentException;
6
use Symfony\Component\ExpressionLanguage\SyntaxError;
7
use Symfony\Component\ExpressionLanguage\Token;
8
9
class TokenStream extends \Symfony\Component\ExpressionLanguage\TokenStream
10
{
11
    /** @var Token[] */
12
    private $tokens;
13
14
    /** @var int */
15
    private $position = 0;
16
17
    /**
18 42
     * Overrides parent constructor because of private properties.
19
     *
20 42
     * {@inheritdoc}
21
     */
22 42
    public function __construct(array $tokens)
23 42
    {
24 42
        parent::__construct($tokens);
25
26
        $this->tokens = $tokens;
27
        $this->rewind();
28
    }
29
30
    /**
31
     * Overrides parent method because of private properties.
32
     *
33
     * {@inheritdoc}
34
     */
35
    public function __toString()
36
    {
37
        return implode("\n", $this->tokens);
38
    }
39
40
    /**
41 30
     * Overrides parent method because of private properties.
42
     *
43 30
     * {@inheritdoc}
44
     */
45 View Code Duplication
    public function next(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
    {
47 30
        if (!isset($this->tokens[$this->position])) {
48
            throw new SyntaxError('Unexpected end of expression', $this->current->cursor);
49 30
        }
50 30
51
        ++$this->position;
52
53
        $this->current = $this->tokens[$this->position];
54
    }
55 42
56
    /**
57 42
     * Move stream pointer to the beginning.
58 42
     */
59 42
    public function rewind(): void
60
    {
61
        $this->position = 0;
62
        $this->current = $this->tokens[0];
63
    }
64
65
    /**
66
     * Move to a particular position in the stream.
67 4
     *
68
     * @param int $offset The offset relative to $whence
69
     * @param int $whence One of SEEK_SET, SEEK_CUR or SEEK_END constants
70 4
     */
71 1
    public function seek($offset, $whence): void
72 1
    {
73
        switch ($whence) {
74 4
            case SEEK_CUR:
75 1
                $this->position += $offset;
76 1
                break;
77
78 4
            case SEEK_END:
79 4
                $this->position = count($this->tokens) - 1 + $offset;
80 4
                break;
81
82
            case SEEK_SET:
83
                $this->position = $offset;
84
                break;
85
86 4
            default:
87
                throw new InvalidArgumentException('Value of argument $whence is not valid.');
88
        }
89
90
        if (!isset($this->tokens[$this->position])) {
91
            throw new SyntaxError(
92
                sprintf('Cannot seek to %s of expression', $this->position > 0 ? 'beyond end' : 'before start'),
93 4
                $this->position
94 4
            );
95
        }
96
97
        $this->current = $this->tokens[$this->position];
98
    }
99 4
100
    /**
101 4
     * Sets the pointer to the previous token.
102
     */
103 View Code Duplication
    public function prev(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105 4
        if (!isset($this->tokens[$this->position])) {
106
            throw new SyntaxError('Unexpected start of expression', $this->current->cursor);
107 4
        }
108 4
109
        --$this->position;
110
111
        $this->current = $this->tokens[$this->position];
112
    }
113
114
    /**
115
     * Tests a token and moves to previous one.
116
     *
117 4
     * @param array|int   $type    The type to test
118
     * @param string|null $value   The token value
119 4
     * @param string|null $message The syntax error message
120 4
     */
121
    public function expectPrev($type, $value = null, $message = null): void
122
    {
123
        $token = $this->current;
124
        if (!$token->test($type, $value)) {
125
            throw new SyntaxError(
126
                sprintf(
127
                    '%sUnexpected token "%s" of value "%s" ("%s" expected%s)',
128
                    $message ? $message . '. ' : '',
129
                    $token->type,
130
                    $token->value,
131
                    $type,
132
                    $value ? sprintf(' with value "%s"', $value) : ''
133 4
                ),
134 4
                $token->cursor
135
            );
136
        }
137
        $this->prev();
138
    }
139
140
    /**
141
     * Returns new TokenStream with tokens replaced by some others.
142
     *
143
     * @param int   $offset
144
     * @param int   $length
145 4
     * @param Token[] $replacements
146
     *
147 4
     * @return static
148 4
     */
149
    public function splice($offset, $length, $replacements): self
150 4
    {
151
        $tokens = $this->tokens;
152
        array_splice($tokens, $offset, $length, $replacements);
153
154
        return new static($tokens);
155
    }
156
157
    /**
158 6
     * Returns the current position.
159
     *
160 6
     * @return int
161
     */
162
    public function position(): int
163
    {
164
        return $this->position;
165
    }
166
}
167