-
Notifications
You must be signed in to change notification settings - Fork 359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Indented syntax improvements] Dart implementation #2467
base: main
Are you sure you want to change the base?
Conversation
…d-syntax-improvements
…d-syntax-improvements
…d-syntax-improvements
@nex3 This is ready for review. Here are some questions I wanted to flag as you review. Thanks!
|
…d-syntax-improvements
…d-syntax-improvements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nex3 This is ready for review. Here are some questions I wanted to flag as you review. Thanks!
allowNewlines
is set totrue
in some cases, like in parser* functions or inscss.dart
, where the value is non-impactful. Should this usage be differentiated somehow for clarity?
For classes where it's universally non-impactful, I'd define a local _whitespace()
function that takes no arguments with a comment explaining that the value isn't relevant.
- There are some places, like in
_atRootQuery
, whereallowNewlines
is true because it is inside parentheses. I opted to not use the_inParentheses
variable except for one place where the consumption did rely on it, in_supportsCondition
. Would it be more idiomatic to use_inParentheses
, even if the consumption is in the same function?
I think how it is now is better.
- In the
+
include syntax, I am not supporting whitespace after the+
as it can be part of a selector. This differs from the=
mixin syntax- should they be the same?
There's already an odd inconsistency here where whitespace is allowed after =
but not after +
, so I think it's fine to expand that to allowing newlines as well. It's possible that we should deprecate that, but it's not in-scope for this change.
- I added paren/bracket context to
almostAnyValue
, with the only change being that they must be matched. That means the error fora:has(d[)]
will be changed from "Expected identifer" to "Expected]
". SincealmostAnyValue
is used for more than selectors, should I make this functionality opt-in, dependent on a parameter? Based on the places where this is used, I don't foresee issues with bracket matching, but want to verify.
It's fine to change this error. Arguably the bracket error is clearer anyway.
@@ -15,7 +15,7 @@ class KeyframeSelectorParser extends Parser { | |||
return wrapSpanFormatException(() { | |||
var selectors = <String>[]; | |||
do { | |||
whitespace(); | |||
whitespace(allowNewlines: false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to pass : false
here, since this is neither a super nor subclass of SassParser
.
@@ -67,23 +67,29 @@ class Parser { | |||
if (!scanner.scanChar($dollar)) return false; | |||
if (!lookingAtIdentifier()) return false; | |||
identifier(); | |||
whitespace(); | |||
whitespace(allowNewlines: false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter because this is only called from a static method, but in theory if this were used in the indented syntax I think we would want to allow newlines here because $foo\n
isn't a complete Sass statement.
return scanner.scanChar($colon); | ||
} | ||
|
||
// ## Tokens | ||
|
||
/// Consumes whitespace, including any comments. | ||
/// | ||
/// If [allowNewlines] is true, the indented syntax will consume newlines as | ||
/// whitespace, in positions when a statement can not end. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
/// whitespace, in positions when a statement can not end. | |
/// whitespace in positions when a statement can't end. |
Also below.
bool atEndOfStatement() { | ||
var next = scanner.peekChar(); | ||
return next.isNewline || | ||
next == null || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be less confusing to put next == null
first, even if next.isNewline
handles nulls gracefully.
var next = scanner.peekChar(); | ||
return next.isNewline || | ||
next == null || | ||
(next == $semicolon && scanner.peekChar(1).isNewline); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should treat ;
even without a newline as the end of a statement, and just let the parser throw an error when it encounters more text afterwards.
allowNewlines: allowNewlines || | ||
bracketList || | ||
_inParentheses || | ||
wasInExpression); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this trigger on wasInExpression
?
brackets.add(opposite(bracket)); | ||
|
||
case $rparen || $rbracket: | ||
if (brackets.isEmpty) break loop; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we're now explicitly parsing matching brackets here, it's probably best to throw a meaningful error here.
Note that this is technically a breaking change whether or not we throw an error here: [foo#{"]:is(bar"}) {x: y}
is currently valid, but will become an error here. I think it's vanishingly unlikely that anyone is doing that, though, so it should be fine to break, but we should add a "potentially breaking bug fix" note in the changelog about it.
@@ -2943,7 +2999,7 @@ abstract class StylesheetParser extends Parser { | |||
case $space || $tab: | |||
buffer.writeCharCode(scanner.readChar()); | |||
|
|||
case $lf || $cr || $ff when indented: | |||
case $lf || $cr || $ff when indented && !allowNewlines: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this also allow newlines when brackets
isn't empty?
var right = _supportsConditionInParens(); | ||
condition = SupportsOperation( | ||
condition, right, operator, scanner.spanFrom(start)); | ||
whitespace(); | ||
whitespace(allowNewlines: false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be : inParentheses
?
var start = scanner.state; | ||
if (scanIdentifier("not")) { | ||
whitespace(); | ||
whitespace(allowNewlines: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should only allow newlines here when inParentheses
is true, since we want to eventually treat @supports
like any other at-rule. Same below.
Blocked until proposal is accepted.
[skip sass-embedded]