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 {
|
public void testStringBuilder() throws Exception {
|
||||||
checkFooBoxIsOk();
|
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();
|
JetType keyType = callInfo.getResolvedCall().getTypeArguments().values().iterator().next();
|
||||||
Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType);
|
Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType);
|
||||||
String collectionClassName;
|
String collectionClassName = null;
|
||||||
if (keyTypeName != null &&
|
if (keyTypeName != null) {
|
||||||
(NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName) ||
|
if (NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName)) {
|
||||||
keyTypeName.asString().equals("String") ||
|
collectionClassName = isSet ? "PrimitiveNumberHashSet" : "PrimitiveNumberHashMap";
|
||||||
PrimitiveType.BOOLEAN.getTypeName().equals(keyTypeName))) {
|
}
|
||||||
collectionClassName = isSet ? "PrimitiveHashSet" : "PrimitiveHashMap";
|
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";
|
collectionClassName = isSet ? "ComplexHashSet" : "ComplexHashMap";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -481,7 +481,7 @@
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @template Key, Value
|
* @template Key, Value
|
||||||
*/
|
*/
|
||||||
Kotlin.PrimitiveHashMap = Kotlin.createClassNow(Kotlin.Map,
|
Kotlin.AbstractPrimitiveHashMap = Kotlin.createClassNow(Kotlin.Map,
|
||||||
function () {
|
function () {
|
||||||
this.$size = 0;
|
this.$size = 0;
|
||||||
this.map = Object.create(null);
|
this.map = Object.create(null);
|
||||||
@@ -541,8 +541,11 @@
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
getKeySetClass: function () {
|
||||||
|
throw new Error("Kotlin.AbstractPrimitiveHashMap.getKetSetClass is abstract");
|
||||||
|
},
|
||||||
keySet: function () {
|
keySet: function () {
|
||||||
var result = new Kotlin.PrimitiveHashSet();
|
var result = new (this.getKeySetClass())();
|
||||||
var map = this.map;
|
var map = this.map;
|
||||||
for (var key in map) {
|
for (var key in map) {
|
||||||
//noinspection JSUnfilteredForInLoop
|
//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() {
|
function LinkedHashMap() {
|
||||||
Kotlin.ComplexHashMap.call(this);
|
Kotlin.ComplexHashMap.call(this);
|
||||||
this.orderedKeys = [];
|
this.orderedKeys = [];
|
||||||
@@ -688,13 +719,13 @@ var SetIterator = Kotlin.createClassNow(Kotlin.Iterator,
|
|||||||
* @extends {Kotlin.Collection.<T>}
|
* @extends {Kotlin.Collection.<T>}
|
||||||
* @template T
|
* @template T
|
||||||
*/
|
*/
|
||||||
Kotlin.PrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
Kotlin.AbstractPrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
||||||
/** @constructs */
|
/** @constructs */
|
||||||
function () {
|
function () {
|
||||||
this.$size = 0;
|
this.$size = 0;
|
||||||
this.map = {};
|
this.map = {};
|
||||||
},
|
},
|
||||||
/** @lends {Kotlin.PrimitiveHashSet.prototype} */
|
/** @lends {Kotlin.AbstractPrimitiveHashSet.prototype} */
|
||||||
{
|
{
|
||||||
size: function () {
|
size: function () {
|
||||||
return this.$size;
|
return this.$size;
|
||||||
@@ -730,11 +761,54 @@ Kotlin.PrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
|
|||||||
this.$size = 0;
|
this.$size = 0;
|
||||||
this.map = {};
|
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 () {
|
toArray: function () {
|
||||||
return Object.keys(this.map);
|
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 () {
|
(function () {
|
||||||
/**
|
/**
|
||||||
* @class
|
* @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