Skip to content

Commit

Permalink
Stop simplifying calculations in supports (#1653)
Browse files Browse the repository at this point in the history
Fixes #1652.

Also releases 1.49.10
  • Loading branch information
jathak committed Mar 30, 2022
1 parent 55157a5 commit 6652001
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -19,6 +19,8 @@
could be emitted as a hex color rather than a format with higher browser
compatibility.

* Calculations are no longer simplified within supports declarations

## 1.49.9

### Embedded Sass
Expand Down
16 changes: 14 additions & 2 deletions lib/src/value/calculation.dart
Expand Up @@ -35,6 +35,13 @@ class SassCalculation extends Value {
@internal
bool get isSpecialNumber => true;

/// Creates a new calculation with the given [name] and [arguments]
/// that will not be simplified.
@internal
static Value unsimplified(String name, Iterable<Object> arguments) {
return SassCalculation._(name, List.unmodifiable(arguments));
}

/// Creates a `calc()` calculation with the given [argument].
///
/// The [argument] must be either a [SassNumber], a [SassCalculation], an
Expand Down Expand Up @@ -162,17 +169,22 @@ class SassCalculation extends Value {
/// a [CalculationInterpolation].
static Object operate(
CalculationOperator operator, Object left, Object right) =>
operateInternal(operator, left, right, inMinMax: false);
operateInternal(operator, left, right, inMinMax: false, simplify: true);

/// Like [operate], but with the internal-only [inMinMax] parameter.
///
/// If [inMinMax] is `true`, this allows unitless numbers to be added and
/// subtracted with numbers with units, for backwards-compatibility with the
/// old global `min()` and `max()` functions.
///
/// If [simplify] is `false`, no simplification will be done.
@internal
static Object operateInternal(
CalculationOperator operator, Object left, Object right,
{required bool inMinMax}) {
{required bool inMinMax, required bool simplify}) {
if (!simplify) {
return CalculationOperation._(operator, left, right);
}
left = _simplify(left);
right = _simplify(right);

Expand Down
29 changes: 25 additions & 4 deletions lib/src/visitor/async_evaluate.dart
Expand Up @@ -219,6 +219,11 @@ class _EvaluateVisitor
/// Whether we're currently building the output of a `@keyframes` rule.
var _inKeyframes = false;

/// Whether we're currently evaluating a [SupportsDeclaration].
///
/// When this is true, calculations will not be simplified.
var _inSupportsDeclaration = false;

/// The canonical URLs of all stylesheets loaded during compilation.
final _loadedUrls = <Uri>{};

Expand Down Expand Up @@ -1949,9 +1954,13 @@ class _EvaluateVisitor
} else if (condition is SupportsInterpolation) {
return await _evaluateToCss(condition.expression, quote: false);
} else if (condition is SupportsDeclaration) {
return "(${await _evaluateToCss(condition.name)}:"
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = true;
var result = "(${await _evaluateToCss(condition.name)}:"
"${condition.isCustomProperty ? '' : ' '}"
"${await _evaluateToCss(condition.value)})";
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
} else if (condition is SupportsFunction) {
return "${await _performInterpolation(condition.name)}("
"${await _performInterpolation(condition.arguments)})";
Expand Down Expand Up @@ -2227,6 +2236,9 @@ class _EvaluateVisitor
await _visitCalculationValue(argument,
inMinMax: node.name == 'min' || node.name == 'max')
];
if (_inSupportsDeclaration) {
return SassCalculation.unsimplified(node.name, arguments);
}

try {
switch (node.name) {
Expand Down Expand Up @@ -2317,7 +2329,8 @@ class _EvaluateVisitor
_binaryOperatorToCalculationOperator(node.operator),
await _visitCalculationValue(node.left, inMinMax: inMinMax),
await _visitCalculationValue(node.right, inMinMax: inMinMax),
inMinMax: inMinMax));
inMinMax: inMinMax,
simplify: !_inSupportsDeclaration));
} else {
assert(node is NumberExpression ||
node is CalculationExpression ||
Expand Down Expand Up @@ -2823,7 +2836,9 @@ class _EvaluateVisitor
Future<SassString> visitStringExpression(StringExpression node) async {
// Don't use [performInterpolation] here because we need to get the raw text
// from strings, rather than the semantic value.
return SassString(
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = false;
var result = SassString(
(await mapAsync(node.text.contents, (value) async {
if (value is String) return value;
var expression = value as Expression;
Expand All @@ -2834,6 +2849,8 @@ class _EvaluateVisitor
}))
.join(),
quotes: node.hasQuotes);
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
}

// ## Plain CSS
Expand Down Expand Up @@ -3088,7 +3105,9 @@ class _EvaluateVisitor
/// values passed into the interpolation.
Future<String> _performInterpolation(Interpolation interpolation,
{bool warnForColor = false}) async {
return (await mapAsync(interpolation.contents, (value) async {
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = false;
var result = (await mapAsync(interpolation.contents, (value) async {
if (value is String) return value;
var expression = value as Expression;
var result = await expression.accept(this);
Expand All @@ -3115,6 +3134,8 @@ class _EvaluateVisitor
return _serialize(result, expression, quote: false);
}))
.join();
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
}

/// Evaluates [expression] and calls `toCssString()` and wraps a
Expand Down
31 changes: 26 additions & 5 deletions lib/src/visitor/evaluate.dart
Expand Up @@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_evaluate.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: f11bdd289c888e0e0737bc96e63283bc8a332d9a
// Checksum: 45277707f5ab21408f3abb8f249ed7115e0a3c0f
//
// ignore_for_file: unused_import

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

/// Whether we're currently evaluating a [SupportsDeclaration].
///
/// When this is true, calculations will not be simplified.
var _inSupportsDeclaration = false;

/// The canonical URLs of all stylesheets loaded during compilation.
final _loadedUrls = <Uri>{};

Expand Down Expand Up @@ -1942,9 +1947,13 @@ class _EvaluateVisitor
} else if (condition is SupportsInterpolation) {
return _evaluateToCss(condition.expression, quote: false);
} else if (condition is SupportsDeclaration) {
return "(${_evaluateToCss(condition.name)}:"
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = true;
var result = "(${_evaluateToCss(condition.name)}:"
"${condition.isCustomProperty ? '' : ' '}"
"${_evaluateToCss(condition.value)})";
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
} else if (condition is SupportsFunction) {
return "${_performInterpolation(condition.name)}("
"${_performInterpolation(condition.arguments)})";
Expand Down Expand Up @@ -2216,6 +2225,9 @@ class _EvaluateVisitor
_visitCalculationValue(argument,
inMinMax: node.name == 'min' || node.name == 'max')
];
if (_inSupportsDeclaration) {
return SassCalculation.unsimplified(node.name, arguments);
}

try {
switch (node.name) {
Expand Down Expand Up @@ -2305,7 +2317,8 @@ class _EvaluateVisitor
_binaryOperatorToCalculationOperator(node.operator),
_visitCalculationValue(node.left, inMinMax: inMinMax),
_visitCalculationValue(node.right, inMinMax: inMinMax),
inMinMax: inMinMax));
inMinMax: inMinMax,
simplify: !_inSupportsDeclaration));
} else {
assert(node is NumberExpression ||
node is CalculationExpression ||
Expand Down Expand Up @@ -2804,7 +2817,9 @@ class _EvaluateVisitor
SassString visitStringExpression(StringExpression node) {
// Don't use [performInterpolation] here because we need to get the raw text
// from strings, rather than the semantic value.
return SassString(
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = false;
var result = SassString(
node.text.contents.map((value) {
if (value is String) return value;
var expression = value as Expression;
Expand All @@ -2814,6 +2829,8 @@ class _EvaluateVisitor
: _serialize(result, expression, quote: false);
}).join(),
quotes: node.hasQuotes);
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
}

// ## Plain CSS
Expand Down Expand Up @@ -3064,7 +3081,9 @@ class _EvaluateVisitor
/// values passed into the interpolation.
String _performInterpolation(Interpolation interpolation,
{bool warnForColor = false}) {
return interpolation.contents.map((value) {
var oldInSupportsDeclaration = _inSupportsDeclaration;
_inSupportsDeclaration = false;
var result = interpolation.contents.map((value) {
if (value is String) return value;
var expression = value as Expression;
var result = expression.accept(this);
Expand All @@ -3090,6 +3109,8 @@ class _EvaluateVisitor

return _serialize(result, expression, quote: false);
}).join();
_inSupportsDeclaration = oldInSupportsDeclaration;
return result;
}

/// Evaluates [expression] and calls `toCssString()` and wraps a
Expand Down
4 changes: 4 additions & 0 deletions pkg/sass_api/CHANGELOG.md
@@ -1,3 +1,7 @@
## 1.0.0-beta.39

* No user-visible changes.

## 1.0.0-beta.38

* No user-visible changes.
Expand Down
4 changes: 2 additions & 2 deletions pkg/sass_api/pubspec.yaml
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: 1.0.0-beta.38
version: 1.0.0-beta.39
description: Additional APIs for Dart Sass.
homepage: https://github.com/sass/dart-sass

environment:
sdk: '>=2.12.0 <3.0.0'

dependencies:
sass: 1.49.9
sass: 1.49.10

dependency_overrides:
sass: {path: ../..}
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,5 +1,5 @@
name: sass
version: 1.49.10-dev
version: 1.49.10
description: A Sass implementation in Dart.
homepage: https://github.com/sass/dart-sass

Expand Down

0 comments on commit 6652001

Please sign in to comment.