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

Stop simplifying calculations in supports #1653

Merged
merged 4 commits into from
Mar 30, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
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: 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
Original file line number Diff line number Diff line change
@@ -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