From 78f593e0372c8c3441059ff09e24b3e8cb6e689e Mon Sep 17 00:00:00 2001 From: Pamela Lozano De La Garza Date: Thu, 18 May 2023 17:03:40 -0700 Subject: [PATCH] Sqrt calc function implementation --- lib/src/ast/sass/expression/calculation.dart | 4 ++++ lib/src/parse/stylesheet.dart | 1 + lib/src/value/calculation.dart | 20 ++++++++++++++++++++ lib/src/visitor/async_evaluate.dart | 5 ++++- lib/src/visitor/evaluate.dart | 7 +++++-- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/src/ast/sass/expression/calculation.dart b/lib/src/ast/sass/expression/calculation.dart index ac17dc0aa..55c5b969a 100644 --- a/lib/src/ast/sass/expression/calculation.dart +++ b/lib/src/ast/sass/expression/calculation.dart @@ -50,6 +50,10 @@ class CalculationExpression implements Expression { } } + /// Returns a `sqrt()` calculation expression. + CalculationExpression.sqrt(Expression argument, FileSpan span) + : this("sqrt", [argument], span); + /// Returns a `clamp()` calculation expression. CalculationExpression.clamp( Expression min, Expression value, Expression max, FileSpan span) diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index 0a4286687..04edf310e 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -2894,6 +2894,7 @@ abstract class StylesheetParser extends Parser { assert(scanner.peekChar() == $lparen); switch (name) { case "calc": + case "sqrt": var arguments = _calculationArguments(1); return CalculationExpression(name, arguments, scanner.spanFrom(start)); diff --git a/lib/src/value/calculation.dart b/lib/src/value/calculation.dart index 74375b280..d7c4aec31 100644 --- a/lib/src/value/calculation.dart +++ b/lib/src/value/calculation.dart @@ -11,6 +11,7 @@ import '../utils.dart'; import '../value.dart'; import '../visitor/interface/value.dart'; import '../visitor/serialize.dart'; +import 'dart:math' as math; /// A SassScript calculation. /// @@ -120,6 +121,25 @@ class SassCalculation extends Value { return SassCalculation._("max", args); } + /// Creates a `sqrt()` calculation with the given [argument]. + /// + /// Each argument must be either a [SassNumber], a [SassCalculation], an + /// unquoted [SassString], a [CalculationOperation], or a + /// [CalculationInterpolation]. It must be passed at least one argument. + /// + /// This automatically simplifies the calculation, so it may return a + /// [SassNumber] rather than a [SassCalculation]. It throws an exception if it + /// can determine that the calculation will definitely produce invalid CSS. + static Value sqrt(Object argument) { + argument = _simplify(argument); + if (argument is! SassNumber) { + return SassCalculation.sqrt(argument); + } + argument.assertNoUnits(); + + return SassNumber(math.sqrt(argument.value)); + } + /// Creates a `clamp()` calculation with the given [min], [value], and [max]. /// /// Each argument must be either a [SassNumber], a [SassCalculation], an diff --git a/lib/src/visitor/async_evaluate.dart b/lib/src/visitor/async_evaluate.dart index 30c72ff49..1d4449da8 100644 --- a/lib/src/visitor/async_evaluate.dart +++ b/lib/src/visitor/async_evaluate.dart @@ -2292,7 +2292,7 @@ class _EvaluateVisitor var arguments = [ for (var argument in node.arguments) await _visitCalculationValue(argument, - inMinMax: node.name == 'min' || node.name == 'max') + inMinMax: {'min', 'max', 'sqrt'}.contains(node.name)) ]; if (_inSupportsDeclaration) { return SassCalculation.unsimplified(node.name, arguments); @@ -2303,6 +2303,9 @@ class _EvaluateVisitor case "calc": assert(arguments.length == 1); return SassCalculation.calc(arguments[0]); + case "sqrt": + assert(arguments.length == 1); + return SassCalculation.sqrt(arguments[0]); case "min": return SassCalculation.min(arguments); case "max": diff --git a/lib/src/visitor/evaluate.dart b/lib/src/visitor/evaluate.dart index 75c876f1b..4f62119dd 100644 --- a/lib/src/visitor/evaluate.dart +++ b/lib/src/visitor/evaluate.dart @@ -5,7 +5,7 @@ // DO NOT EDIT. This file was generated from async_evaluate.dart. // See tool/grind/synchronize.dart for details. // -// Checksum: 17862153344c8577d780b3e039a1ce5ebb774c17 +// Checksum: e62a93c1e80688b9131d8c0dedbcc87d061cc8a2 // // ignore_for_file: unused_import @@ -2281,7 +2281,7 @@ class _EvaluateVisitor var arguments = [ for (var argument in node.arguments) _visitCalculationValue(argument, - inMinMax: node.name == 'min' || node.name == 'max') + inMinMax: {'min', 'max', 'sqrt'}.contains(node.name)) ]; if (_inSupportsDeclaration) { return SassCalculation.unsimplified(node.name, arguments); @@ -2292,6 +2292,9 @@ class _EvaluateVisitor case "calc": assert(arguments.length == 1); return SassCalculation.calc(arguments[0]); + case "sqrt": + assert(arguments.length == 1); + return SassCalculation.sqrt(arguments[0]); case "min": return SassCalculation.min(arguments); case "max":