Skip to content

Commit 458852d

Browse files
committed
Revert "Calc functions implementation (#1970)"
This reverts commit e4c8cd6.
1 parent 86a2f42 commit 458852d

File tree

15 files changed

+109
-837
lines changed

15 files changed

+109
-837
lines changed

CHANGELOG.md

-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
## 1.65.0
2-
3-
* All functions defined in CSS Values and Units 4 are now parsed as calculation
4-
objects: `round()`, `mod()`, `rem()`, `sin()`, `cos()`, `tan()`, `asin()`,
5-
`acos()`, `atan()`, `atan2()`, `pow()`, `sqrt()`, `hypot()`, `log()`, `exp()`,
6-
`abs()`, and `sign()`.
7-
8-
* Deprecate explicitly passing the `%` unit to the global `abs()` function. In
9-
future releases, this will emit a CSS abs() function to be resolved by the
10-
browser. This deprecation is named `abs-percent`.
11-
121
## 1.64.3
132

143
### Dart API

lib/src/ast/sass/expression/calculation.dart

-69
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ final class CalculationExpression implements Expression {
4040
}
4141
}
4242

43-
/// Returns a `hypot()` calculation expression.
44-
CalculationExpression.hypot(Iterable<Expression> arguments, FileSpan span)
45-
: this("hypot", arguments, span);
46-
4743
/// Returns a `max()` calculation expression.
4844
CalculationExpression.max(Iterable<Expression> arguments, this.span)
4945
: name = "max",
@@ -53,76 +49,11 @@ final class CalculationExpression implements Expression {
5349
}
5450
}
5551

56-
/// Returns a `sqrt()` calculation expression.
57-
CalculationExpression.sqrt(Expression argument, FileSpan span)
58-
: this("sqrt", [argument], span);
59-
60-
/// Returns a `sin()` calculation expression.
61-
CalculationExpression.sin(Expression argument, FileSpan span)
62-
: this("sin", [argument], span);
63-
64-
/// Returns a `cos()` calculation expression.
65-
CalculationExpression.cos(Expression argument, FileSpan span)
66-
: this("cos", [argument], span);
67-
68-
/// Returns a `tan()` calculation expression.
69-
CalculationExpression.tan(Expression argument, FileSpan span)
70-
: this("tan", [argument], span);
71-
72-
/// Returns a `asin()` calculation expression.
73-
CalculationExpression.asin(Expression argument, FileSpan span)
74-
: this("asin", [argument], span);
75-
76-
/// Returns a `acos()` calculation expression.
77-
CalculationExpression.acos(Expression argument, FileSpan span)
78-
: this("acos", [argument], span);
79-
80-
/// Returns a `atan()` calculation expression.
81-
CalculationExpression.atan(Expression argument, FileSpan span)
82-
: this("atan", [argument], span);
83-
84-
/// Returns a `abs()` calculation expression.
85-
CalculationExpression.abs(Expression argument, FileSpan span)
86-
: this("abs", [argument], span);
87-
88-
/// Returns a `sign()` calculation expression.
89-
CalculationExpression.sign(Expression argument, FileSpan span)
90-
: this("sign", [argument], span);
91-
92-
/// Returns a `exp()` calculation expression.
93-
CalculationExpression.exp(Expression argument, FileSpan span)
94-
: this("exp", [argument], span);
95-
9652
/// Returns a `clamp()` calculation expression.
9753
CalculationExpression.clamp(
9854
Expression min, Expression value, Expression max, FileSpan span)
9955
: this("clamp", [min, max, value], span);
10056

101-
/// Returns a `pow()` calculation expression.
102-
CalculationExpression.pow(Expression base, Expression exponent, FileSpan span)
103-
: this("pow", [base, exponent], span);
104-
105-
/// Returns a `log()` calculation expression.
106-
CalculationExpression.log(Expression number, Expression base, FileSpan span)
107-
: this("log", [number, base], span);
108-
109-
/// Returns a `round()` calculation expression.
110-
CalculationExpression.round(
111-
Expression strategy, Expression number, Expression step, FileSpan span)
112-
: this("round", [strategy, number, step], span);
113-
114-
/// Returns a `atan2()` calculation expression.
115-
CalculationExpression.atan2(Expression y, Expression x, FileSpan span)
116-
: this("atan2", [y, x], span);
117-
118-
/// Returns a `mod()` calculation expression.
119-
CalculationExpression.mod(Expression y, Expression x, FileSpan span)
120-
: this("mod", [y, x], span);
121-
122-
/// Returns a `rem()` calculation expression.
123-
CalculationExpression.rem(Expression y, Expression x, FileSpan span)
124-
: this("rem", [y, x], span);
125-
12657
/// Returns a calculation expression with the given name and arguments.
12758
///
12859
/// Unlike the other constructors, this doesn't verify that the arguments are

lib/src/deprecation.dart

