Skip to content
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

Add support for % as a stand-alone expression #2540

Merged
merged 1 commit into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
## 1.85.2-dev
## 1.86.0

* Add support for `%` as an expression in its own right. It will still be parsed
as the modulo operator when between two other expressions, but in any other
context it will be an expression whose value is the unquoted string `%`.

* Consider `attr()` to be a special number function that can be used as a
channel in color functions.

* Deprecate user-defined functions named `type()` so that we can eventually
support the new CSS `type()` function.

### Dart API

Expand Down
9 changes: 8 additions & 1 deletion lib/src/deprecation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ enum Deprecation {
// DO NOT EDIT. This section was generated from the language repo.
// See tool/grind/generate_deprecations.dart for details.
//
// Checksum: 47c97f7824eb25d7f1e64e3230938b88330d40b4
// Checksum: 3639e60773866019c018ae16267c8f23e4df86cf

/// Deprecation for passing a string directly to meta.call().
callString(
Expand Down Expand Up @@ -166,6 +166,13 @@ enum Deprecation {
'Global built-in functions that are available in sass: modules.',
),

/// Deprecation for functions named "type".
typeFunction(
'type-function',
deprecatedIn: '1.86.0',
description: 'Functions named "type".',
),

Comment on lines +169 to +175
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

off-topic: for whatever reason when I generate the deprecations I end up getting a different formatting, like:

  typeFunction('type-function', deprecatedIn: '1.86.0',
    description: 'Functions named "type".'),

do you happen to know what that would be? this is when running dart run grinder... I guess I may have some config file somewhere that tells dart to behave this way 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw something similar and I couldn't figure out exactly what it was. The Dart formatter is in the process of rolling out new changes so it's probably something related to that, but I don't know what exactly. I suspect making the generator add a trailing comma would force it to behave the same way for both the old and new formatter logic, though.

// END AUTOGENERATED CODE

/// Used for deprecations coming from user-authored code.
Expand Down
34 changes: 30 additions & 4 deletions lib/src/parse/stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -923,11 +923,20 @@ abstract class StylesheetParser extends Parser {
deprecation: Deprecation.cssFunctionMixin,
message:
'Sass @function names beginning with -- are deprecated for forward-'
'compatibility with plain CSS mixins.\n'
'compatibility with plain CSS functions.\n'
'\n'
'For details, see https://sass-lang.com/d/css-function-mixin',
span: scanner.spanFrom(beforeName),
));
} else if (equalsIgnoreCase(name, 'type')) {
warnings.add((
deprecation: Deprecation.typeFunction,
message: 'Sass @functions named "type" are deprecated for forward-'
'compatibility with the plain CSS type() function.\n'
'\n'
'For details, see https://sass-lang.com/d/type-function',
span: scanner.spanFrom(beforeName),
));
}

whitespace(consumeNewlines: true);
Expand Down Expand Up @@ -2079,7 +2088,6 @@ abstract class StylesheetParser extends Parser {
operators.last.precedence >= operator.precedence) {
resolveOneOperation();
}
operators.add(operator);

var singleExpression = singleExpression_;
if (singleExpression == null) {
Expand All @@ -2089,9 +2097,16 @@ abstract class StylesheetParser extends Parser {
length: operator.operator.length,
);
}
operands.add(singleExpression);
whitespace(consumeNewlines: true);
singleExpression_ = _singleExpression();

if (operator == BinaryOperator.modulo && !_lookingAtExpression()) {
addSingleExpression(StringExpression.plain(
'%', scanner.spanFromPosition(scanner.position - 1)));
} else {
operators.add(operator);
operands.add(singleExpression);
singleExpression_ = _singleExpression();
}
}

void resolveSpaceExpressions() {
Expand Down Expand Up @@ -2353,6 +2368,7 @@ abstract class StylesheetParser extends Parser {
$plus => _plusExpression(),
$minus => _minusExpression(),
$exclamation => _importantExpression(),
$percent => _percentExpression(),
// dart-lang/sdk#52740
// ignore: non_constant_relational_pattern_expression
$u || $U when scanner.peekChar(1) == $plus => _unicodeRange(),
Expand Down Expand Up @@ -2553,6 +2569,15 @@ abstract class StylesheetParser extends Parser {
return StringExpression.plain("!important", scanner.spanFrom(start));
}

/// Consumes a `%` expression.
Expression _percentExpression() {
assert(scanner.peekChar() == $percent);

var start = scanner.state;
scanner.readChar();
return StringExpression.plain("%", scanner.spanFrom(start));
}

/// Consumes a unary operation expression.
UnaryOperationExpression _unaryOperation() {
var start = scanner.state;
Expand Down Expand Up @@ -3799,6 +3824,7 @@ abstract class StylesheetParser extends Parser {
$backslash ||
$dollar ||
$ampersand ||
$percent ||
int(isNameStart: true) ||
int(isDigit: true) =>
true,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/value/string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class SassString extends Value {
if (text.length < "min(_)".length) return false;

return switch (text.codeUnitAt(0)) {
$a || $A => equalsLetterIgnoreCase($t, text.codeUnitAt(1)) &&
equalsLetterIgnoreCase($t, text.codeUnitAt(2)) &&
equalsLetterIgnoreCase($r, text.codeUnitAt(3)) &&
text.codeUnitAt(4) == $lparen,
$c || $C => switch (text.codeUnitAt(1)) {
$l || $L => equalsLetterIgnoreCase($a, text.codeUnitAt(2)) &&
equalsLetterIgnoreCase($m, text.codeUnitAt(3)) &&
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 0.4.16-dev
## 0.4.16

* Use union types rather than base classes for Sass nodes wherever possible.
This makes it possible for TypeScript to automatically narrow node types based
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass-parser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sass-parser",
"version": "0.4.16-dev",
"version": "0.4.16",
"description": "A PostCSS-compatible wrapper of the official Sass parser",
"repository": "sass/sass",
"author": "Google Inc.",
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass_api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 15.2.2-dev
## 15.3.0

* No user-visible changes.

Expand Down
4 changes: 2 additions & 2 deletions pkg/sass_api/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ name: sass_api
# Note: Every time we add a new Sass AST node, we need to bump the *major*
# version because it's a breaking change for anyone who's implementing the
# visitor interface(s).
version: 15.2.2-dev
version: 15.3.0
description: Additional APIs for Dart Sass.
homepage: https://github.com/sass/dart-sass

environment:
sdk: ">=3.6.0 <4.0.0"

dependencies:
sass: 1.85.2
sass: 1.86.0

dev_dependencies:
dartdoc: ^8.0.14
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: sass
version: 1.85.2-dev
version: 1.86.0
description: A Sass implementation in Dart.
homepage: https://github.com/sass/dart-sass

Expand Down