Skip to content

[TASK] Use native type declarations in ParserState #1136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Please also have a look at our
- Make all non-private properties `@internal` (#886)
- Use more native type declarations and strict mode
(#641, #772, #774, #778, #804, #841, #873, #875, #891, #922, #923, #933, #958,
#964, #967, #1000, #1044, #1134, #1137, #1139)
#964, #967, #1000, #1044, #1134, #1136, #1137, #1139)
- Add visibility to all class/interface constants (#469)

### Deprecated
Expand Down
18 changes: 0 additions & 18 deletions config/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,6 @@ parameters:
count: 1
path: ../src/Parsing/ParserState.php

-
message: '#^Parameters should have "bool" types as the only types passed to this method$#'
identifier: typePerfect.narrowPublicClassMethodParamType
count: 2
path: ../src/Parsing/ParserState.php

-
message: '#^Parameters should have "int" types as the only types passed to this method$#'
identifier: typePerfect.narrowPublicClassMethodParamType
count: 2
path: ../src/Parsing/ParserState.php

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

-
message: '#^Cannot call method render\(\) on string\.$#'
identifier: method.nonObject
Expand Down
90 changes: 29 additions & 61 deletions src/Parsing/ParserState.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ParserState
private $characters;

/**
* @var int
* @var int<0, max>
*/
private $currentPosition = 0;

Expand All @@ -53,7 +53,7 @@ class ParserState
* @param string $text the complete CSS as text (i.e., usually the contents of a CSS file)
* @param int<1, max> $lineNumber
*/
public function __construct($text, Settings $parserSettings, int $lineNumber = 1)
public function __construct(string $text, Settings $parserSettings, int $lineNumber = 1)
{
$this->parserSettings = $parserSettings;
$this->text = $text;
Expand All @@ -75,23 +75,20 @@ public function setCharset(string $charset): void
/**
* @return int<1, max>
*/
public function currentLine()
public function currentLine(): int
{
return $this->lineNumber;
}

/**
* @return int
* @return int<0, max>
*/
public function currentColumn()
public function currentColumn(): int
{
return $this->currentPosition;
}

/**
* @return Settings
*/
public function getSettings()
public function getSettings(): Settings
{
return $this->parserSettings;
}
Expand All @@ -102,21 +99,17 @@ public function anchor(): Anchor
}

/**
* @param int $position
* @param int<0, max> $position
*/
public function setPosition($position): void
public function setPosition(int $position): void
{
$this->currentPosition = $position;
}

/**
* @param bool $ignoreCase
*
* @return string
*
* @throws UnexpectedTokenException
*/
public function parseIdentifier($ignoreCase = true)
public function parseIdentifier(bool $ignoreCase = true): string
{
if ($this->isEnd()) {
throw new UnexpectedEOFException('', '', 'identifier', $this->lineNumber);
Expand All @@ -140,14 +133,10 @@ public function parseIdentifier($ignoreCase = true)
}

/**
* @param bool $isForIdentifier
*
* @return string|null
*
* @throws UnexpectedEOFException
* @throws UnexpectedTokenException
*/
public function parseCharacter($isForIdentifier)
public function parseCharacter(bool $isForIdentifier): ?string
{
if ($this->peek() === '\\') {
$this->consume('\\');
Expand Down Expand Up @@ -225,11 +214,7 @@ public function consumeWhiteSpace(): array
return $comments;
}

/**
* @param string $string
* @param bool $caseInsensitive
*/
public function comes($string, $caseInsensitive = false): bool
public function comes(string $string, bool $caseInsensitive = false): bool
{
$peek = $this->peek(\strlen($string));
return ($peek == '')
Expand All @@ -238,10 +223,10 @@ public function comes($string, $caseInsensitive = false): bool
}

/**
* @param int $length
* @param int $offset
* @param int<1, max> $length
* @param int<0, max> $offset
*/
public function peek($length = 1, $offset = 0): string
public function peek(int $length = 1, int $offset = 0): string
{
$offset += $this->currentPosition;
if ($offset >= \count($this->characters)) {
Expand All @@ -251,7 +236,7 @@ public function peek($length = 1, $offset = 0): string
}

/**
* @param int $value
* @param string|int<1, max> $value
*
* @throws UnexpectedEOFException
* @throws UnexpectedTokenException
Expand Down Expand Up @@ -286,12 +271,12 @@ public function consume($value = 1): string

/**
* @param string $expression
* @param int|null $maximumLength
* @param int<1, max>|null $maximumLength
*
* @throws UnexpectedEOFException
* @throws UnexpectedTokenException
*/
public function consumeExpression($expression, $maximumLength = null): string
public function consumeExpression(string $expression, ?int $maximumLength = null): string
{
$matches = null;
$input = $maximumLength !== null ? $this->peek($maximumLength) : $this->inputLeft();
Expand Down Expand Up @@ -335,17 +320,15 @@ public function isEnd(): bool

/**
* @param array<array-key, string>|string $stopCharacters
* @param bool $includeEnd
* @param bool $consumeEnd
* @param array<int, Comment> $comments
*
* @throws UnexpectedEOFException
* @throws UnexpectedTokenException
*/
public function consumeUntil(
$stopCharacters,
$includeEnd = false,
$consumeEnd = false,
bool $includeEnd = false,
bool $consumeEnd = false,
array &$comments = []
): string {
$stopCharacters = \is_array($stopCharacters) ? $stopCharacters : [$stopCharacters];
Expand Down Expand Up @@ -386,12 +369,7 @@ private function inputLeft(): string
return $this->substr($this->currentPosition, -1);
}

/**
* @param string $string1
* @param string $string2
* @param bool $caseInsensitive
*/
public function streql($string1, $string2, $caseInsensitive = true): bool
public function streql(string $string1, string $string2, bool $caseInsensitive = true): bool
{
if ($caseInsensitive) {
return $this->strtolower($string1) === $this->strtolower($string2);
Expand All @@ -401,17 +379,17 @@ public function streql($string1, $string2, $caseInsensitive = true): bool
}

/**
* @param int $numberOfCharacters
* @param int<1, max> $numberOfCharacters
*/
public function backtrack($numberOfCharacters): void
public function backtrack(int $numberOfCharacters): void
{
$this->currentPosition -= $numberOfCharacters;
}

/**
* @param string $string
* @return int<0, max>
*/
public function strlen($string): int
public function strlen(string $string): int
{
if ($this->parserSettings->hasMultibyteSupport()) {
return \mb_strlen($string, $this->charset);
Expand All @@ -421,10 +399,9 @@ public function strlen($string): int
}

/**
* @param int $offset
* @param int $length
* @param int<0, max> $offset
*/
private function substr($offset, $length): string
private function substr(int $offset, int $length): string
{
if ($length < 0) {
$length = \count($this->characters) - $offset + $length;
Expand All @@ -441,10 +418,7 @@ private function substr($offset, $length): string
return $result;
}

/**
* @param string $string
*/
private function strtolower($string): string
private function strtolower(string $string): string
{
if ($this->parserSettings->hasMultibyteSupport()) {
return \mb_strtolower($string, $this->charset);
Expand All @@ -454,13 +428,11 @@ private function strtolower($string): string
}

/**
* @param string $string
*
* @return array<int, string>
*
* @throws SourceException if the charset is UTF-8 and the string contains invalid byte sequences
*/
private function strsplit($string)
private function strsplit(string $string): array
{
if ($this->parserSettings->hasMultibyteSupport()) {
if ($this->streql($this->charset, 'utf-8')) {
Expand All @@ -487,13 +459,9 @@ private function strsplit($string)
}

/**
* @param string $haystack
* @param string $needle
* @param int $offset
*
* @return int|false
*/
private function strpos($haystack, $needle, $offset)
private function strpos(string $haystack, string $needle, int $offset)
{
if ($this->parserSettings->hasMultibyteSupport()) {
return \mb_strpos($haystack, $needle, $offset, $this->charset);
Expand Down