Skip to content

Commit 26ac2f2

Browse files
committed
[CLEANUP] Extract method DeclarationBlock::parseSelector
Closes #1324
1 parent 8d123a2 commit 26ac2f2

File tree

3 files changed

+57
-17
lines changed

3 files changed

+57
-17
lines changed

src/Parsing/ParserState.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,27 @@ public function consume($value = 1): string
279279
return $result;
280280
}
281281

282+
/**
283+
* If the possibly-expected next content is next, consume it.
284+
*
285+
* @param non-empty-string $nextContent
286+
*
287+
* @return bool whether the possibly-expected content was found and consumed
288+
*/
289+
public function consumeIfComes(string $nextContent): bool
290+
{
291+
$length = $this->strlen($nextContent);
292+
if (!$this->streql($this->substr($this->currentPosition, $length), $nextContent)) {
293+
return false;
294+
}
295+
296+
$numberOfLines = \substr_count($nextContent, "\n");
297+
$this->lineNumber += $numberOfLines;
298+
$this->currentPosition += $this->strlen($nextContent);
299+
300+
return true;
301+
}
302+
282303
/**
283304
* @param string $expression
284305
* @param int<1, max>|null $maximumLength
@@ -343,6 +364,10 @@ public function consumeUntil(
343364
$consumedCharacters = '';
344365
$start = $this->currentPosition;
345366

367+
$comment = $this->consumeComment();
368+
if ($comment instanceof Comment) {
369+
$comments[] = $comment;
370+
}
346371
while (!$this->isEnd()) {
347372
$character = $this->consume(1);
348373
if (\in_array($character, $stopCharacters, true)) {

src/RuleSet/DeclarationBlock.php

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -283,19 +283,33 @@ public function render(OutputFormat $outputFormat): string
283283
private static function parseSelectors(ParserState $parserState, array &$comments = []): array
284284
{
285285
$selectors = [];
286+
287+
while (true) {
288+
$selectors[] = self::parseSelector($parserState, $comments);
289+
if (!$parserState->consumeIfComes(',')) {
290+
break;
291+
}
292+
}
293+
294+
return $selectors;
295+
}
296+
297+
/**
298+
* @param list<Comment> $comments
299+
*
300+
* @throws UnexpectedTokenException
301+
*/
302+
private static function parseSelector(ParserState $parserState, array &$comments = []): string
303+
{
286304
$selectorParts = [];
287305
$stringWrapperCharacter = null;
288306
$functionNestingLevel = 0;
289-
$consumedNextCharacter = false;
290307
static $stopCharacters = ['{', '}', '\'', '"', '(', ')', ','];
291308

292-
do {
293-
if (!$consumedNextCharacter) {
294-
$selectorParts[] = $parserState->consume(1);
295-
}
309+
while (true) {
310+
$selectorParts[] = $parserState->consume(1);
296311
$selectorParts[] = $parserState->consumeUntil($stopCharacters, false, false, $comments);
297312
$nextCharacter = $parserState->peek();
298-
$consumedNextCharacter = false;
299313
switch ($nextCharacter) {
300314
case '\'':
301315
// The fallthrough is intentional.
@@ -321,22 +335,24 @@ private static function parseSelectors(ParserState $parserState, array &$comment
321335
--$functionNestingLevel;
322336
}
323337
break;
338+
case '{':
339+
case '}':
340+
if (!\is_string($stringWrapperCharacter)) {
341+
break 2;
342+
}
343+
break;
324344
case ',':
325345
if (!\is_string($stringWrapperCharacter) && $functionNestingLevel === 0) {
326-
$selectors[] = \implode('', $selectorParts);
327-
$selectorParts = [];
328-
$parserState->consume(1);
329-
$consumedNextCharacter = true;
346+
break 2;
330347
}
331348
break;
332349
}
333-
} while (!\in_array($nextCharacter, ['{', '}'], true) || \is_string($stringWrapperCharacter));
350+
}
334351

335352
if ($functionNestingLevel !== 0) {
336353
throw new UnexpectedTokenException(')', $nextCharacter);
337354
}
338-
$selectors[] = \implode('', $selectorParts); // add final or only selector
339355

340-
return $selectors;
356+
return \implode('', $selectorParts);
341357
}
342358
}

tests/ParserTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,10 +1048,9 @@ public function commentExtracting(): void
10481048
$fooBarBlock = $nodes[1];
10491049
self::assertInstanceOf(Commentable::class, $fooBarBlock);
10501050
$fooBarBlockComments = $fooBarBlock->getComments();
1051-
// TODO Support comments in selectors.
1052-
// $this->assertCount(2, $fooBarBlockComments);
1053-
// $this->assertSame("* Number 4 *", $fooBarBlockComments[0]->getComment());
1054-
// $this->assertSame("* Number 5 *", $fooBarBlockComments[1]->getComment());
1051+
self::assertCount(2, $fooBarBlockComments);
1052+
self::assertSame(' Number 4 ', $fooBarBlockComments[0]->getComment());
1053+
self::assertSame(' Number 5 ', $fooBarBlockComments[1]->getComment());
10551054

10561055
// Declaration rules.
10571056
self::assertInstanceOf(DeclarationBlock::class, $fooBarBlock);

0 commit comments

Comments
 (0)