Properly parse multi-line selectors in the indented syntax (#243)

Closes #235
Closes #237
This commit is contained in:
Natalie Weizenbaum 2018-03-02 17:49:57 -08:00 committed by GitHub
parent b7d4384a5c
commit aba4ab1421
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 14 deletions

View File

@ -2,18 +2,21 @@
* Support hard tabs in the indented syntax.
* Don't deadlock on `/*` comments in the indented syntax.
* Don't add an extra `*/` to comments in the indented syntax that already have
it.
* Improve the formatting of comments that don't start on the same line as the
opening `/*`.
* Preserve empty lines in `/*` comments in the indented syntax.
* Preserve whitespace after `and` in media queries in compressed mode.
### Indented Syntax
* Properly parse multi-line selectors.
* Don't deadlock on `/*` comments.
* Don't add an extra `*/` to comments that already have it.
* Preserve empty lines in `/*` comments.
## 1.0.0-beta.5.2
* Fix a bug where some colors would crash `compressed` mode.

View File

@ -39,6 +39,19 @@ class SassParser extends StylesheetParser {
SassParser(String contents, {url, bool color: false})
: super(contents, url: url, color: color);
Interpolation styleRuleSelector() {
var start = scanner.state;
var buffer = new InterpolationBuffer();
do {
buffer.addInterpolation(almostAnyValue());
buffer.writeCharCode($lf);
} while (buffer.trailingString.trimRight().endsWith(",") &&
scanCharIf(isNewline));
return buffer.interpolation(scanner.spanFrom(start));
}
void expectStatementSeparator([String name]) {
if (!atEndOfStatement()) scanner.expectChar($lf);
if (_peekIndentation() <= currentIndentation) return;

View File

@ -17,6 +17,8 @@ class ScssParser extends StylesheetParser {
ScssParser(String contents, {url, bool color: false})
: super(contents, url: url, color: color);
Interpolation styleRuleSelector() => almostAnyValue();
void expectStatementSeparator([String name]) {
whitespaceWithoutComments();
if (scanner.isDone) return;

View File

@ -173,7 +173,7 @@ abstract class StylesheetParser extends Parser {
if (indented) scanner.scanChar($backslash);
var start = scanner.state;
var selector = _almostAnyValue();
var selector = styleRuleSelector();
var children = this.children(_statement);
var rule = new StyleRule(selector, children, scanner.spanFrom(start));
_inStyleRule = wasInStyleRule;
@ -218,7 +218,7 @@ abstract class StylesheetParser extends Parser {
if (declarationOrBuffer is Declaration) return declarationOrBuffer;
var buffer = declarationOrBuffer as InterpolationBuffer;
buffer.addInterpolation(_almostAnyValue());
buffer.addInterpolation(styleRuleSelector());
var selectorSpan = scanner.spanFrom(start);
var wasInStyleRule = _inStyleRule;
@ -320,7 +320,7 @@ abstract class StylesheetParser extends Parser {
// If the value would be followed by a semicolon, it's definitely supposed
// to be a property, not a selector.
scanner.state = beforeDeclaration;
var additional = _almostAnyValue();
var additional = almostAnyValue();
if (!indented && scanner.peekChar() == $semicolon) rethrow;
nameBuffer.write(midBuffer);
@ -593,7 +593,7 @@ abstract class StylesheetParser extends Parser {
position: start.position, length: "@extend".length);
}
var value = _almostAnyValue();
var value = almostAnyValue();
var optional = scanner.scanChar($exclamation);
if (optional) expectIdentifier("optional");
expectStatementSeparator("@extend rule");
@ -983,7 +983,7 @@ abstract class StylesheetParser extends Parser {
Interpolation value;
var next = scanner.peekChar();
if (next != $exclamation && !atEndOfStatement()) value = _almostAnyValue();
if (next != $exclamation && !atEndOfStatement()) value = almostAnyValue();
var children = lookingAtChildren() ? this.children(_statement) : null;
if (children == null) expectStatementSeparator();
@ -1000,7 +1000,7 @@ abstract class StylesheetParser extends Parser {
/// This declares a return type of [Statement] so that it can be returned
/// within case statements.
Statement _disallowedAtRule(LineScannerState start) {
_almostAnyValue();
almostAnyValue();
scanner.error("This at-rule is not allowed here.",
position: start.position,
length: scanner.state.position - start.position);
@ -2228,7 +2228,8 @@ abstract class StylesheetParser extends Parser {
/// * This supports Sass-style single-line comments.
///
/// * This does not compress adjacent whitespace characters.
Interpolation _almostAnyValue() {
@protected
Interpolation almostAnyValue() {
var start = scanner.state;
var buffer = new InterpolationBuffer();
@ -2747,6 +2748,10 @@ abstract class StylesheetParser extends Parser {
@protected
int get currentIndentation;
/// Parses and returns a selector used in a style rule.
@protected
Interpolation styleRuleSelector();
/// Asserts that the scanner is positioned before a statement separator, or at
/// the end of a list of statements.
///