Skip to content

Commit 6652001

Browse files
authored
Stop simplifying calculations in supports (#1653)
Fixes #1652. Also releases 1.49.10
1 parent 55157a5 commit 6652001

File tree

7 files changed

+74
-14
lines changed

7 files changed

+74
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
could be emitted as a hex color rather than a format with higher browser
2020
compatibility.
2121

22+
* Calculations are no longer simplified within supports declarations
23+
2224
## 1.49.9
2325

2426
### Embedded Sass

lib/src/value/calculation.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ class SassCalculation extends Value {
3535
@internal
3636
bool get isSpecialNumber => true;
3737

38+
/// Creates a new calculation with the given [name] and [arguments]
39+
/// that will not be simplified.
40+
@internal
41+
static Value unsimplified(String name, Iterable<Object> arguments) {
42+
return SassCalculation._(name, List.unmodifiable(arguments));
43+
}
44+
3845
/// Creates a `calc()` calculation with the given [argument].
3946
///
4047
/// The [argument] must be either a [SassNumber], a [SassCalculation], an
@@ -162,17 +169,22 @@ class SassCalculation extends Value {
162169
/// a [CalculationInterpolation].
163170
static Object operate(
164171
CalculationOperator operator, Object left, Object right) =>
165-
operateInternal(operator, left, right, inMinMax: false);
172+
operateInternal(operator, left, right, inMinMax: false, simplify: true);
166173

167174
/// Like [operate], but with the internal-only [inMinMax] parameter.
168175
///
169176
/// If [inMinMax] is `true`, this allows unitless numbers to be added and
170177
/// subtracted with numbers with units, for backwards-compatibility with the
171178
/// old global `min()` and `max()` functions.
179+
///
180+
/// If [simplify] is `false`, no simplification will be done.
172181
@internal
173182
static Object operateInternal(
174183
CalculationOperator operator, Object left, Object right,
175-
{required bool inMinMax}) {
184+
{required bool inMinMax, required bool simplify}) {
185+
if (!simplify) {
186+
return CalculationOperation._(operator, left, right);
187+
}
176188
left = _simplify(left);
177189
right = _simplify(right);
178190

lib/src/visitor/async_evaluate.dart

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ class _EvaluateVisitor
219219
/// Whether we're currently building the output of a `@keyframes` rule.
220220
var _inKeyframes = false;
221221

222+
/// Whether we're currently evaluating a [SupportsDeclaration].
223+
///
224+
/// When this is true, calculations will not be simplified.
225+
var _inSupportsDeclaration = false;
226+
222227
/// The canonical URLs of all stylesheets loaded during compilation.
223228
final _loadedUrls = <Uri>{};
224229

@@ -1949,9 +1954,13 @@ class _EvaluateVisitor
19491954
} else if (condition is SupportsInterpolation) {
19501955
return await _evaluateToCss(condition.expression, quote: false);
19511956
} else if (condition is SupportsDeclaration) {
1952-
return "(${await _evaluateToCss(condition.name)}:"
1957+
var oldInSupportsDeclaration = _inSupportsDeclaration;
1958+
_inSupportsDeclaration = true;
1959+
var result = "(${await _evaluateToCss(condition.name)}:"
19531960
"${condition.isCustomProperty ? '' : ' '}"
19541961
"${await _evaluateToCss(condition.value)})";
1962+
_inSupportsDeclaration = oldInSupportsDeclaration;
1963+
return result;
19551964
} else if (condition is SupportsFunction) {
19561965
return "${await _performInterpolation(condition.name)}("
19571966
"${await _performInterpolation(condition.arguments)})";
@@ -2227,6 +2236,9 @@ class _EvaluateVisitor
22272236
await _visitCalculationValue(argument,
22282237
inMinMax: node.name == 'min' || node.name == 'max')
22292238
];
2239+
if (_inSupportsDeclaration) {
2240+
return SassCalculation.unsimplified(node.name, arguments);
2241+
}
22302242

22312243
try {
22322244
switch (node.name) {
@@ -2317,7 +2329,8 @@ class _EvaluateVisitor
23172329
_binaryOperatorToCalculationOperator(node.operator),
23182330
await _visitCalculationValue(node.left, inMinMax: inMinMax),
23192331
await _visitCalculationValue(node.right, inMinMax: inMinMax),
2320-
inMinMax: inMinMax));
2332+
inMinMax: inMinMax,
2333+
simplify: !_inSupportsDeclaration));
23212334
} else {
23222335
assert(node is NumberExpression ||
23232336
node is CalculationExpression ||
@@ -2823,7 +2836,9 @@ class _EvaluateVisitor
28232836
Future<SassString> visitStringExpression(StringExpression node) async {
28242837
// Don't use [performInterpolation] here because we need to get the raw text
28252838
// from strings, rather than the semantic value.
2826-
return SassString(
2839+
var oldInSupportsDeclaration = _inSupportsDeclaration;
2840+
_inSupportsDeclaration = false;
2841+
var result = SassString(
28272842
(await mapAsync(node.text.contents, (value) async {
28282843
if (value is String) return value;
28292844
var expression = value as Expression;
@@ -2834,6 +2849,8 @@ class _EvaluateVisitor
28342849
}))
28352850
.join(),
28362851
quotes: node.hasQuotes);
2852+
_inSupportsDeclaration = oldInSupportsDeclaration;
2853+
return result;
28372854
}
28382855

28392856
// ## Plain CSS
@@ -3088,7 +3105,9 @@ class _EvaluateVisitor
30883105
/// values passed into the interpolation.
30893106
Future<String> _performInterpolation(Interpolation interpolation,
30903107
{bool warnForColor = false}) async {
3091-
return (await mapAsync(interpolation.contents, (value) async {
3108+
var oldInSupportsDeclaration = _inSupportsDeclaration;
3109+
_inSupportsDeclaration = false;
3110+
var result = (await mapAsync(interpolation.contents, (value) async {
30923111
if (value is String) return value;
30933112
var expression = value as Expression;
30943113
var result = await expression.accept(this);
@@ -3115,6 +3134,8 @@ class _EvaluateVisitor
31153134
return _serialize(result, expression, quote: false);
31163135
}))
31173136
.join();
3137+
_inSupportsDeclaration = oldInSupportsDeclaration;
3138+
return result;
31183139
}
31193140

31203141
/// Evaluates [expression] and calls `toCssString()` and wraps a

lib/src/visitor/evaluate.dart

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: f11bdd289c888e0e0737bc96e63283bc8a332d9a
8+
// Checksum: 45277707f5ab21408f3abb8f249ed7115e0a3c0f
99
//
1010
// ignore_for_file: unused_import
1111

@@ -227,6 +227,11 @@ class _EvaluateVisitor
227227
/// Whether we're currently building the output of a `@keyframes` rule.
228228
var _inKeyframes = false;
229229

230+
/// Whether we're currently evaluating a [SupportsDeclaration].
231+
///
232+
/// When this is true, calculations will not be simplified.
233+
var _inSupportsDeclaration = false;
234+
230235
/// The canonical URLs of all stylesheets loaded during compilation.
231236
final _loadedUrls = <Uri>{};
232237

@@ -1942,9 +1947,13 @@ class _EvaluateVisitor
19421947
} else if (condition is SupportsInterpolation) {
19431948
return _evaluateToCss(condition.expression, quote: false);
19441949
} else if (condition is SupportsDeclaration) {
1945-
return "(${_evaluateToCss(condition.name)}:"
1950+
var oldInSupportsDeclaration = _inSupportsDeclaration;
1951+
_inSupportsDeclaration = true;
1952+
var result = "(${_evaluateToCss(condition.name)}:"
19461953
"${condition.isCustomProperty ? '' : ' '}"
19471954
"${_evaluateToCss(condition.value)})";
1955+
_inSupportsDeclaration = oldInSupportsDeclaration;
1956+
return result;
19481957
} else if (condition is SupportsFunction) {
19491958
return "${_performInterpolation(condition.name)}("
19501959
"${_performInterpolation(condition.arguments)})";
@@ -2216,6 +2225,9 @@ class _EvaluateVisitor
22162225
_visitCalculationValue(argument,
22172226
inMinMax: node.name == 'min' || node.name == 'max')
22182227
];
2228+
if (_inSupportsDeclaration) {
2229+
return SassCalculation.unsimplified(node.name, arguments);
2230+
}
22192231

22202232
try {
22212233
switch (node.name) {
@@ -2305,7 +2317,8 @@ class _EvaluateVisitor
23052317
_binaryOperatorToCalculationOperator(node.operator),
23062318
_visitCalculationValue(node.left, inMinMax: inMinMax),
23072319
_visitCalculationValue(node.right, inMinMax: inMinMax),
2308-
inMinMax: inMinMax));
2320+
inMinMax: inMinMax,
2321+
simplify: !_inSupportsDeclaration));
23092322
} else {
23102323
assert(node is NumberExpression ||
23112324
node is CalculationExpression ||
@@ -2804,7 +2817,9 @@ class _EvaluateVisitor
28042817
SassString visitStringExpression(StringExpression node) {
28052818
// Don't use [performInterpolation] here because we need to get the raw text
28062819
// from strings, rather than the semantic value.
2807-
return SassString(
2820+
var oldInSupportsDeclaration = _inSupportsDeclaration;
2821+
_inSupportsDeclaration = false;
2822+
var result = SassString(
28082823
node.text.contents.map((value) {
28092824
if (value is String) return value;
28102825
var expression = value as Expression;
@@ -2814,6 +2829,8 @@ class _EvaluateVisitor
28142829
: _serialize(result, expression, quote: false);
28152830
}).join(),
28162831
quotes: node.hasQuotes);
2832+
_inSupportsDeclaration = oldInSupportsDeclaration;
2833+
return result;
28172834
}
28182835

28192836
// ## Plain CSS
@@ -3064,7 +3081,9 @@ class _EvaluateVisitor
30643081
/// values passed into the interpolation.
30653082
String _performInterpolation(Interpolation interpolation,
30663083
{bool warnForColor = false}) {
3067-
return interpolation.contents.map((value) {
3084+
var oldInSupportsDeclaration = _inSupportsDeclaration;
3085+
_inSupportsDeclaration = false;
3086+
var result = interpolation.contents.map((value) {
30683087
if (value is String) return value;
30693088
var expression = value as Expression;
30703089
var result = expression.accept(this);
@@ -3090,6 +3109,8 @@ class _EvaluateVisitor
30903109

30913110
return _serialize(result, expression, quote: false);
30923111
}).join();
3112+
_inSupportsDeclaration = oldInSupportsDeclaration;
3113+
return result;
30933114
}
30943115

30953116
/// Evaluates [expression] and calls `toCssString()` and wraps a

pkg/sass_api/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.0-beta.39
2+
3+
* No user-visible changes.
4+
15
## 1.0.0-beta.38
26

37
* No user-visible changes.

pkg/sass_api/pubspec.yaml

Lines changed: 2 additions & 2 deletions
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: 1.0.0-beta.38
5+
version: 1.0.0-beta.39
66
description: Additional APIs for Dart Sass.
77
homepage: https://github.com/sass/dart-sass
88

99
environment:
1010
sdk: '>=2.12.0 <3.0.0'
1111

1212
dependencies:
13-
sass: 1.49.9
13+
sass: 1.49.10
1414

1515
dependency_overrides:
1616
sass: {path: ../..}

pubspec.yaml

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

0 commit comments

Comments
 (0)