Skip to content

Commit 521415c

Browse files
committed
[CLEANUP] Don't store array length as a property
Since PHP 5, if not earlier, the length of an array is internally stored by PHP and can be accessed in O(1) time. Maintaining both the array and its length in class properties is error-prone (particularly regarding possible future code changes). When used in a loop, `\count($array)` is more repetitively expensive than `$arrayLength`, but the latter can be set up as a local variable as and when needed. Reference: https://stackoverflow.com/questions/5835241/is-phps-count-function-o1-or-on-for-arrays This change also ensures that the characters are always a (dazzling) array. And adds a type parameter to `ParserState::setCharset()`, which was unavoidably required. Resolves #953.
1 parent d71ff28 commit 521415c

File tree

2 files changed

+19
-24
lines changed

2 files changed

+19
-24
lines changed

config/phpstan-baseline.neon

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ parameters:
174174
count: 2
175175
path: ../src/Parsing/ParserState.php
176176

177-
-
178-
message: '#^Parameters should have "string" types as the only types passed to this method$#'
179-
identifier: typePerfect.narrowPublicClassMethodParamType
180-
count: 1
181-
path: ../src/Parsing/ParserState.php
182-
183177
-
184178
message: '#^Parameters should have "string\|int\|null" types as the only types passed to this method$#'
185179
identifier: typePerfect.narrowPublicClassMethodParamType

src/Parsing/ParserState.php

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ParserState
3030
/**
3131
* @var array<int, string>
3232
*/
33-
private $characters;
33+
private $characters = [];
3434

3535
/**
3636
* @var int
@@ -44,11 +44,6 @@ class ParserState
4444
*/
4545
private $charset;
4646

47-
/**
48-
* @var int
49-
*/
50-
private $length;
51-
5247
/**
5348
* @var int
5449
*/
@@ -69,15 +64,21 @@ public function __construct($text, Settings $parserSettings, $lineNumber = 1)
6964
/**
7065
* Sets the charset to be used if the CSS does not contain an `@charset` declaration.
7166
*
72-
* @param string $charset
67+
* @throws SourceException
7368
*/
74-
public function setCharset($charset): void
69+
public function setCharset(string $charset): void
7570
{
71+
// The charset property must be set for `strsplit()`, but may need to be reverted if it fails.
72+
$oldCharset = $this->charset;
7673
$this->charset = $charset;
77-
$this->characters = $this->strsplit($this->text);
78-
if (\is_array($this->characters)) {
79-
$this->length = \count($this->characters);
74+
75+
$newCharacters = $this->strsplit($this->text);
76+
if (!\is_array($newCharacters)) {
77+
$this->charset = $oldCharset;
78+
throw new SourceException('Charset `' . $charset . '` cannot be reconciled with the CSS provided.');
8079
}
80+
81+
$this->characters = $newCharacters;
8182
}
8283

8384
/**
@@ -227,7 +228,7 @@ public function consumeWhiteSpace(): array
227228
try {
228229
$oComment = $this->consumeComment();
229230
} catch (UnexpectedEOFException $e) {
230-
$this->currentPosition = $this->length;
231+
$this->currentPosition = \count($this->characters);
231232
return $comments;
232233
}
233234
} else {
@@ -259,7 +260,7 @@ public function comes($sString, $bCaseInsensitive = false): bool
259260
public function peek($length = 1, $iOffset = 0): string
260261
{
261262
$iOffset += $this->currentPosition;
262-
if ($iOffset >= $this->length) {
263+
if ($iOffset >= \count($this->characters)) {
263264
return '';
264265
}
265266
return $this->substr($iOffset, $length);
@@ -288,7 +289,7 @@ public function consume($mValue = 1): string
288289
$this->currentPosition += $this->strlen($mValue);
289290
return $mValue;
290291
} else {
291-
if ($this->currentPosition + $mValue > $this->length) {
292+
if ($this->currentPosition + $mValue > \count($this->characters)) {
292293
throw new UnexpectedEOFException((string) $mValue, $this->peek(5), 'count', $this->lineNumber);
293294
}
294295
$result = $this->substr($this->currentPosition, $mValue);
@@ -345,7 +346,7 @@ public function consumeComment()
345346

346347
public function isEnd(): bool
347348
{
348-
return $this->currentPosition >= $this->length;
349+
return $this->currentPosition >= \count($this->characters);
349350
}
350351

351352
/**
@@ -438,10 +439,10 @@ public function strlen($sString): int
438439
private function substr($iStart, $length): string
439440
{
440441
if ($length < 0) {
441-
$length = $this->length - $iStart + $length;
442+
$length = \count($this->characters) - $iStart + $length;
442443
}
443-
if ($iStart + $length > $this->length) {
444-
$length = $this->length - $iStart;
444+
if ($iStart + $length > \count($this->characters)) {
445+
$length = \count($this->characters) - $iStart;
445446
}
446447
$result = '';
447448
while ($length > 0) {

0 commit comments

Comments
 (0)