-5
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,6 @@ enum Deprecation {
5555
deprecatedIn: '1.56.0',
5656
description: 'Passing invalid units to built-in functions.'),
5757

58-
/// Deprecation for passing percentages to the Sass abs() function.
59-
absPercent('abs-percent',
60-
deprecatedIn: '1.64.0',
61-
description: 'Passing percentages to the Sass abs() function.'),
62-
6358
duplicateVariableFlags('duplicate-var-flags',
6459
deprecatedIn: '1.62.0',
6560
description:

lib/src/functions/math.dart

+66-22
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import '../deprecation.dart';
1212
import '../evaluation_context.dart';
1313
import '../exception.dart';
1414
import '../module/built_in.dart';
15-
import '../util/number.dart';
1615
import '../value.dart';
1716

1817
/// The global definitions of Sass math functions.
@@ -133,32 +132,87 @@ final _log = _function("log", r"$number, $base: null", (arguments) {
133132
final _pow = _function("pow", r"$base, $exponent", (arguments) {
134133
var base = arguments[0].assertNumber("base");
135134
var exponent = arguments[1].assertNumber("exponent");
136-
return pow(base, exponent);
135+
if (base.hasUnits) {
136+
throw SassScriptException("\$base: Expected $base to have no units.");
137+
} else if (exponent.hasUnits) {
138+
throw SassScriptException(
139+
"\$exponent: Expected $exponent to have no units.");
140+
} else {
141+
return SassNumber(math.pow(base.value, exponent.value));
142+
}
137143
});
138144

139-
final _sqrt = _singleArgumentMathFunc("sqrt", sqrt);
145+
final _sqrt = _function("sqrt", r"$number", (arguments) {
146+
var number = arguments[0].assertNumber("number");
147+
if (number.hasUnits) {
148+
throw SassScriptException("\$number: Expected $number to have no units.");
149+
} else {
150+
return SassNumber(math.sqrt(number.value));
151+
}
152+
});
140153

141154
///
142155
/// Trigonometric functions
143156
///
144157
145-
final _acos = _singleArgumentMathFunc("acos", acos);
158+
final _acos = _function("acos", r"$number", (arguments) {
159+
var number = arguments[0].assertNumber("number");
160+
if (number.hasUnits) {
161+
throw SassScriptException("\$number: Expected $number to have no units.");
162+
} else {
163+
return SassNumber.withUnits(math.acos(number.value) * 180 / math.pi,
164+
numeratorUnits: ['deg']);
165+
}
166+
});
146167

147-
final _asin = _singleArgumentMathFunc("asin", asin);
168+
final _asin = _function("asin", r"$number", (arguments) {
169+
var number = arguments[0].assertNumber("number");
170+
if (number.hasUnits) {
171+
throw SassScriptException("\$number: Expected $number to have no units.");
172+
} else {
173+
return SassNumber.withUnits(math.asin(number.value) * 180 / math.pi,
174+
numeratorUnits: ['deg']);
175+
}
176+
});
148177

149-
final _atan = _singleArgumentMathFunc("atan", atan);
178+
final _atan = _function("atan", r"$number", (arguments) {
179+
var number = arguments[0].assertNumber("number");
180+
if (number.hasUnits) {
181+
throw SassScriptException("\$number: Expected $number to have no units.");
182+
} else {
183+
return SassNumber.withUnits(math.atan(number.value) * 180 / math.pi,
184+
numeratorUnits: ['deg']);
185+
}
186+
});
150187

151188
final _atan2 = _function("atan2", r"$y, $x", (arguments) {
152189
var y = arguments[0].assertNumber("y");
153190
var x = arguments[1].assertNumber("x");
154-
return atan2(y, x);
191+
return SassNumber.withUnits(
192+
math.atan2(y.value, x.convertValueToMatch(y, 'x', 'y')) * 180 / math.pi,
193+
numeratorUnits: ['deg']);
155194
});
156195

157-
final _cos = _singleArgumentMathFunc("cos", cos);
158-
159-
final _sin = _singleArgumentMathFunc("sin", sin);
160-
161-
final _tan = _singleArgumentMathFunc("tan", tan);
196+
final _cos = _function(
197+
"cos",
198+
r"$number",
199+
(arguments) => SassNumber(math.cos(arguments[0]
200+
.assertNumber("number")
201+
.coerceValueToUnit("rad", "number"))));
202+
203+
final _sin = _function(
204+
"sin",
205+
r"$number",
206+
(arguments) => SassNumber(math.sin(arguments[0]
207+
.assertNumber("number")
208+
.coerceValueToUnit("rad", "number"))));
209+
210+
final _tan = _function(
211+
"tan",
212+
r"$number",
213+
(arguments) => SassNumber(math.tan(arguments[0]
214+
.assertNumber("number")
215+
.coerceValueToUnit("rad", "number"))));
162216

163217
///
164218
/// Unit functions
@@ -234,16 +288,6 @@ final _div = _function("div", r"$number1, $number2", (arguments) {
234288
/// Helpers
235289
///
236290
237-
/// Returns a [Callable] named [name] that calls a single argument
238-
/// math function.
239-
BuiltInCallable _singleArgumentMathFunc(
240-
String name, SassNumber mathFunc(SassNumber value)) {
241-
return _function(name, r"$number", (arguments) {
242-
var number = arguments[0].assertNumber("number");
243-
return mathFunc(number);
244-
});
245-
}
246-
247291
/// Returns a [Callable] named [name] that transforms a number's value
248292
/// using [transform] and preserves its units.
249293
BuiltInCallable _numberFunction(String name, double transform(double value)) {

lib/src/js/value/calculation.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ final JSClass calculationOperationClass = () {
9393
_assertCalculationValue(left);
9494
_assertCalculationValue(right);
9595
return SassCalculation.operateInternal(operator, left, right,
96-
inLegacySassFunction: false, simplify: false);
96+
inMinMax: false, simplify: false);
9797
});
9898

9999
jsClass.defineMethods({
@@ -109,7 +109,7 @@ final JSClass calculationOperationClass = () {
109109

110110
getJSClass(SassCalculation.operateInternal(
111111
CalculationOperator.plus, SassNumber(1), SassNumber(1),
112-
inLegacySassFunction: false, simplify: false))
112+
inMinMax: false, simplify: false))
113113
.injectSuperclass(jsClass);
114114
return jsClass;
115115
}();

lib/src/parse/stylesheet.dart

+10-43
Original file line numberDiff line numberDiff line change
@@ -2065,8 +2065,7 @@ abstract class StylesheetParser extends Parser {
20652065
/// produces a potentially slash-separated number.
20662066
bool _isSlashOperand(Expression expression) =>
20672067
expression is NumberExpression ||
2068-
(expression is CalculationExpression &&
2069-
!{'min', 'max', 'round', 'abs'}.contains(expression.name)) ||
2068+
expression is CalculationExpression ||
20702069
(expression is BinaryOperationExpression && expression.allowsSlash);
20712070

20722071
/// Consumes an expression that doesn't contain any top-level whitespace.
@@ -2653,64 +2652,32 @@ abstract class StylesheetParser extends Parser {
26532652
assert(scanner.peekChar() == $lparen);
26542653
switch (name) {
26552654
case "calc":
2656-
case "sqrt":
2657-
case "sin":
2658-
case "cos":
2659-
case "tan":
2660-
case "asin":
2661-
case "acos":
2662-
case "atan":
2663-
case "exp":
2664-
case "sign":
26652655
var arguments = _calculationArguments(1);
26662656
return CalculationExpression(name, arguments, scanner.spanFrom(start));
26672657

2668-
case "abs":
2669-
return _tryArgumentsCalculation(name, start, 1);
2670-
2671-
case "hypot":
2672-
var arguments = _calculationArguments();
2673-
return CalculationExpression(name, arguments, scanner.spanFrom(start));
2674-
26752658
case "min" || "max":
26762659
// min() and max() are parsed as calculations if possible, and otherwise
26772660
// are parsed as normal Sass functions.
2678-
return _tryArgumentsCalculation(name, start, null);
2679-
2680-
case "pow":
2681-
case "log":
2682-
case "atan2":
2683-
case "mod":
2684-
case "rem":
2685-
var arguments = _calculationArguments(2);
2661+
var beforeArguments = scanner.state;
2662+
List<Expression> arguments;
2663+
try {
2664+
arguments = _calculationArguments();
2665+
} on FormatException catch (_) {
2666+
scanner.state = beforeArguments;
2667+
return null;
2668+
}
2669+
26862670
return CalculationExpression(name, arguments, scanner.spanFrom(start));
26872671

26882672
case "clamp":
26892673
var arguments = _calculationArguments(3);
26902674
return CalculationExpression(name, arguments, scanner.spanFrom(start));
26912675

2692-
case "round":
2693-
return _tryArgumentsCalculation(name, start, 3);
2694-
26952676
case _:
26962677
return null;
26972678
}
26982679
}
26992680

2700-
// Returns a CalculationExpression if the function can be parsed as a calculation,
2701-
// otherwise, returns null and the function is parsed as a normal Sass function.
2702-
CalculationExpression? _tryArgumentsCalculation(
2703-
String name, LineScannerState start, int? maxArgs) {
2704-
var beforeArguments = scanner.state;
2705-
try {
2706-
var arguments = _calculationArguments(maxArgs);
2707-
return CalculationExpression(name, arguments, scanner.spanFrom(start));
2708-
} on FormatException catch (_) {
2709-
scanner.state = beforeArguments;
2710-
return null;
2711-
}
2712-
}
2713-
27142681
/// Consumes and returns arguments for a calculation expression, including the
27152682
/// opening and closing parentheses.
27162683
///

0 commit comments

Comments
 (0)