JS: prevent Any.equals from mangling

This commit is contained in:
Alexey Andreev
2016-12-07 18:43:21 +03:00
parent a2d45153ba
commit cc819928de
7 changed files with 61 additions and 19 deletions
@@ -230,6 +230,7 @@ class NameSuggestion {
when (overriddenDescriptor.fqNameUnsafe.asString()) {
"kotlin.CharSequence.subSequence" -> return NameAndStability("substring", true)
"kotlin.CharSequence.get" -> return NameAndStability("charAt", true)
"kotlin.Any.equals" -> return NameAndStability("equals", true)
}
}
@@ -5609,6 +5609,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("equalsMangling.kt")
public void testEqualsMangling() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/equalsMangling.kt");
doTest(fileName);
}
@TestMetadata("eval.kt")
public void testEval() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/eval.kt");
@@ -54,7 +54,7 @@ fun test(expected: String, f: () -> Unit) {
}
}
val STABLE_EQUALS = "equals_za3rmp$"
val STABLE_EQUALS = "equals"
val STABLE_HASH_CODE = "hashCode"
val STABLE_TO_STRING = "toString"
val STABLE_EQUALS_2 = "equals_wn2jw4$"
+10
View File
@@ -0,0 +1,10 @@
function foo(first, second) {
return first.equals(second);
}
function B(value) {
this.value = value;
}
B.prototype.equals = function(other) {
return other instanceof B && other.value == this.value;
};
+25
View File
@@ -0,0 +1,25 @@
data class A(val number: Int)
@native fun foo(first: A, second: A): Boolean
@native class B(value: Int)
fun box(): String {
val a = A(23)
val b = A(23)
val c = A(42)
if (!foo(a, b)) return "fail1"
if (!foo(a, a)) return "fail2"
if (foo(a, c)) return "fail3"
val d = B(23)
val e = B(23)
val f = B(42)
if (d != e) return "fail4"
if (d != d) return "fail5"
if (d == f) return "fail6"
return "OK"
}
+2 -2
View File
@@ -48,8 +48,8 @@ Kotlin.equals = function (obj1, obj2) {
return false;
}
if (typeof obj1 == "object" && typeof obj1.equals_za3rmp$ === "function") {
return obj1.equals_za3rmp$(obj2);
if (typeof obj1 == "object" && typeof obj1.equals === "function") {
return obj1.equals(obj2);
}
return obj1 === obj2;
+16 -16
View File
@@ -297,7 +297,7 @@ Kotlin.Long.prototype.toString = function(opt_radix) {
}
if (this.isNegative()) {
if (this.equals(Kotlin.Long.MIN_VALUE)) {
if (this.equalsLong(Kotlin.Long.MIN_VALUE)) {
// We need to change the Long value before it can be negated, so we remove
// the bottom-most digit in this base and then recurse to do the rest.
var radixLong = Kotlin.Long.fromNumber(radix);
@@ -358,7 +358,7 @@ Kotlin.Long.prototype.getLowBitsUnsigned = function() {
*/
Kotlin.Long.prototype.getNumBitsAbs = function() {
if (this.isNegative()) {
if (this.equals(Kotlin.Long.MIN_VALUE)) {
if (this.equalsLong(Kotlin.Long.MIN_VALUE)) {
return 64;
} else {
return this.negate().getNumBitsAbs();
@@ -397,7 +397,7 @@ Kotlin.Long.prototype.isOdd = function() {
* @param {Kotlin.Long} other Long to compare against.
* @return {boolean} Whether this Long equals the other.
*/
Kotlin.Long.prototype.equals = function(other) {
Kotlin.Long.prototype.equalsLong = function(other) {
return (this.high_ == other.high_) && (this.low_ == other.low_);
};
@@ -406,7 +406,7 @@ Kotlin.Long.prototype.equals = function(other) {
* @param {Kotlin.Long} other Long to compare against.
* @return {boolean} Whether this Long does not equal the other.
*/
Kotlin.Long.prototype.notEquals = function(other) {
Kotlin.Long.prototype.notEqualsLong = function(other) {
return (this.high_ != other.high_) || (this.low_ != other.low_);
};
@@ -454,7 +454,7 @@ Kotlin.Long.prototype.greaterThanOrEqual = function(other) {
* if the given one is greater.
*/
Kotlin.Long.prototype.compare = function(other) {
if (this.equals(other)) {
if (this.equalsLong(other)) {
return 0;
}
@@ -478,7 +478,7 @@ Kotlin.Long.prototype.compare = function(other) {
/** @return {!Kotlin.Long} The negation of this value. */
Kotlin.Long.prototype.negate = function() {
if (this.equals(Kotlin.Long.MIN_VALUE)) {
if (this.equalsLong(Kotlin.Long.MIN_VALUE)) {
return Kotlin.Long.MIN_VALUE;
} else {
return this.not().add(Kotlin.Long.ONE);
@@ -542,9 +542,9 @@ Kotlin.Long.prototype.multiply = function(other) {
return Kotlin.Long.ZERO;
}
if (this.equals(Kotlin.Long.MIN_VALUE)) {
if (this.equalsLong(Kotlin.Long.MIN_VALUE)) {
return other.isOdd() ? Kotlin.Long.MIN_VALUE : Kotlin.Long.ZERO;
} else if (other.equals(Kotlin.Long.MIN_VALUE)) {
} else if (other.equalsLong(Kotlin.Long.MIN_VALUE)) {
return this.isOdd() ? Kotlin.Long.MIN_VALUE : Kotlin.Long.ZERO;
}
@@ -614,17 +614,17 @@ Kotlin.Long.prototype.div = function(other) {
return Kotlin.Long.ZERO;
}
if (this.equals(Kotlin.Long.MIN_VALUE)) {
if (other.equals(Kotlin.Long.ONE) ||
other.equals(Kotlin.Long.NEG_ONE)) {
if (this.equalsLong(Kotlin.Long.MIN_VALUE)) {
if (other.equalsLong(Kotlin.Long.ONE) ||
other.equalsLong(Kotlin.Long.NEG_ONE)) {
return Kotlin.Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
} else if (other.equals(Kotlin.Long.MIN_VALUE)) {
} else if (other.equalsLong(Kotlin.Long.MIN_VALUE)) {
return Kotlin.Long.ONE;
} else {
// At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
var halfThis = this.shiftRight(1);
var approx = halfThis.div(other).shiftLeft(1);
if (approx.equals(Kotlin.Long.ZERO)) {
if (approx.equalsLong(Kotlin.Long.ZERO)) {
return other.isNegative() ? Kotlin.Long.ONE : Kotlin.Long.NEG_ONE;
} else {
var rem = this.subtract(other.multiply(approx));
@@ -632,7 +632,7 @@ Kotlin.Long.prototype.div = function(other) {
return result;
}
}
} else if (other.equals(Kotlin.Long.MIN_VALUE)) {
} else if (other.equalsLong(Kotlin.Long.MIN_VALUE)) {
return Kotlin.Long.ZERO;
}
@@ -810,8 +810,8 @@ Kotlin.Long.prototype.shiftRightUnsigned = function(numBits) {
};
// Support for Kotlin
Kotlin.Long.prototype.equals_za3rmp$ = function (other) {
return other instanceof Kotlin.Long && this.equals(other);
Kotlin.Long.prototype.equals = function (other) {
return other instanceof Kotlin.Long && this.equalsLong(other);
};
Kotlin.Long.prototype.compareTo_za3rmp$ = Kotlin.Long.prototype.compare;