Skip to content

Commit

Permalink
Corrections and rename parameter to inLegacySassFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
pamelalozano16 committed May 26, 2023
1 parent acf8b34 commit b9b9602
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 98 deletions.
7 changes: 7 additions & 0 deletions lib/src/parse/stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2917,8 +2917,15 @@ abstract class StylesheetParser extends Parser {
return CalculationExpression(name, arguments, scanner.spanFrom(start));

case "clamp":
var arguments = _calculationArguments(3);
return CalculationExpression(name, arguments, scanner.spanFrom(start));
case "round":
var beforeArguments = scanner.state;
var arguments = _calculationArguments(3);
if (arguments.length == 1) {
scanner.state = beforeArguments;
return null;
}
return CalculationExpression(name, arguments, scanner.spanFrom(start));

default:
Expand Down
31 changes: 0 additions & 31 deletions lib/src/util/number.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import 'dart:math' as math;

import '../exception.dart';
import '../value.dart';

/// The power of ten to which to round Sass numbers to determine if they're
Expand Down Expand Up @@ -132,33 +131,3 @@ SassNumber pow(SassNumber num1, SassNumber num2) {
num2.assertNoUnits();
return SassNumber(math.pow(num1.value, num2.value));
}

/// Return the rounded number according to the strategy
SassNumber roundStrategies(SassString strategy, SassNumber number) {
if (!number.value.isNaN && number.value.isFinite) {
var strategies = {
'nearest': SassNumber(number.value.round().toDouble()),
'up': SassNumber(number.value.ceil().toDouble()),
'down': SassNumber(number.value.floor().toDouble()),
'to-zero': number.value < 0
? SassNumber(number.value.ceil().toDouble())
: SassNumber(number.value.floor().toDouble())
};

return strategies[strategy.text] ?? SassNumber(double.nan);
}
return SassNumber(double.nan);
}

/// Return the rounded number according to the strategy and the step provided.
SassNumber step(SassString strategy, SassNumber number, SassNumber step) {
var stepStrategies = {
'nearest': SassNumber((number.value / step.value).round() * step.value),
'up': SassNumber((number.value / step.value).ceil() * step.value),
'down': SassNumber((number.value / step.value).floor() * step.value),
'to-zero': number.value < 0
? SassNumber((number.value / step.value).ceil() * step.value)
: SassNumber((number.value / step.value).floor() * step.value)
};
return stepStrategies[strategy.text] ?? step;
}
87 changes: 51 additions & 36 deletions lib/src/value/calculation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,18 @@ class SassCalculation extends Value {
///
/// This may be passed fewer than three arguments, but only if one of the
/// arguments is an unquoted `var()` string.
static Value pow(Object base, Object exponent) {
static Value pow(Object base, Object? exponent) {
_verifyLength([base, if (exponent != null) exponent], 2);
base = _simplify(base);
exponent = _simplify(exponent);
exponent = exponent.andThen(_simplify);
if (base is! SassNumber || exponent is! SassNumber) {
return SassCalculation._("pow", [base, exponent]);
return SassCalculation._("pow", [base, exponent ?? double.nan]);
}

_verifyCompatibleNumbers([base, exponent]);
return number_lib.pow(base, exponent);
}

/// Creates a `round()` calculation with the given [strategy], [number], and [step].
///
/// Strategy must be either nearest, up, down or to-zero.
///
/// Number and step must be either a [SassNumber], a [SassCalculation], an
Expand All @@ -217,13 +217,15 @@ class SassCalculation extends Value {

var args = [if (strategy != null) strategy, number, if (step != null) step];

// Sets the default strategy to nearest.
// If only two arguments are provided, they should match [number] and [step].
if (number is SassString && step is SassNumber) {
throw SassScriptException("If strategy is not null, step is required.");
}

strategy ??= SassString('nearest', quotes: false);

if (strategy is! SassString ||
!{'nearest', 'up', 'down', 'to-zero'}.contains(strategy.text)) {
if (step == null && strategy is SassNumber) {
throw SassScriptException("If step not null, strategy is required.");
}
throw SassScriptException(
"$strategy must be either nearest, up, down or to-zero.");
}
Expand All @@ -232,33 +234,45 @@ class SassCalculation extends Value {
return SassCalculation._("round", args);
}

if (step is SassNumber) {
if (step.value == 0) return SassNumber(double.nan);
if (number.value.isInfinite) {
if (step.value.isInfinite) {
return SassNumber(double.nan);
}
return SassNumber(double.infinity);
}
// Handle one argument case with legacy round.
if (step is! SassNumber) {
return SassNumber(number.value.round().toDouble());
}

if (step.value == 0) return SassNumber(double.nan);
if (number.value.isInfinite) {
if (step.value.isInfinite) {
if (number.value == -0) return number;
if (number.value >= 0 && strategy.text == "up") {
return SassNumber(double.infinity);
}
if (number.value < 0 && strategy.text == "down") {
return SassNumber(-double.infinity);
}

return SassNumber(0);
return SassNumber(double.nan);
}
return SassNumber(double.infinity);
}

_verifyCompatibleNumbers([number, step]);
if (step.value.isInfinite) {
if (number.value == -0) return number;
if (number.value >= 0 && strategy.text == "up") {
return SassNumber(double.infinity);
}
if (number.value < 0 && strategy.text == "down") {
return SassNumber(-double.infinity);
}

return SassNumber(0);
}

//Handle step
return number_lib.step(strategy, number, step);
} else if (step == null) {
return number_lib.roundStrategies(strategy, number);
_verifyCompatibleNumbers([number, step]);

//Handle step
switch (strategy.text) {
case 'nearest':
return SassNumber((number.value / step.value).round() * step.value);
case 'up':
return SassNumber((number.value / step.value).ceil() * step.value);
case 'down':
return SassNumber((number.value / step.value).floor() * step.value);
case 'to-zero':
return number.value < 0
? SassNumber((number.value / step.value).ceil() * step.value)
: SassNumber((number.value / step.value).floor() * step.value);
}
return SassNumber(double.nan);
}
Expand All @@ -274,19 +288,20 @@ class SassCalculation extends Value {
/// a [CalculationInterpolation].
static Object operate(
CalculationOperator operator, Object left, Object right) =>
operateInternal(operator, left, right, inMinMax: false, simplify: true);
operateInternal(operator, left, right,
inLegacySassFunction: false, simplify: true);

/// Like [operate], but with the internal-only [inMinMax] parameter.
/// Like [operate], but with the internal-only [inLegacySassFunction] parameter.
///
/// If [inMinMax] is `true`, this allows unitless numbers to be added and
/// If [inLegacySassFunction] 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 simplify}) {
{required bool inLegacySassFunction, required bool simplify}) {
if (!simplify) {
return CalculationOperation._(operator, left, right);
}
Expand All @@ -297,7 +312,7 @@ class SassCalculation extends Value {
operator == CalculationOperator.minus) {
if (left is SassNumber &&
right is SassNumber &&
(inMinMax
(inLegacySassFunction
? left.isComparableTo(right)
: left.hasCompatibleUnits(right))) {
return operator == CalculationOperator.plus
Expand Down
29 changes: 14 additions & 15 deletions lib/src/visitor/async_evaluate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2292,7 +2292,7 @@ class _EvaluateVisitor
var arguments = [
for (var argument in node.arguments)
await _visitCalculationValue(argument,
inMinMax: {'min', 'max', 'round'}.contains(node.name))
inLegacySassFunction: {'min', 'max', 'round'}.contains(node.name))
];
if (_inSupportsDeclaration) {
return SassCalculation.unsimplified(node.name, arguments);
Expand All @@ -2311,18 +2311,14 @@ class _EvaluateVisitor
case "max":
return SassCalculation.max(arguments);
case "pow":
if (arguments.length < 2)
throw SassScriptException(
"2 arguments required, but only 1 was passed.");
return SassCalculation.pow(arguments[0], arguments[1]);
return SassCalculation.pow(
arguments[0], arguments.length > 1 ? arguments[1] : null);
case "round":
assert(arguments.isNotEmpty, true);
return arguments.length > 2
? SassCalculation.round(arguments[0], arguments[1], arguments[2])
: SassCalculation.round(
arguments.length > 1 ? arguments[0] : null,
arguments.length == 1 ? arguments[0] : arguments[1],
null);
: SassCalculation.round(null, arguments[0],
arguments.length > 1 ? arguments[1] : null);
case "clamp":
return SassCalculation.clamp(
arguments[0],
Expand Down Expand Up @@ -2379,14 +2375,15 @@ class _EvaluateVisitor

/// Evaluates [node] as a component of a calculation.
///
/// If [inMinMax] is `true`, this allows unitless numbers to be added and
/// If [inLegacySassFunction] 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.
Future<Object> _visitCalculationValue(Expression node,
{required bool inMinMax}) async {
{required bool inLegacySassFunction}) async {
if (node is ParenthesizedExpression) {
var inner = node.expression;
var result = await _visitCalculationValue(inner, inMinMax: inMinMax);
var result = await _visitCalculationValue(inner,
inLegacySassFunction: inLegacySassFunction);
return inner is FunctionExpression &&
inner.name.toLowerCase() == 'var' &&
result is SassString &&
Expand Down Expand Up @@ -2422,9 +2419,11 @@ class _EvaluateVisitor
node,
() async => SassCalculation.operateInternal(
_binaryOperatorToCalculationOperator(node.operator),
await _visitCalculationValue(node.left, inMinMax: inMinMax),
await _visitCalculationValue(node.right, inMinMax: inMinMax),
inMinMax: inMinMax,
await _visitCalculationValue(node.left,
inLegacySassFunction: inLegacySassFunction),
await _visitCalculationValue(node.right,
inLegacySassFunction: inLegacySassFunction),
inLegacySassFunction: inLegacySassFunction,
simplify: !_inSupportsDeclaration));
} else {
assert(node is NumberExpression ||
Expand Down
32 changes: 16 additions & 16 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: eefc1feceabe200845cb42b0c043ef68ac9f9b58
// Checksum: dc839ab8ceec0ac46fb2094ccbcfc4f1331fcc08
//
// ignore_for_file: unused_import

Expand Down Expand Up @@ -2281,7 +2281,7 @@ class _EvaluateVisitor
var arguments = [
for (var argument in node.arguments)
_visitCalculationValue(argument,
inMinMax: {'min', 'max', 'round'}.contains(node.name))
inLegacySassFunction: {'min', 'max', 'round'}.contains(node.name))
];
if (_inSupportsDeclaration) {
return SassCalculation.unsimplified(node.name, arguments);
Expand All @@ -2300,18 +2300,14 @@ class _EvaluateVisitor
case "max":
return SassCalculation.max(arguments);
case "pow":
if (arguments.length < 2)
throw SassScriptException(
"2 arguments required, but only 1 was passed.");
return SassCalculation.pow(arguments[0], arguments[1]);
return SassCalculation.pow(
arguments[0], arguments.length > 1 ? arguments[1] : null);
case "round":
assert(arguments.isNotEmpty, true);
return arguments.length > 2
? SassCalculation.round(arguments[0], arguments[1], arguments[2])
: SassCalculation.round(
arguments.length > 1 ? arguments[0] : null,
arguments.length == 1 ? arguments[0] : arguments[1],
null);
: SassCalculation.round(null, arguments[0],
arguments.length > 1 ? arguments[1] : null);
case "clamp":
return SassCalculation.clamp(
arguments[0],
Expand Down Expand Up @@ -2368,13 +2364,15 @@ class _EvaluateVisitor

/// Evaluates [node] as a component of a calculation.
///
/// If [inMinMax] is `true`, this allows unitless numbers to be added and
/// If [inLegacySassFunction] 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.
Object _visitCalculationValue(Expression node, {required bool inMinMax}) {
Object _visitCalculationValue(Expression node,
{required bool inLegacySassFunction}) {
if (node is ParenthesizedExpression) {
var inner = node.expression;
var result = _visitCalculationValue(inner, inMinMax: inMinMax);
var result = _visitCalculationValue(inner,
inLegacySassFunction: inLegacySassFunction);
return inner is FunctionExpression &&
inner.name.toLowerCase() == 'var' &&
result is SassString &&
Expand Down Expand Up @@ -2410,9 +2408,11 @@ class _EvaluateVisitor
node,
() => SassCalculation.operateInternal(
_binaryOperatorToCalculationOperator(node.operator),
_visitCalculationValue(node.left, inMinMax: inMinMax),
_visitCalculationValue(node.right, inMinMax: inMinMax),
inMinMax: inMinMax,
_visitCalculationValue(node.left,
inLegacySassFunction: inLegacySassFunction),
_visitCalculationValue(node.right,
inLegacySassFunction: inLegacySassFunction),
inLegacySassFunction: inLegacySassFunction,
simplify: !_inSupportsDeclaration));
} else {
assert(node is NumberExpression ||
Expand Down

0 comments on commit b9b9602

Please sign in to comment.