Fix number equality.

This commit is contained in:
Natalie Weizenbaum 2016-10-18 14:26:52 -07:00
parent 45becee133
commit 286b24afca
3 changed files with 34 additions and 12 deletions

View File

@ -269,6 +269,14 @@ abstract class Value {
Value dividedBy(Value other) =>
new SassString("${toCssString()}/${other.toCssString()}");
/// The SassScript `==` operation.
///
/// For the most part, this is the same as the Dart `==` operation, which is
/// used as equivalence for map keys. However, [SassNumber]s with units are
/// SassScript-`==` to the same unitless numbers, but they not Dart `==`. This
/// ensures that map-key equality is transitive.
SassBoolean equals(Value other) => new SassBoolean(this == other);
/// The SassScript unary `+` operation.
Value unaryPlus() => new SassString("+${toCssString()}");

View File

@ -392,32 +392,28 @@ class SassNumber extends Value {
SassBoolean greaterThan(Value other) {
if (other is SassNumber) {
return new SassBoolean(
_coerceUnits(other, (num1, num2) => fuzzyGreaterThan(num1, num2)));
return new SassBoolean(_coerceUnits(other, fuzzyGreaterThan));
}
throw new SassScriptException('Undefined operation "$this > $other".');
}
SassBoolean greaterThanOrEquals(Value other) {
if (other is SassNumber) {
return new SassBoolean(_coerceUnits(
other, (num1, num2) => fuzzyGreaterThanOrEquals(num1, num2)));
return new SassBoolean(_coerceUnits(other, fuzzyGreaterThanOrEquals));
}
throw new SassScriptException('Undefined operation "$this >= $other".');
}
SassBoolean lessThan(Value other) {
if (other is SassNumber) {
return new SassBoolean(
_coerceUnits(other, (num1, num2) => fuzzyLessThan(num1, num2)));
return new SassBoolean(_coerceUnits(other, fuzzyLessThan));
}
throw new SassScriptException('Undefined operation "$this < $other".');
}
SassBoolean lessThanOrEquals(Value other) {
if (other is SassNumber) {
return new SassBoolean(_coerceUnits(
other, (num1, num2) => fuzzyLessThanOrEquals(num1, num2)));
return new SassBoolean(_coerceUnits(other, fuzzyLessThanOrEquals));
}
throw new SassScriptException('Undefined operation "$this <= $other".');
}
@ -464,6 +460,18 @@ class SassNumber extends Value {
throw new SassScriptException('Undefined operation "$this / $other".');
}
SassBoolean equals(Value other) {
if (other is SassNumber) {
try {
return new SassBoolean(_coerceUnits(other, fuzzyEquals));
} on SassScriptException {
return sassFalse;
}
} else {
return sassFalse;
}
}
Value unaryPlus() => this;
Value unaryMinus() => new SassNumber(-value);
@ -593,9 +601,15 @@ class SassNumber extends Value {
}
bool operator ==(other) =>
other is SassNumber && fuzzyEquals(value, other.value);
other is SassNumber &&
fuzzyEquals(value, other.value) &&
listEquals(numeratorUnits, other.numeratorUnits) &&
listEquals(denominatorUnits, other.denominatorUnits);
int get hashCode => fuzzyHashCode(value);
int get hashCode =>
fuzzyHashCode(value) ^
listHash(numeratorUnits) ^
listHash(denominatorUnits);
/// Throws a [SassScriptException] with the given [message].
SassScriptException _exception(String message, [String name]) =>

View File

@ -662,9 +662,9 @@ class _PerformVisitor implements StatementVisitor, ExpressionVisitor<Value> {
case BinaryOperator.and:
return left.and(right);
case BinaryOperator.equals:
return new SassBoolean(left == right);
return left.equals(right);
case BinaryOperator.notEquals:
return new SassBoolean(left != right);
return left.equals(right).unaryNot();
case BinaryOperator.greaterThan:
return left.greaterThan(right);
case BinaryOperator.greaterThanOrEquals: