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

Avoid throw/catch in Number.== #1188

Merged
merged 1 commit into from
Jan 11, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.32.3

* Optimize `==` for numbers that have different units.

## 1.32.2

* Print the actual number that was received in unit deprecation warnings for
Expand Down
39 changes: 33 additions & 6 deletions lib/src/value/number.dart
Original file line number Diff line number Diff line change
Expand Up @@ -620,16 +620,26 @@ class SassNumber extends Value implements ext.SassNumber {

bool operator ==(Object other) {
if (other is SassNumber) {
// Unitless numbers are convertable to unit numbers, but not equal, so we
// special-case unitless here.
if (hasUnits != other.hasUnits) return false;
if (numeratorUnits.length != other.numeratorUnits.length ||
denominatorUnits.length != other.denominatorUnits.length) {
return false;
}
if (!hasUnits) return fuzzyEquals(value, other.value);

try {
return _coerceUnits(other, fuzzyEquals);
} on SassScriptException {
if (!listEquals(_canonicalizeUnitList(numeratorUnits),
_canonicalizeUnitList(other.numeratorUnits)) ||
!listEquals(_canonicalizeUnitList(denominatorUnits),
_canonicalizeUnitList(other.denominatorUnits))) {
return false;
}

return fuzzyEquals(
value *
_canonicalMultiplier(numeratorUnits) /
_canonicalMultiplier(denominatorUnits),
other.value *
_canonicalMultiplier(other.numeratorUnits) /
_canonicalMultiplier(other.denominatorUnits));
} else {
return false;
}
Expand All @@ -639,6 +649,23 @@ class SassNumber extends Value implements ext.SassNumber {
_canonicalMultiplier(numeratorUnits) /
_canonicalMultiplier(denominatorUnits));

/// Converts a unit list (such as [numeratorUnits]) into an equivalent list in
/// a canonical form, to make it easier to check whether two numbers have
/// compatible units.
List<String> _canonicalizeUnitList(List<String> units) {
if (units.isEmpty) return units;
if (units.length == 1) {
var type = _typesByUnit[units.first];
return type == null ? units : [_unitsByType[type].first];
}

return units.map((unit) {
var type = _typesByUnit[unit];
return type == null ? unit : _unitsByType[type].first;
}).toList()
..sort();
}

/// Returns a multiplier that encapsulates unit equivalence in [units].
///
/// That is, if `X units1 == Y units2`, `X * _canonicalMultiplier(units1) == Y
Expand Down
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.32.2
version: 1.32.3
description: A Sass implementation in Dart.
author: Sass Team
homepage: https://github.com/sass/dart-sass
Expand Down