Improve handling of invalid semicolons in the indented syntax (#330)

This improves the error message and fixes a bug where semicolons were
allowed after declarations.
This commit is contained in:
Natalie Weizenbaum 2018-05-24 19:15:56 -04:00 committed by GitHub
parent 7c26959156
commit 8007892075
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 7 deletions

View File

@ -1,5 +1,9 @@
## 1.4.0 ## 1.4.0
* Improve the error message for invalid semicolons in the indented syntax.
* Properly disallow semicolons after declarations in the indented syntax.
### Command-Line Interface ### Command-Line Interface
* Add support for compiling multiple files at once by writing * Add support for compiling multiple files at once by writing

View File

@ -54,17 +54,13 @@ class SassParser extends StylesheetParser {
} }
void expectStatementSeparator([String name]) { void expectStatementSeparator([String name]) {
if (!atEndOfStatement()) scanner.expectChar($lf); if (!atEndOfStatement()) _expectNewline();
if (_peekIndentation() <= currentIndentation) return; if (_peekIndentation() <= currentIndentation) return;
scanner.error( scanner.error(
"Nothing may be indented ${name == null ? 'here' : 'beneath a $name'}.", "Nothing may be indented ${name == null ? 'here' : 'beneath a $name'}.",
position: _nextIndentationEnd.position); position: _nextIndentationEnd.position);
} }
void expectSemicolon(String name) {
if (!atEndOfStatement()) scanner.expectChar($lf);
}
bool atEndOfStatement() { bool atEndOfStatement() {
var next = scanner.peekChar(); var next = scanner.peekChar();
return next == null || isNewline(next); return next == null || isNewline(next);
@ -295,6 +291,20 @@ class SassParser extends StylesheetParser {
} }
} }
/// Expect and consume a single newline character.
void _expectNewline() {
switch (scanner.peekChar()) {
case $semicolon:
scanner.error("semicolons aren't allowed in the indented syntax.");
return;
case $lf:
scanner.readChar();
return;
default:
scanner.error("expected newline.");
}
}
/// As long as the scanner's position is indented beneath the starting line, /// As long as the scanner's position is indented beneath the starting line,
/// runs [body] to consume the next statement. /// runs [body] to consume the next statement.
void _whileIndentedLower(void body()) { void _whileIndentedLower(void body()) {

View File

@ -304,12 +304,12 @@ abstract class StylesheetParser extends Parser {
// Properties that are ambiguous with selectors can't have additional // Properties that are ambiguous with selectors can't have additional
// properties nested beneath them, so we force an error. This will be // properties nested beneath them, so we force an error. This will be
// caught below and cause the text to be reparsed as a selector. // caught below and cause the text to be reparsed as a selector.
if (couldBeSelector) scanner.expectChar($semicolon); if (couldBeSelector) expectStatementSeparator();
} else if (!atEndOfStatement()) { } else if (!atEndOfStatement()) {
// Force an exception if there isn't a valid end-of-property character // Force an exception if there isn't a valid end-of-property character
// but don't consume that character. This will also cause the text to be // but don't consume that character. This will also cause the text to be
// reparsed. // reparsed.
scanner.expectChar($semicolon); expectStatementSeparator();
} }
} on FormatException catch (_) { } on FormatException catch (_) {
if (!couldBeSelector) rethrow; if (!couldBeSelector) rethrow;