JS backend: fix KT-4297 PrimitiveHashMap returns wrong keys (string instead of original type)
This commit is contained in:
@@ -66,4 +66,12 @@ public final class StandardClassesTest extends SingleFileTranslationTest {
|
||||
public void testStringBuilder() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testHashSetTypeOfElement() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testHashMapTypeOfElement() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -232,14 +232,20 @@ public final class TopLevelFIF extends CompositeFIF {
|
||||
) {
|
||||
JetType keyType = callInfo.getResolvedCall().getTypeArguments().values().iterator().next();
|
||||
Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType);
|
||||
String collectionClassName;
|
||||
if (keyTypeName != null &&
|
||||
(NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName) ||
|
||||
keyTypeName.asString().equals("String") ||
|
||||
PrimitiveType.BOOLEAN.getTypeName().equals(keyTypeName))) {
|
||||
collectionClassName = isSet ? "PrimitiveHashSet" : "PrimitiveHashMap";
|
||||
String collectionClassName = null;
|
||||
if (keyTypeName != null) {
|
||||
if (NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName)) {
|
||||
collectionClassName = isSet ? "PrimitiveNumberHashSet" : "PrimitiveNumberHashMap";
|
||||
}
|
||||
else if (PrimitiveType.BOOLEAN.getTypeName().equals(keyTypeName)) {
|
||||
collectionClassName = isSet ? "PrimitiveBooleanHashSet" : "PrimitiveBooleanHashMap";
|
||||
}
|
||||
else if (keyTypeName.asString().equals("String")) {
|
||||
collectionClassName = isSet ? "DefaultPrimitiveHashSet" : "DefaultPrimitiveHashMap";
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (collectionClassName == null ) {
|
||||
collectionClassName = isSet ? "ComplexHashSet" : "ComplexHashMap";
|
||||
}
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
* @constructor
|
||||
* @template Key, Value
|
||||
*/
|
||||
Kotlin.PrimitiveHashMap = Kotlin.createClassNow(Kotlin.Map,
|
||||
Kotlin.AbstractPrimitiveHashMap = Kotlin.createClassNow(Kotlin.Map,
|
||||
function () {
|
||||
this.$size = 0;
|
||||
this.map = Object.create(null);
|
||||
@@ -541,8 +541,11 @@
|
||||
|
||||
return result;
|
||||
},
|
||||
getKeySetClass: function () {
|
||||
throw new Error("Kotlin.AbstractPrimitiveHashMap.getKetSetClass is abstract");
|
||||
},
|
||||
keySet: function () {
|
||||
var result = new Kotlin.PrimitiveHashSet();
|
||||
var result = new (this.getKeySetClass())();
|
||||
var map = this.map;
|
||||
for (var key in map) {
|
||||
//noinspection JSUnfilteredForInLoop
|
||||
@@ -559,6 +562,34 @@
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.DefaultPrimitiveHashMap = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashMap,
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashMap.call(this);
|
||||
}, {
|
||||
getKeySetClass: function () {
|
||||
return Kotlin.DefaultPrimitiveHashSet;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.PrimitiveNumberHashMap = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashMap,
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashMap.call(this);
|
||||
this.$keySetClass$ = Kotlin.PrimitiveNumberHashSet;
|
||||
}, {
|
||||
getKeySetClass: function () {
|
||||
return Kotlin.PrimitiveNumberHashSet;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.PrimitiveBooleanHashMap = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashMap,
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashMap.call(this);
|
||||
}, {
|
||||
getKeySetClass: function () {
|
||||
return Kotlin.PrimitiveBooleanHashSet;
|
||||
}
|
||||
});
|
||||
|
||||
function LinkedHashMap() {
|
||||
Kotlin.ComplexHashMap.call(this);
|
||||
this.orderedKeys = [];
|
||||
@@ -688,13 +719,13 @@ var SetIterator = Kotlin.createClassNow(Kotlin.Iterator,
|
||||
* @extends {Kotlin.Collection.<T>}
|
||||
* @template T
|
||||
*/
|
||||
Kotlin.PrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
||||
Kotlin.AbstractPrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
||||
/** @constructs */
|
||||
function () {
|
||||
this.$size = 0;
|
||||
this.map = {};
|
||||
},
|
||||
/** @lends {Kotlin.PrimitiveHashSet.prototype} */
|
||||
/** @lends {Kotlin.AbstractPrimitiveHashSet.prototype} */
|
||||
{
|
||||
size: function () {
|
||||
return this.$size;
|
||||
@@ -730,11 +761,54 @@ Kotlin.PrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
||||
this.$size = 0;
|
||||
this.map = {};
|
||||
},
|
||||
convertKeyToKeyType: function (key) {
|
||||
throw new Error("Kotlin.AbstractPrimitiveHashSet.convertKeyToKeyType is abstract");
|
||||
},
|
||||
toArray: function () {
|
||||
var result = Object.keys(this.map);
|
||||
for(var i=0; i<result.length; i++) {
|
||||
result[i] = this.convertKeyToKeyType(result[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.DefaultPrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashSet,
|
||||
/** @constructs */
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashSet.call(this);
|
||||
},
|
||||
{
|
||||
/** @lends {Kotlin.DefaultPrimitiveHashSet.prototype} */
|
||||
toArray: function () {
|
||||
return Object.keys(this.map);
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.PrimitiveNumberHashSet = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashSet,
|
||||
/** @constructs */
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashSet.call(this);
|
||||
},
|
||||
/** @lends {Kotlin.PrimitiveNumberHashSet.prototype} */
|
||||
{
|
||||
convertKeyToKeyType: function (key) {
|
||||
return +key;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.PrimitiveBooleanHashSet = Kotlin.createClassNow(Kotlin.AbstractPrimitiveHashSet,
|
||||
/** @constructs */
|
||||
function () {
|
||||
Kotlin.AbstractPrimitiveHashSet.call(this);
|
||||
},
|
||||
/** @lends {Kotlin.PrimitiveBooleanHashSet.prototype} */
|
||||
{
|
||||
convertKeyToKeyType: function (key) {
|
||||
return key == "true";
|
||||
}
|
||||
});
|
||||
|
||||
(function () {
|
||||
/**
|
||||
* @class
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package foo
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
native fun typeof(a: Any): String = noImpl
|
||||
|
||||
fun box(): String {
|
||||
|
||||
val x = true
|
||||
val y = false
|
||||
|
||||
val mapWithIntKeys = HashMap<Int, Int>()
|
||||
mapWithIntKeys[1] = 1
|
||||
assertEquals("number", typeof (mapWithIntKeys.keySet().iterator().next()), "mapWithIntKeys")
|
||||
|
||||
val mapWithShortKeys = HashMap<Short, Int>()
|
||||
mapWithShortKeys[1: Short] = 1
|
||||
assertEquals("number", typeof (mapWithShortKeys.keySet().iterator().next()), "mapWithShortKeys")
|
||||
|
||||
val mapWithByteKeys = HashMap<Byte, Int>()
|
||||
mapWithByteKeys[1: Byte] = 1
|
||||
assertEquals("number", typeof (mapWithByteKeys.keySet().iterator().next()), "mapWithByteKeys")
|
||||
|
||||
val mapWithDoubleKeys = HashMap<Double, Int>()
|
||||
mapWithDoubleKeys[1.0] = 1
|
||||
assertEquals("number", typeof (mapWithDoubleKeys.keySet().iterator().next()), "mapWithDoubleKeys")
|
||||
|
||||
mapWithDoubleKeys.clear()
|
||||
var dNaN = 0.0 / 0.0
|
||||
mapWithDoubleKeys[dNaN] = 100
|
||||
assertEquals(100, mapWithDoubleKeys[dNaN])
|
||||
assertEquals("number", typeof (mapWithDoubleKeys.keySet().iterator().next()), "dNaN")
|
||||
|
||||
mapWithDoubleKeys.clear()
|
||||
var dPositiveInfinity = +1.0 / 0.0
|
||||
mapWithDoubleKeys[dPositiveInfinity] = 100
|
||||
assertEquals(100, mapWithDoubleKeys[dPositiveInfinity])
|
||||
assertEquals("number", typeof (mapWithDoubleKeys.keySet().iterator().next()), "dPositiveInfinity")
|
||||
|
||||
mapWithDoubleKeys.clear()
|
||||
var dNegativeInfinity = -1.0 / 0.0
|
||||
mapWithDoubleKeys[dNegativeInfinity] = 100
|
||||
assertEquals(100, mapWithDoubleKeys[dNegativeInfinity])
|
||||
assertEquals("number", typeof (mapWithDoubleKeys.keySet().iterator().next()), "dNegativeInfinity")
|
||||
|
||||
val mapWithFloatKeys = HashMap<Float, Int>()
|
||||
mapWithFloatKeys[1.0f] = 1
|
||||
assertEquals("number", typeof (mapWithFloatKeys.keySet().iterator().next()), "mapWithFloatKeys")
|
||||
|
||||
mapWithFloatKeys.clear()
|
||||
var fNaN: Float = 0.0f / 0.0f
|
||||
mapWithFloatKeys[dNaN] = 100
|
||||
assertEquals(100, mapWithFloatKeys[dNaN])
|
||||
assertEquals("number", typeof (mapWithFloatKeys.keySet().iterator().next()), "fNaN")
|
||||
|
||||
mapWithFloatKeys.clear()
|
||||
var fPositiveInfinity = +1.0f / 0.0f
|
||||
mapWithFloatKeys[fPositiveInfinity] = 100
|
||||
assertEquals(100, mapWithFloatKeys[fPositiveInfinity])
|
||||
assertEquals("number", typeof (mapWithFloatKeys.keySet().iterator().next()), "fPositiveInfinity")
|
||||
|
||||
mapWithFloatKeys.clear()
|
||||
var NegativeInfinity = -1.0f / 0.0f
|
||||
mapWithFloatKeys[NegativeInfinity] = 100
|
||||
assertEquals(100, mapWithFloatKeys[NegativeInfinity])
|
||||
assertEquals("number", typeof (mapWithFloatKeys.keySet().iterator().next()), "fNegativeInfinity")
|
||||
|
||||
val mapWithCharKeys = HashMap<Char, Int>()
|
||||
mapWithCharKeys['A'] = 1
|
||||
assertEquals("number", typeof (mapWithCharKeys.keySet().iterator().next()), "mapWithCharKeys")
|
||||
|
||||
val mapWithLongKeys = HashMap<Long, Int>()
|
||||
mapWithLongKeys[1L] = 1
|
||||
assertEquals("number", typeof (mapWithLongKeys.keySet().iterator().next()), "mapWithLongKeys")
|
||||
|
||||
val mapWithBooleanKeys = HashMap<Boolean, Int>()
|
||||
mapWithBooleanKeys[true] = 1
|
||||
assertEquals("boolean", typeof (mapWithBooleanKeys.keySet().iterator().next()), "mapWithBooleanKeys")
|
||||
|
||||
val mapWithStringKeys = HashMap<String, Int>()
|
||||
mapWithStringKeys["key"] = 1
|
||||
assertEquals("string", typeof (mapWithStringKeys.keySet().iterator().next()), "mapWithStringKeys")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package foo
|
||||
|
||||
import java.util.HashSet
|
||||
|
||||
native fun typeof(a: Any): String = noImpl
|
||||
|
||||
fun box(): String {
|
||||
|
||||
val x = true
|
||||
val y = false
|
||||
|
||||
val intSet = HashSet<Int>()
|
||||
intSet.add(1)
|
||||
assertEquals("number", typeof (intSet.iterator().next()), "intSet")
|
||||
|
||||
val shortSet = HashSet<Short>()
|
||||
shortSet.add(1: Short)
|
||||
assertEquals("number", typeof (shortSet.iterator().next()), "shortSet")
|
||||
|
||||
val byteSet = HashSet<Byte>()
|
||||
byteSet.add(1: Byte)
|
||||
assertEquals("number", typeof (byteSet.iterator().next()), "byteSet")
|
||||
|
||||
val doubleSet = HashSet<Double>()
|
||||
doubleSet.add(1.0)
|
||||
assertEquals("number", typeof (doubleSet.iterator().next()), "doubleSet")
|
||||
|
||||
doubleSet.clear()
|
||||
doubleSet.add(0.0 / 0.0)
|
||||
assertEquals("number", typeof (doubleSet.iterator().next()), "dNaN")
|
||||
|
||||
doubleSet.clear()
|
||||
doubleSet.add(1.0 / 0.0)
|
||||
assertEquals("number", typeof (doubleSet.iterator().next()), "dPositiveInfinity")
|
||||
|
||||
doubleSet.clear()
|
||||
doubleSet.add(-1.0 / 0.0)
|
||||
assertEquals("number", typeof (doubleSet.iterator().next()), "dNegativeInfinity")
|
||||
|
||||
val floatSet = HashSet<Float>()
|
||||
floatSet.add(1.0f)
|
||||
assertEquals("number", typeof (floatSet.iterator().next()), "floatSet")
|
||||
|
||||
floatSet.clear()
|
||||
floatSet.add(0.0f / 0.0f)
|
||||
assertEquals("number", typeof (floatSet.iterator().next()), "fNaN")
|
||||
|
||||
floatSet.clear()
|
||||
floatSet.add(+1.0f / 0.0f)
|
||||
assertEquals("number", typeof (floatSet.iterator().next()), "fPositiveInfinity")
|
||||
|
||||
floatSet.clear()
|
||||
floatSet.add(-1.0f / 0.0f)
|
||||
assertEquals("number", typeof (floatSet.iterator().next()), "fNegativeInfinity")
|
||||
|
||||
val charSet = HashSet<Char>()
|
||||
charSet.add('A')
|
||||
assertEquals("number", typeof (charSet.iterator().next()), "charSet")
|
||||
|
||||
val longSet = HashSet<Long>()
|
||||
longSet.add(1L)
|
||||
assertEquals("number", typeof (longSet.iterator().next()), "longSet")
|
||||
|
||||
val booleanSet = HashSet<Boolean>()
|
||||
booleanSet.add(true)
|
||||
assertEquals("boolean", typeof (booleanSet.iterator().next()), "booleanSet")
|
||||
|
||||
val stringSet = HashSet<String>()
|
||||
stringSet.add("text")
|
||||
assertEquals("string", typeof (stringSet.iterator().next()), "stringSet")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user