From a24115faa4aa655da7c26cad5c09c9aefca6cdf1 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Sat, 28 Jun 2025 18:13:29 +0100 Subject: [PATCH 1/7] [CLEANUP] Tidy up `DeclarationBlock::parse()` - Assign the result of `ParserState::peek()` to a local variable, for efficiency; - Use a switch statement to branch on its value, for extensibility (e.g. #1292); - Don't unnecessarily test that a quote character is not escaped when not within a string. --- src/RuleSet/DeclarationBlock.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index e4125797..8bf2bf8f 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -44,14 +44,20 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? do { $selectorParts[] = $parserState->consume(1) . $parserState->consumeUntil(['{', '}', '\'', '"'], false, false, $comments); - if (\in_array($parserState->peek(), ['\'', '"'], true) && \substr(\end($selectorParts), -1) != '\\') { - if (!isset($stringWrapperCharacter)) { - $stringWrapperCharacter = $parserState->peek(); - } elseif ($stringWrapperCharacter === $parserState->peek()) { - unset($stringWrapperCharacter); - } + $nextCharacter = $parserState->peek(); + switch ($nextCharacter) { + case '\'': + case '"': + if (!isset($stringWrapperCharacter)) { + $stringWrapperCharacter = $nextCharacter; + } elseif ($stringWrapperCharacter === $nextCharacter) { + if (\substr(\end($selectorParts), -1) !== '\\') { + unset($stringWrapperCharacter); + } + } + break; } - } while (!\in_array($parserState->peek(), ['{', '}'], true) || isset($stringWrapperCharacter)); + } while (!\in_array($nextCharacter, ['{', '}'], true) || isset($stringWrapperCharacter)); $result->setSelectors(\implode('', $selectorParts), $list); if ($parserState->comes('{')) { $parserState->consume(1); From 3fe6d1317e0070a44afc596391b27fd525c63abf Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Sat, 28 Jun 2025 18:35:39 +0100 Subject: [PATCH 2/7] Add comment about fallthrough in `switch` Co-authored-by: Oliver Klee --- src/RuleSet/DeclarationBlock.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index 8bf2bf8f..3063fdc0 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -47,6 +47,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? $nextCharacter = $parserState->peek(); switch ($nextCharacter) { case '\'': + // The fallthrough is intentional. case '"': if (!isset($stringWrapperCharacter)) { $stringWrapperCharacter = $nextCharacter; From 4d5318593bff352d905c226d4b51c818a769d592 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Sat, 28 Jun 2025 18:36:26 +0100 Subject: [PATCH 3/7] Use `is_string` rather than `isset` Co-authored-by: Oliver Klee --- src/RuleSet/DeclarationBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index 3063fdc0..f234c946 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -49,7 +49,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? case '\'': // The fallthrough is intentional. case '"': - if (!isset($stringWrapperCharacter)) { + if (!\is_string($stringWrapperCharacter)) { $stringWrapperCharacter = $nextCharacter; } elseif ($stringWrapperCharacter === $nextCharacter) { if (\substr(\end($selectorParts), -1) !== '\\') { From d766711a04e46fb5d69ca373a24e3e3307933736 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Sat, 28 Jun 2025 18:36:52 +0100 Subject: [PATCH 4/7] Assign to `null` rather than use `unset()` Co-authored-by: Oliver Klee --- src/RuleSet/DeclarationBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index f234c946..876e7ea0 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -53,7 +53,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? $stringWrapperCharacter = $nextCharacter; } elseif ($stringWrapperCharacter === $nextCharacter) { if (\substr(\end($selectorParts), -1) !== '\\') { - unset($stringWrapperCharacter); + $stringWrapperCharacter = null; } } break; From d4e79eff0ce29b27b50131a40f5204611435fb2f Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Sat, 28 Jun 2025 18:37:23 +0100 Subject: [PATCH 5/7] Use `is_string` rather than `isset` Co-authored-by: Oliver Klee --- src/RuleSet/DeclarationBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index 876e7ea0..790e07ce 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -58,7 +58,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? } break; } - } while (!\in_array($nextCharacter, ['{', '}'], true) || isset($stringWrapperCharacter)); + } while (!\in_array($nextCharacter, ['{', '}'], true) || \is_string($stringWrapperCharacter)); $result->setSelectors(\implode('', $selectorParts), $list); if ($parserState->comes('{')) { $parserState->consume(1); From dfeba4a9ea54c92edc44a7a35a193a66edecb3d6 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Sat, 28 Jun 2025 19:33:38 +0100 Subject: [PATCH 6/7] Initialize `$stringWrapperCharacter` --- src/RuleSet/DeclarationBlock.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RuleSet/DeclarationBlock.php b/src/RuleSet/DeclarationBlock.php index 790e07ce..5280e5a1 100644 --- a/src/RuleSet/DeclarationBlock.php +++ b/src/RuleSet/DeclarationBlock.php @@ -41,6 +41,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ? $result = new DeclarationBlock($parserState->currentLine()); try { $selectorParts = []; + $stringWrapperCharacter = null; do { $selectorParts[] = $parserState->consume(1) . $parserState->consumeUntil(['{', '}', '\'', '"'], false, false, $comments); From 5826c8b96dbfd7354a0c45ef0f7af8356656fe02 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Sat, 28 Jun 2025 19:35:07 +0100 Subject: [PATCH 7/7] Update PHPStan baseline with warning removed --- config/phpstan-baseline.neon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/phpstan-baseline.neon b/config/phpstan-baseline.neon index 9be2ebd7..8d882804 100644 --- a/config/phpstan-baseline.neon +++ b/config/phpstan-baseline.neon @@ -42,12 +42,6 @@ parameters: count: 1 path: ../src/Rule/Rule.php - - - message: '#^Loose comparison via "\!\=" is not allowed\.$#' - identifier: notEqual.notAllowed - count: 1 - path: ../src/RuleSet/DeclarationBlock.php - - message: '#^Parameters should have "string" types as the only types passed to this method$#' identifier: typePerfect.narrowPublicClassMethodParamType