Skip to content

Commit e0e0dd3

Browse files
authored
[BUGFIX] Include comments for all rules in declaration block (#1169)
- `Rule::parse()` will no longer consume anything after the semicolon terminating the rule - it does not belong to that rule; - The whitespace and comments before a rule will be processed by `RuleSet::parseRuleSet()` and passed as a parameter to `Rule::parse()` - - This is only required while 'strict mode' parsing is an option, to avoid having an exception thrown during normal operation (i.e. when `Rule::parse()` encounters normal `}` as opposed to some other junk, which is not distinguished). Fixes #173. See also #672, #741.
1 parent b561b72 commit e0e0dd3

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Please also have a look at our
6666

6767
### Fixed
6868

69+
- Include comments for all rules in declaration block (#1169)
6970
- Render rules in line and column number order (#1059)
7071
- Don't render `rgb` colors with percentage values using hex notation (#803)
7172
- Parse `@font-face` `src` property as comma-delimited list (#790)

src/Rule/Rule.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,16 @@ public function __construct($rule, int $lineNumber = 0, $columnNumber = 0)
6868
}
6969

7070
/**
71+
* @param list<Comment> $commentsBeforeRule
72+
*
7173
* @throws UnexpectedEOFException
7274
* @throws UnexpectedTokenException
7375
*
7476
* @internal since V8.8.0
7577
*/
76-
public static function parse(ParserState $parserState): Rule
78+
public static function parse(ParserState $parserState, array $commentsBeforeRule = []): Rule
7779
{
78-
$comments = $parserState->consumeWhiteSpace();
80+
$comments = \array_merge($commentsBeforeRule, $parserState->consumeWhiteSpace());
7981
$rule = new Rule(
8082
$parserState->parseIdentifier(!$parserState->comes('--')),
8183
$parserState->currentLine(),
@@ -98,8 +100,6 @@ public static function parse(ParserState $parserState): Rule
98100
$parserState->consume(';');
99101
}
100102

101-
$parserState->consumeWhiteSpace();
102-
103103
return $rule;
104104
}
105105

src/RuleSet/RuleSet.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,15 @@ public static function parseRuleSet(ParserState $parserState, RuleSet $ruleSet):
6565
while ($parserState->comes(';')) {
6666
$parserState->consume(';');
6767
}
68-
while (!$parserState->comes('}')) {
68+
while (true) {
69+
$commentsBeforeRule = $parserState->consumeWhiteSpace();
70+
if ($parserState->comes('}')) {
71+
break;
72+
}
6973
$rule = null;
7074
if ($parserState->getSettings()->usesLenientParsing()) {
7175
try {
72-
$rule = Rule::parse($parserState);
76+
$rule = Rule::parse($parserState, $commentsBeforeRule);
7377
} catch (UnexpectedTokenException $e) {
7478
try {
7579
$consumedText = $parserState->consumeUntil(["\n", ';', '}'], true);
@@ -87,7 +91,7 @@ public static function parseRuleSet(ParserState $parserState, RuleSet $ruleSet):
8791
}
8892
}
8993
} else {
90-
$rule = Rule::parse($parserState);
94+
$rule = Rule::parse($parserState, $commentsBeforeRule);
9195
}
9296
if ($rule instanceof Rule) {
9397
$ruleSet->addRule($rule);

tests/ParserTest.php

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,26 +1091,62 @@ public function flatCommentExtractingOneComment(): void
10911091
{
10921092
$parser = new Parser('div {/*Find Me!*/left:10px; text-align:left;}');
10931093
$document = $parser->parse();
1094+
10941095
$contents = $document->getContents();
10951096
$divRules = $contents[0]->getRules();
10961097
$comments = $divRules[0]->getComments();
1098+
10971099
self::assertCount(1, $comments);
10981100
self::assertSame('Find Me!', $comments[0]->getComment());
10991101
}
11001102

11011103
/**
11021104
* @test
11031105
*/
1104-
public function flatCommentExtractingTwoComments(): void
1106+
public function flatCommentExtractingTwoConjoinedCommentsForOneRule(): void
11051107
{
1106-
self::markTestSkipped('This is currently broken.');
1108+
$parser = new Parser('div {/*Find Me!*//*Find Me Too!*/left:10px; text-align:left;}');
1109+
$document = $parser->parse();
1110+
1111+
$contents = $document->getContents();
1112+
$divRules = $contents[0]->getRules();
1113+
$comments = $divRules[0]->getComments();
11071114

1115+
self::assertCount(2, $comments);
1116+
self::assertSame('Find Me!', $comments[0]->getComment());
1117+
self::assertSame('Find Me Too!', $comments[1]->getComment());
1118+
}
1119+
1120+
/**
1121+
* @test
1122+
*/
1123+
public function flatCommentExtractingTwoSpaceSeparatedCommentsForOneRule(): void
1124+
{
1125+
$parser = new Parser('div { /*Find Me!*/ /*Find Me Too!*/ left:10px; text-align:left;}');
1126+
$document = $parser->parse();
1127+
1128+
$contents = $document->getContents();
1129+
$divRules = $contents[0]->getRules();
1130+
$comments = $divRules[0]->getComments();
1131+
1132+
self::assertCount(2, $comments);
1133+
self::assertSame('Find Me!', $comments[0]->getComment());
1134+
self::assertSame('Find Me Too!', $comments[1]->getComment());
1135+
}
1136+
1137+
/**
1138+
* @test
1139+
*/
1140+
public function flatCommentExtractingCommentsForTwoRules(): void
1141+
{
11081142
$parser = new Parser('div {/*Find Me!*/left:10px; /*Find Me Too!*/text-align:left;}');
11091143
$document = $parser->parse();
1144+
11101145
$contents = $document->getContents();
11111146
$divRules = $contents[0]->getRules();
11121147
$rule1Comments = $divRules[0]->getComments();
11131148
$rule2Comments = $divRules[1]->getComments();
1149+
11141150
self::assertCount(1, $rule1Comments);
11151151
self::assertCount(1, $rule2Comments);
11161152
self::assertSame('Find Me!', $rule1Comments[0]->getComment());

0 commit comments

Comments
 (0)