Skip to content

Commit 3b2019a

Browse files
committed
Add support for % as a stand-alone expression
This also deprecates user-defined functions named "type". See #2539
1 parent 734e9de commit 3b2019a

File tree

9 files changed

+59
-12
lines changed

9 files changed

+59
-12
lines changed

CHANGELOG.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
## 1.85.2-dev
1+
## 1.86.0
2+
3+
* Add support for `%` as an expression in its own right. It will still be parsed
4+
as the modulo operator when between two other expressions, but in any other
5+
context it will be an expression whose value is the unquoted string `%`.
6+
7+
* Consider `attr()` to be a special number function that can be used as a
8+
channel in color functions.
9+
10+
* Deprecate user-defined functions named `type()` so that we can eventually
11+
support the new CSS `type()` function.
212

313
### Dart API
414

lib/src/deprecation.dart

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ enum Deprecation {
1515
// DO NOT EDIT. This section was generated from the language repo.
1616
// See tool/grind/generate_deprecations.dart for details.
1717
//
18-
// Checksum: 47c97f7824eb25d7f1e64e3230938b88330d40b4
18+
// Checksum: 3639e60773866019c018ae16267c8f23e4df86cf
1919

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

169+
/// Deprecation for functions named "type".
170+
typeFunction(
171+
'type-function',
172+
deprecatedIn: '1.86.0',
173+
description: 'Functions named "type".',
174+
),
175+
169176
// END AUTOGENERATED CODE
170177

171178
/// Used for deprecations coming from user-authored code.

lib/src/parse/stylesheet.dart

+30-4
Original file line numberDiff line numberDiff line change
@@ -923,11 +923,20 @@ abstract class StylesheetParser extends Parser {
923923
deprecation: Deprecation.cssFunctionMixin,
924924
message:
925925
'Sass @function names beginning with -- are deprecated for forward-'
926-
'compatibility with plain CSS mixins.\n'
926+
'compatibility with plain CSS functions.\n'
927927
'\n'
928928
'For details, see https://sass-lang.com/d/css-function-mixin',
929929
span: scanner.spanFrom(beforeName),
930930
));
931+
} else if (equalsIgnoreCase(name, 'type')) {
932+
warnings.add((
933+
deprecation: Deprecation.typeFunction,
934+
message: 'Sass @functions named "type" are deprecated for forward-'
935+
'compatibility with the plain CSS type() function.\n'
936+
'\n'
937+
'For details, see https://sass-lang.com/d/type-function',
938+
span: scanner.spanFrom(beforeName),
939+
));
931940
}
932941

933942
whitespace(consumeNewlines: true);
@@ -2079,7 +2088,6 @@ abstract class StylesheetParser extends Parser {
20792088
operators.last.precedence >= operator.precedence) {
20802089
resolveOneOperation();
20812090
}
2082-
operators.add(operator);
20832091

20842092
var singleExpression = singleExpression_;
20852093
if (singleExpression == null) {
@@ -2089,9 +2097,16 @@ abstract class StylesheetParser extends Parser {
20892097
length: operator.operator.length,
20902098
);
20912099
}
2092-
operands.add(singleExpression);
20932100
whitespace(consumeNewlines: true);
2094-
singleExpression_ = _singleExpression();
2101+
2102+
if (operator == BinaryOperator.modulo && !_lookingAtExpression()) {
2103+
addSingleExpression(StringExpression.plain(
2104+
'%', scanner.spanFromPosition(scanner.position - 1)));
2105+
} else {
2106+
operators.add(operator);
2107+
operands.add(singleExpression);
2108+
singleExpression_ = _singleExpression();
2109+
}
20952110
}
20962111

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

2572+
/// Consumes a `%` expression.
2573+
Expression _percentExpression() {
2574+
assert(scanner.peekChar() == $percent);
2575+
2576+
var start = scanner.state;
2577+
scanner.readChar();
2578+
return StringExpression.plain("%", scanner.spanFrom(start));
2579+
}
2580+
25562581
/// Consumes a unary operation expression.
25572582
UnaryOperationExpression _unaryOperation() {
25582583
var start = scanner.state;
@@ -3799,6 +3824,7 @@ abstract class StylesheetParser extends Parser {
37993824
$backslash ||
38003825
$dollar ||
38013826
$ampersand ||
3827+
$percent ||
38023828
int(isNameStart: true) ||
38033829
int(isDigit: true) =>
38043830
true,

lib/src/value/string.dart

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class SassString extends Value {
7171
if (text.length < "min(_)".length) return false;
7272

7373
return switch (text.codeUnitAt(0)) {
74+
$a || $A => equalsLetterIgnoreCase($t, text.codeUnitAt(1)) &&
75+
equalsLetterIgnoreCase($t, text.codeUnitAt(2)) &&
76+
equalsLetterIgnoreCase($r, text.codeUnitAt(3)) &&
77+
text.codeUnitAt(4) == $lparen,
7478
$c || $C => switch (text.codeUnitAt(1)) {
7579
$l || $L => equalsLetterIgnoreCase($a, text.codeUnitAt(2)) &&
7680
equalsLetterIgnoreCase($m, text.codeUnitAt(3)) &&

pkg/sass-parser/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## 0.4.16-dev
1+
## 0.4.16
22

33
* Use union types rather than base classes for Sass nodes wherever possible.
44
This makes it possible for TypeScript to automatically narrow node types based

pkg/sass-parser/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sass-parser",
3-
"version": "0.4.16-dev",
3+
"version": "0.4.16",
44
"description": "A PostCSS-compatible wrapper of the official Sass parser",
55
"repository": "sass/sass",
66
"author": "Google Inc.",

pkg/sass_api/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## 15.2.2-dev
1+
## 15.3.0
22

33
* No user-visible changes.
44

pkg/sass_api/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ name: sass_api
22
# Note: Every time we add a new Sass AST node, we need to bump the *major*
33
# version because it's a breaking change for anyone who's implementing the
44
# visitor interface(s).
5-
version: 15.2.2-dev
5+
version: 15.3.0
66
description: Additional APIs for Dart Sass.
77
homepage: https://github.com/sass/dart-sass
88

99
environment:
1010
sdk: ">=3.6.0 <4.0.0"
1111

1212
dependencies:
13-
sass: 1.85.2
13+
sass: 1.86.0
1414

1515
dev_dependencies:
1616
dartdoc: ^8.0.14

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass
2-
version: 1.85.2-dev
2+
version: 1.86.0
33
description: A Sass implementation in Dart.
44
homepage: https://github.com/sass/dart-sass
55

0 commit comments

Comments
 (0)