KT-9377 Support is-checks for read-only collections
Intrinsics for is/as/as? with mutable Kotlin collections and related types.
This commit is contained in:
@@ -36,9 +36,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.*;
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsPackage;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -3751,7 +3749,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
v.mark(ok);
|
||||
}
|
||||
|
||||
generateCheckCastInstruction(rightType);
|
||||
generateCheckCastInstruction(rightType, opToken == JetTokens.AS_SAFE);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
@@ -3826,14 +3824,16 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
private void generateInstanceOfInstruction(@NotNull JetType jetType) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
|
||||
v.instanceOf(type);
|
||||
InstanceOf.instanceOf(v, jetType, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateCheckCastInstruction(@NotNull JetType jetType) {
|
||||
private StackValue generateCheckCastInstruction(@NotNull JetType jetType, boolean safeAs) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
|
||||
v.checkcast(type);
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType,
|
||||
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
|
||||
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
|
||||
CheckCast.checkcast(v, jetType, type, safeAs);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.google.common.collect.ImmutableSet
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.CheckCast
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.InstanceOf
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -36,13 +38,15 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
companion object {
|
||||
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
|
||||
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
|
||||
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
|
||||
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
|
||||
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
|
||||
public val CLASS_LITERAL_MARKER_METHOD_NAME: String = "reifyClassLiteral"
|
||||
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
|
||||
|
||||
private val PARAMETRISED_MARKERS = ImmutableSet.of(
|
||||
NEW_ARRAY_MARKER_METHOD_NAME, CHECKCAST_MARKER_METHOD_NAME,
|
||||
NEW_ARRAY_MARKER_METHOD_NAME,
|
||||
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
|
||||
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME,
|
||||
CLASS_LITERAL_MARKER_METHOD_NAME
|
||||
)
|
||||
@@ -134,15 +138,18 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
|
||||
val asmType = mapping.asmType
|
||||
if (asmType != null) {
|
||||
val jetType = mapping.type ?: return null
|
||||
|
||||
// process* methods return false if marker should be reified further
|
||||
// or it's invalid (may be emitted explicitly in code)
|
||||
// they return true if instruction is reified and marker can be deleted
|
||||
if (when (insn.name) {
|
||||
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
|
||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, asmType)
|
||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, asmType)
|
||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = false)
|
||||
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = true)
|
||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType)
|
||||
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
|
||||
CLASS_LITERAL_MARKER_METHOD_NAME -> processClassLiteral(insn, asmType, instructions, mapping.type!!)
|
||||
CLASS_LITERAL_MARKER_METHOD_NAME -> processClassLiteral(insn, instructions, jetType, asmType)
|
||||
else -> false
|
||||
}) {
|
||||
instructions.remove(insn.getPrevious()!!)
|
||||
@@ -159,11 +166,29 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||
|
||||
private fun processCheckcast(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.CHECKCAST)
|
||||
private fun processCheckcast(insn: MethodInsnNode, instructions: InsnList, jetType: JetType, asmType: Type, safe: Boolean) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
CheckCast.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processInstanceof(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.INSTANCEOF)
|
||||
private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: JetType, asmType: Type) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
InstanceOf.instanceOf(instanceofInsn, instructions, jetType, asmType)
|
||||
return true
|
||||
}
|
||||
|
||||
inline private fun rewriteNextTypeInsn(
|
||||
marker: MethodInsnNode,
|
||||
expectedNextOpcode: Int,
|
||||
rewrite: (AbstractInsnNode) -> Boolean
|
||||
): Boolean {
|
||||
val next = marker.next ?: return false
|
||||
if (next.opcode != expectedNextOpcode) return false
|
||||
return rewrite(next)
|
||||
}
|
||||
|
||||
private fun processNextTypeInsn(insn: MethodInsnNode, parameter: Type, expectedNextOpcode: Int): Boolean {
|
||||
if (insn.getNext()?.getOpcode() != expectedNextOpcode) return false
|
||||
@@ -178,7 +203,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processClassLiteral(insn: MethodInsnNode, parameter: Type, instructions: InsnList, type: JetType): Boolean {
|
||||
private fun processClassLiteral(insn: MethodInsnNode, instructions: InsnList, type: JetType, parameter: Type): Boolean {
|
||||
val next = insn.next
|
||||
if (next !is FieldInsnNode || next.opcode != Opcodes.GETSTATIC) return false
|
||||
val descriptor = type.constructor.declarationDescriptor!!
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode
|
||||
|
||||
object CheckCast {
|
||||
private val INTRINSICS_CLASS = "kotlin/jvm/internal/Intrinsics"
|
||||
|
||||
private val CHECKCAST_METHOD_NAME = hashMapOf(
|
||||
"kotlin.MutableIterator" to "asMutableIterator",
|
||||
"kotlin.MutableIterable" to "asMutableIterable",
|
||||
"kotlin.MutableCollection" to "asMutableCollection",
|
||||
"kotlin.MutableList" to "asMutableList",
|
||||
"kotlin.MutableListIterator" to "asMutableListIterator",
|
||||
"kotlin.MutableSet" to "asMutableSet",
|
||||
"kotlin.MutableMap" to "asMutableMap",
|
||||
"kotlin.MutableMap.MutableEntry" to "asMutableMapEntry"
|
||||
)
|
||||
|
||||
private val SAFE_CHECKCAST_METHOD_NAME = hashMapOf(
|
||||
"kotlin.MutableIterator" to "safeAsMutableIterator",
|
||||
"kotlin.MutableIterable" to "safeAsMutableIterable",
|
||||
"kotlin.MutableCollection" to "safeAsMutableCollection",
|
||||
"kotlin.MutableList" to "safeAsMutableList",
|
||||
"kotlin.MutableListIterator" to "safeAsMutableListIterator",
|
||||
"kotlin.MutableSet" to "safeAsMutableSet",
|
||||
"kotlin.MutableMap" to "safeAsMutableMap",
|
||||
"kotlin.MutableMap.MutableEntry" to "safeAsMutableMapEntry"
|
||||
)
|
||||
|
||||
public @JvmStatic fun checkcast(v: InstructionAdapter, jetType: JetType, boxedAsmType: Type, safe: Boolean) {
|
||||
val intrinsicMethodName = getCheckcastIntrinsicMethodName(jetType, safe)
|
||||
if (intrinsicMethodName == null) {
|
||||
v.checkcast(boxedAsmType)
|
||||
}
|
||||
else {
|
||||
val signature = getCheckcastIntrinsicMethodSignature(boxedAsmType)
|
||||
v.invokestatic(INTRINSICS_CLASS, intrinsicMethodName, signature, false)
|
||||
}
|
||||
}
|
||||
|
||||
public @JvmStatic fun checkcast(checkcastInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type, safe: Boolean) {
|
||||
val intrinsicMethodName = getCheckcastIntrinsicMethodName(jetType, safe)
|
||||
if (intrinsicMethodName == null) {
|
||||
checkcastInsn.desc = asmType.internalName
|
||||
}
|
||||
else {
|
||||
val signature = getCheckcastIntrinsicMethodSignature(asmType)
|
||||
val invokeNode = MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, intrinsicMethodName, signature, false)
|
||||
instructions.insertBefore(checkcastInsn, invokeNode)
|
||||
instructions.remove(checkcastInsn)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCheckcastIntrinsicMethodName(jetType: JetType, safe: Boolean): String? {
|
||||
val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null
|
||||
val classFqName = DescriptorUtils.getFqName(classDescriptor).asString()
|
||||
return if (safe) SAFE_CHECKCAST_METHOD_NAME[classFqName] else CHECKCAST_METHOD_NAME[classFqName]
|
||||
}
|
||||
|
||||
private fun getCheckcastIntrinsicMethodSignature(asmType: Type): String =
|
||||
"(Ljava/lang/Object;)${asmType.descriptor}"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode
|
||||
|
||||
object InstanceOf {
|
||||
private val INTRINSICS_CLASS = "kotlin/jvm/internal/Intrinsics"
|
||||
|
||||
private val INSTANCEOF_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z"
|
||||
|
||||
private val INSTANCEOF_METHOD_NAME = hashMapOf(
|
||||
"kotlin.MutableIterator" to "isMutableIterator",
|
||||
"kotlin.MutableIterable" to "isMutableIterable",
|
||||
"kotlin.MutableCollection" to "isMutableCollection",
|
||||
"kotlin.MutableList" to "isMutableList",
|
||||
"kotlin.MutableListIterator" to "isMutableListIterator",
|
||||
"kotlin.MutableSet" to "isMutableSet",
|
||||
"kotlin.MutableMap" to "isMutableMap",
|
||||
"kotlin.MutableMap.MutableEntry" to "isMutableMapEntry"
|
||||
)
|
||||
|
||||
public @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: JetType, boxedAsmType: Type) {
|
||||
val intrinsicMethodName = getInstanceOfIntrinsicMethodName(jetType)
|
||||
if (intrinsicMethodName == null) {
|
||||
v.instanceOf(boxedAsmType)
|
||||
}
|
||||
else {
|
||||
v.invokestatic(INTRINSICS_CLASS, intrinsicMethodName, INSTANCEOF_METHOD_SIGNATURE, false)
|
||||
}
|
||||
}
|
||||
|
||||
public @JvmStatic fun instanceOf(instanceofInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type) {
|
||||
val intrinsicMethodName = getInstanceOfIntrinsicMethodName(jetType)
|
||||
if (intrinsicMethodName == null) {
|
||||
instanceofInsn.desc = asmType.internalName
|
||||
}
|
||||
else {
|
||||
val invokeNode = MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, intrinsicMethodName, INSTANCEOF_METHOD_SIGNATURE, false)
|
||||
instructions.insertBefore(instanceofInsn, invokeNode)
|
||||
instructions.remove(instanceofInsn)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInstanceOfIntrinsicMethodName(jetType: JetType): String? {
|
||||
val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null
|
||||
val classFqName = DescriptorUtils.getFqName(classDescriptor).asString()
|
||||
return INSTANCEOF_METHOD_NAME[classFqName]
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,14 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val collection = MyCollection<String>() as MutableCollection<String>
|
||||
val myCollection = MyCollection<String>()
|
||||
val collection = myCollection as java.util.Collection<String>
|
||||
|
||||
expectUoe { collection.add("") }
|
||||
expectUoe { collection.remove("") }
|
||||
expectUoe { collection.addAll(collection) }
|
||||
expectUoe { collection.removeAll(collection) }
|
||||
expectUoe { collection.retainAll(collection) }
|
||||
expectUoe { collection.addAll(myCollection) }
|
||||
expectUoe { collection.removeAll(myCollection) }
|
||||
expectUoe { collection.retainAll(myCollection) }
|
||||
expectUoe { collection.clear() }
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -5,7 +5,7 @@ class MyIterator<T>(val v: T): Iterator<T> {
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
(MyIterator<String>("") as MutableIterator<String>).remove()
|
||||
(MyIterator<String>("") as java.util.Iterator<String>).remove()
|
||||
throw AssertionError()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
|
||||
@@ -6,6 +6,6 @@ class MyIterator<T>(val v: T): Iterator<T> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
(MyIterator<String>("") as MutableIterator<String>).remove()
|
||||
(MyIterator<String>("") as java.util.Iterator<String>).remove()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyList<String>() as MutableList<String>
|
||||
val list = MyList<String>() as java.util.List<String>
|
||||
|
||||
expectUoe { list.add("") }
|
||||
expectUoe { list.remove("") }
|
||||
|
||||
@@ -16,7 +16,7 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyListIterator<String>() as MutableListIterator<String>
|
||||
val list = MyListIterator<String>() as java.util.ListIterator<String>
|
||||
|
||||
expectUoe { list.set("") }
|
||||
expectUoe { list.add("") }
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ class MyList<T>(val v: T): List<T> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyList<String>("") as MutableList<String>
|
||||
val list = MyList<String>("") as java.util.List<String>
|
||||
|
||||
list.add("")
|
||||
list.remove("")
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class MyList<T>(v: T): Super<T>(v), List<T> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyList<String>("") as MutableList<String>
|
||||
val list = MyList<String>("") as java.util.List<String>
|
||||
|
||||
list.add("")
|
||||
list.remove("")
|
||||
|
||||
+3
-2
@@ -18,11 +18,12 @@ fun expectUoe(block: () -> Unit) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val map = MyMap<String, Int>() as MutableMap<String, Int>
|
||||
val myMap = MyMap<String, Int>()
|
||||
val map = myMap as java.util.Map<String, Int>
|
||||
|
||||
expectUoe { map.put("", 1) }
|
||||
expectUoe { map.remove("") }
|
||||
expectUoe { map.putAll(map) }
|
||||
expectUoe { map.putAll(myMap) }
|
||||
expectUoe { map.clear() }
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -7,7 +7,7 @@ class MyMapEntry<K, V>: Map.Entry<K, V> {
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
(MyMapEntry<String, Int>() as MutableMap.MutableEntry<String, Int>).setValue(1)
|
||||
(MyMapEntry<String, Int>() as java.util.Map.Entry<String, Int>).setValue(1)
|
||||
throw AssertionError()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
|
||||
@@ -8,7 +8,7 @@ class MyMapEntry<K, V>: Map.Entry<K, V> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
(MyMapEntry<String, Int>() as MutableMap.MutableEntry<String, Int>).setValue(1)
|
||||
(MyMapEntry<String, Int>() as java.util.Map.Entry<String, Int>).setValue(1)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+3
-2
@@ -15,11 +15,12 @@ class MyMap<K, V>: Map<K, V> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val map = MyMap<String, Int>() as MutableMap<String, Int>
|
||||
val myMap = MyMap<String, Int>()
|
||||
val map = myMap as java.util.Map<String, Int>
|
||||
|
||||
map.put("", 1)
|
||||
map.remove("")
|
||||
map.putAll(map)
|
||||
map.putAll(myMap)
|
||||
map.clear()
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -23,7 +23,7 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyList() as MutableList<String>
|
||||
val list = MyList() as java.util.List<String>
|
||||
|
||||
expectUoe { list.add("") }
|
||||
expectUoe { list.remove("") }
|
||||
|
||||
@@ -11,7 +11,7 @@ class B(var result: String) : A() {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = B("Fail") as MutableIterator<String>
|
||||
val a = B("Fail") as java.util.Iterator<String>
|
||||
a.next()
|
||||
a.hasNext()
|
||||
a.remove()
|
||||
|
||||
@@ -13,7 +13,7 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A<String>() as MutableList<String>
|
||||
val a = A<String>() as java.util.List<String>
|
||||
expectUoe { a.add("") }
|
||||
expectUoe { a.remove("") }
|
||||
expectUoe { a.addAll(a) }
|
||||
@@ -28,7 +28,7 @@ fun box(): String {
|
||||
a.listIterator(0)
|
||||
a.subList(0, 0)
|
||||
|
||||
val b = B() as MutableList<String>
|
||||
val b = B() as java.util.List<String>
|
||||
expectUoe { b.add("") }
|
||||
expectUoe { b.remove("") }
|
||||
expectUoe { b.addAll(b) }
|
||||
|
||||
@@ -21,7 +21,7 @@ fun box(): String {
|
||||
val a = C()
|
||||
if (!a.add("")) return "Fail 1"
|
||||
if (!(a as Addable).add("")) return "Fail 2"
|
||||
if (!(a as MutableList<String>).add("")) return "Fail 3"
|
||||
if (!(a as java.util.List<String>).add("")) return "Fail 3"
|
||||
return "OK"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "Fail: no stub method should be generated"
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ class S : Set<String>, SetStringImpl() {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val s = S() as MutableSet<String>
|
||||
val s = S() as java.util.Set<String>
|
||||
s.add("")
|
||||
s.remove("")
|
||||
s.clear()
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ fun expectUoe(block: () -> Any) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A<Int, Int, Int>() as MutableSet<Int>
|
||||
val a = A<Int, Int, Int>() as java.util.Set<Int>
|
||||
|
||||
a.iterator()
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class MyCollection<T> : Collection<List<Iterator<T>>> {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = MyCollection<String>() as MutableCollection<List<Iterator<String>>>
|
||||
val c = MyCollection<String>() as java.util.Collection<List<Iterator<String>>>
|
||||
try {
|
||||
c.add(ArrayList())
|
||||
return "Fail"
|
||||
|
||||
@@ -5,7 +5,7 @@ class MyIterator<E : Number> : Iterator<E> {
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
(MyIterator<Int>() as MutableIterator<Number>).remove()
|
||||
(MyIterator<Int>() as java.util.Iterator<Number>).remove()
|
||||
return "Fail"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
inline fun asFailsWithCCE(operation: String, block: () -> Unit) {
|
||||
try {
|
||||
block()
|
||||
}
|
||||
catch (e: java.lang.ClassCastException) {
|
||||
return
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should throw ClassCastException, got $e")
|
||||
}
|
||||
throw AssertionError("$operation: should throw ClassCastException, no exception thrown")
|
||||
}
|
||||
|
||||
inline fun asSucceeds(operation: String, block: () -> Unit) {
|
||||
try {
|
||||
block()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should not throw exceptions, got $e")
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
asFailsWithCCE("itr as MutableIterator") { itr as MutableIterator<*> }
|
||||
asSucceeds("mitr as MutableIterator") { mitr as MutableIterator<*> }
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
asFailsWithCCE("litr as MutableIterator") { litr as MutableIterator<*> }
|
||||
asFailsWithCCE("litr as MutableListIterator") { litr as MutableListIterator<*> }
|
||||
asSucceeds("mlitr as MutableIterator") { mlitr as MutableIterator<*> }
|
||||
asSucceeds("mlitr as MutableListIterator") { mlitr as MutableListIterator<*> }
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
asFailsWithCCE("it as MutableIterable") { it as MutableIterable<*> }
|
||||
asSucceeds("mit as MutableIterable") { mit as MutableIterable<*> }
|
||||
asSucceeds("arrayList as MutableIterable") { arrayList as MutableIterable<*> }
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
asFailsWithCCE("coll as MutableIterable") { coll as MutableIterable<*> }
|
||||
asFailsWithCCE("coll as MutableCollection") { coll as MutableCollection<*> }
|
||||
asSucceeds("mcoll as MutableIterable") { mcoll as MutableIterable<*> }
|
||||
asSucceeds("mcoll as MutableCollection") { mcoll as MutableCollection<*> }
|
||||
asSucceeds("arrayList as MutableCollection") { arrayList as MutableCollection<*> }
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
asFailsWithCCE("list as MutableIterable") { list as MutableIterable<*> }
|
||||
asFailsWithCCE("list as MutableCollection") { list as MutableCollection<*> }
|
||||
asFailsWithCCE("list as MutableList") { list as MutableList<*> }
|
||||
asSucceeds("mlist as MutableIterable") { mlist as MutableIterable<*> }
|
||||
asSucceeds("mlist as MutableCollection") { mlist as MutableCollection<*> }
|
||||
asSucceeds("mlist as MutableList") { mlist as MutableList<*> }
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
asFailsWithCCE("set as MutableIterable") { set as MutableIterable<*> }
|
||||
asFailsWithCCE("set as MutableCollection") { set as MutableCollection<*> }
|
||||
asFailsWithCCE("set as MutableSet") { set as MutableSet<*> }
|
||||
asSucceeds("mset as MutableIterable") { mset as MutableIterable<*> }
|
||||
asSucceeds("mset as MutableCollection") { mset as MutableCollection<*> }
|
||||
asSucceeds("mset as MutableSet") { mset as MutableSet<*> }
|
||||
asSucceeds("hashSet as MutableSet") { hashSet as MutableSet<*> }
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
asFailsWithCCE("map as MutableMap") { map as MutableMap<*, *> }
|
||||
asSucceeds("mmap as MutableMap") { mmap as MutableMap<*, *> }
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
asFailsWithCCE("entry as MutableMap.MutableEntry") { entry as MutableMap.MutableEntry<*, *> }
|
||||
asSucceeds("mentry as MutableMap.MutableEntry") { mentry as MutableMap.MutableEntry<*, *> }
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
asSucceeds("hashMapEntry as MutableMap.MutableEntry") { hashMapEntry as MutableMap.MutableEntry<*, *> }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
assert(itr !is MutableIterator<*>) { "Itr should satisfy '!is MutableIterator'" }
|
||||
assert(mitr is MutableIterator<*>) { "MItr should satisfy 'is MutableIterator'" }
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
assert(litr !is MutableIterator<*>) { "LItr should satisfy '!is MutableIterator'" }
|
||||
assert(litr !is MutableListIterator<*>) { "LItr should satisfy '!is MutableListIterator'" }
|
||||
assert(mlitr is MutableListIterator<*>) { "MLItr should satisfy 'is MutableListIterator'" }
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
assert(it !is MutableIterable<*>) { "It should satisfy '!is MutableIterable'" }
|
||||
assert(mit is MutableIterable<*>) { "MIt should satisfy 'is MutableIterable'" }
|
||||
assert(arrayList is MutableIterable<*>) { "ArrayList should satisfy 'is MutableIterable'" }
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
assert(coll !is MutableCollection<*>) { "C should satisfy '!is MutableCollection'" }
|
||||
assert(coll !is MutableIterable<*>) { "C should satisfy '!is MutableIterable'" }
|
||||
assert(mcoll is MutableCollection<*>) { "MC should satisfy 'is MutableCollection'" }
|
||||
assert(mcoll is MutableIterable<*>) { "MC should satisfy 'is MutableIterable'" }
|
||||
assert(arrayList is MutableCollection<*>) { "ArrayList should satisfy 'is MutableCollection'" }
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
assert(list !is MutableList<*>) { "L should satisfy '!is MutableList'" }
|
||||
assert(list !is MutableCollection<*>) { "L should satisfy '!is MutableCollection'" }
|
||||
assert(list !is MutableIterable<*>) { "L should satisfy '!is MutableIterable'" }
|
||||
assert(mlist is MutableList<*>) { "ML should satisfy 'is MutableList'" }
|
||||
assert(mlist is MutableCollection<*>) { "ML should satisfy 'is MutableCollection'" }
|
||||
assert(mlist is MutableIterable<*>) { "ML should satisfy 'is MutableIterable'" }
|
||||
assert(arrayList is MutableList<*>) { "ArrayList should satisfy 'is MutableList'" }
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
assert(set !is MutableSet<*>) { "S should satisfy '!is MutableSet'" }
|
||||
assert(set !is MutableCollection<*>) { "S should satisfy '!is MutableCollection'" }
|
||||
assert(set !is MutableIterable<*>) { "S should satisfy '!is MutableIterable'" }
|
||||
assert(mset is MutableSet<*>) { "MS should satisfy 'is MutableSet'" }
|
||||
assert(mset is MutableCollection<*>) { "MS should satisfy 'is MutableCollection'" }
|
||||
assert(mset is MutableIterable<*>) { "MS should satisfy 'is MutableIterable'" }
|
||||
assert(hashSet is MutableSet<*>) { "HashSet should satisfy 'is MutableSet'" }
|
||||
assert(hashSet is MutableCollection<*>) { "HashSet should satisfy 'is MutableCollection'" }
|
||||
assert(hashSet is MutableIterable<*>) { "HashSet should satisfy 'is MutableIterable'" }
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
assert(map !is MutableMap<*, *>) { "M should satisfy '!is MutableMap'" }
|
||||
assert(mmap is MutableMap<*, *>) { "MM should satisfy 'is MutableMap'"}
|
||||
assert(hashMap is MutableMap<*, *>) { "HashMap should satisfy 'is MutableMap'" }
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
assert(entry !is MutableMap.MutableEntry<*, *>) { "ME should satisfy '!is MutableMap.MutableEntry'"}
|
||||
assert(mentry is MutableMap.MutableEntry<*, *>) { "MME should satisfy 'is MutableMap.MutableEntry'"}
|
||||
assert(hashMapEntry is MutableMap.MutableEntry<*, *>) { "HashMap.Entry should satisfy 'is MutableMap.MutableEntry'"}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
inline fun <reified T> reifiedAsSucceeds(x: Any, operation: String) {
|
||||
try {
|
||||
x as T
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should not throw exceptions, got $e")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> reifiedAsFailsWithCCE(x: Any, operation: String) {
|
||||
try {
|
||||
x as T
|
||||
}
|
||||
catch (e: java.lang.ClassCastException) {
|
||||
return
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should throw ClassCastException, got $e")
|
||||
}
|
||||
throw AssertionError("$operation: should fail with CCE, no exception thrown")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableIterator<*>>(itr, "reifiedAs<MutableIterator<*>>(itr)")
|
||||
reifiedAsSucceeds<MutableIterator<*>>(mitr, "reifiedAs<MutableIterator<*>>(mitr)")
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableIterator<*>>(litr, "reifiedAs<MutableIterator<*>>(litr)")
|
||||
reifiedAsFailsWithCCE<MutableListIterator<*>>(litr, "reifiedAs<MutableListIterator<*>>(litr)")
|
||||
reifiedAsSucceeds<MutableListIterator<*>>(mlitr, "reifiedAs<MutableListIterator<*>>(mlitr)")
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableIterable<*>>(it, "reifiedAs<MutableIterable<*>>(it)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(mit, "reifiedAs<MutableIterable<*>>(mit)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(arrayList, "reifiedAs<MutableIterable<*>>(arrayList)")
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableCollection<*>>(coll, "reifiedAs<MutableCollection<*>>(coll)")
|
||||
reifiedAsFailsWithCCE<MutableIterable<*>>(coll, "reifiedAs<MutableIterable<*>>(coll)")
|
||||
reifiedAsSucceeds<MutableCollection<*>>(mcoll, "reifiedAs<MutableCollection<*>>(mcoll)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(mcoll, "reifiedAs<MutableIterable<*>>(mcoll)")
|
||||
reifiedAsSucceeds<MutableCollection<*>>(arrayList, "reifiedAs<MutableCollection<*>>(arrayList)")
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableList<*>>(list, "reifiedAs<MutableList<*>>(list)")
|
||||
reifiedAsFailsWithCCE<MutableCollection<*>>(list, "reifiedAs<MutableCollection<*>>(list)")
|
||||
reifiedAsFailsWithCCE<MutableIterable<*>>(list, "reifiedAs<MutableIterable<*>>(list)")
|
||||
reifiedAsSucceeds<MutableList<*>>(mlist, "reifiedAs<MutableList<*>>(mlist)")
|
||||
reifiedAsSucceeds<MutableCollection<*>>(mlist, "reifiedAs<MutableCollection<*>>(mlist)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(mlist, "reifiedAs<MutableIterable<*>>(mlist)")
|
||||
reifiedAsSucceeds<MutableList<*>>(arrayList, "reifiedAs<MutableList<*>>(arrayList)")
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableSet<*>>(set, "reifiedAs<MutableSet<*>>(set)")
|
||||
reifiedAsFailsWithCCE<MutableCollection<*>>(set, "reifiedAs<MutableCollection<*>>(set)")
|
||||
reifiedAsFailsWithCCE<MutableIterable<*>>(set, "reifiedAs<MutableIterable<*>>(set)")
|
||||
reifiedAsSucceeds<MutableSet<*>>(mset, "reifiedAs<MutableSet<*>>(mset)")
|
||||
reifiedAsSucceeds<MutableCollection<*>>(mset, "reifiedAs<MutableCollection<*>>(mset)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(mset, "reifiedAs<MutableIterable<*>>(mset)")
|
||||
reifiedAsSucceeds<MutableSet<*>>(hashSet, "reifiedAs<MutableSet<*>>(hashSet)")
|
||||
reifiedAsSucceeds<MutableCollection<*>>(hashSet, "reifiedAs<MutableCollection<*>>(hashSet)")
|
||||
reifiedAsSucceeds<MutableIterable<*>>(hashSet, "reifiedAs<MutableIterable<*>>(hashSet)")
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableMap<*, *>>(map, "reifiedAs<MutableMap<*, *>>(map)")
|
||||
reifiedAsSucceeds<MutableMap<*, *>>(mmap, "reifiedAs<MutableMap<*, *>>(mmap)")
|
||||
reifiedAsSucceeds<MutableMap<*, *>>(hashMap, "reifiedAs<MutableMap<*, *>>(hashMap)")
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
reifiedAsFailsWithCCE<MutableMap.MutableEntry<*, *>>(entry, "reifiedAs<MutableMap.MutableEntry<*, *>>(entry)")
|
||||
reifiedAsSucceeds<MutableMap.MutableEntry<*, *>>(mentry, "reifiedAs<MutableMap.MutableEntry<*, *>>(mentry)")
|
||||
reifiedAsSucceeds<MutableMap.MutableEntry<*, *>>(hashMapEntry, "reifiedAs<MutableMap.MutableEntry<*, *>>(hashMapEntry)")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
inline fun <reified T> reifiedIs(x: Any): Boolean = x is T
|
||||
inline fun <reified T> reifiedIsNot(x: Any): Boolean = x !is T
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
assert(reifiedIsNot<MutableIterator<*>>(itr)) { "reifiedIsNot<MutableIterator<*>>(itr)" }
|
||||
assert(reifiedIs<MutableIterator<*>>(mitr)) { "reifiedIs<MutableIterator<*>>(mitr)" }
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
assert(reifiedIsNot<MutableIterator<*>>(litr)) { "reifiedIsNot<MutableIterator<*>>(litr)" }
|
||||
assert(reifiedIsNot<MutableListIterator<*>>(litr)) { "reifiedIsNot<MutableListIterator<*>>(litr)" }
|
||||
assert(reifiedIs<MutableListIterator<*>>(mlitr)) { "reifiedIs<MutableListIterator<*>>(mlitr)" }
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
assert(reifiedIsNot<MutableIterable<*>>(it)) { "reifiedIsNot<MutableIterable<*>>(it)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(mit)) { "reifiedIs<MutableIterable<*>>(mit)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(arrayList)) { "reifiedIs<MutableIterable<*>>(arrayList)" }
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
assert(reifiedIsNot<MutableCollection<*>>(coll)) { "reifiedIsNot<MutableCollection<*>>(coll)" }
|
||||
assert(reifiedIsNot<MutableIterable<*>>(coll)) { "reifiedIsNot<MutableIterable<*>>(coll)" }
|
||||
assert(reifiedIs<MutableCollection<*>>(mcoll)) { "reifiedIs<MutableCollection<*>>(mcoll)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(mcoll)) { "reifiedIs<MutableIterable<*>>(mcoll)" }
|
||||
assert(reifiedIs<MutableCollection<*>>(arrayList)) { "reifiedIs<MutableCollection<*>>(arrayList)" }
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
assert(reifiedIsNot<MutableList<*>>(list)) { "reifiedIsNot<MutableList<*>>(list)" }
|
||||
assert(reifiedIsNot<MutableCollection<*>>(list)) { "reifiedIsNot<MutableCollection<*>>(list)" }
|
||||
assert(reifiedIsNot<MutableIterable<*>>(list)) { "reifiedIsNot<MutableIterable<*>>(list)" }
|
||||
assert(reifiedIs<MutableList<*>>(mlist)) { "reifiedIs<MutableList<*>>(mlist)" }
|
||||
assert(reifiedIs<MutableCollection<*>>(mlist)) { "reifiedIs<MutableCollection<*>>(mlist)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(mlist)) { "reifiedIs<MutableIterable<*>>(mlist)" }
|
||||
assert(reifiedIs<MutableList<*>>(arrayList)) { "reifiedIs<MutableList<*>>(arrayList)" }
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
assert(reifiedIsNot<MutableSet<*>>(set)) { "reifiedIsNot<MutableSet<*>>(set)" }
|
||||
assert(reifiedIsNot<MutableCollection<*>>(set)) { "reifiedIsNot<MutableCollection<*>>(set)" }
|
||||
assert(reifiedIsNot<MutableIterable<*>>(set)) { "reifiedIsNot<MutableIterable<*>>(set)" }
|
||||
assert(reifiedIs<MutableSet<*>>(mset)) { "reifiedIs<MutableSet<*>>(mset)" }
|
||||
assert(reifiedIs<MutableCollection<*>>(mset)) { "reifiedIs<MutableCollection<*>>(mset)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(mset)) { "reifiedIs<MutableIterable<*>>(mset)" }
|
||||
assert(reifiedIs<MutableSet<*>>(hashSet)) { "reifiedIs<MutableSet<*>>(hashSet)" }
|
||||
assert(reifiedIs<MutableCollection<*>>(hashSet)) { "reifiedIs<MutableCollection<*>>(hashSet)" }
|
||||
assert(reifiedIs<MutableIterable<*>>(hashSet)) { "reifiedIs<MutableIterable<*>>(hashSet)" }
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
assert(reifiedIsNot<MutableMap<*, *>>(map)) { "reifiedIsNot<MutableMap<*, *>>(map)" }
|
||||
assert(reifiedIs<MutableMap<*, *>>(mmap)) { "reifiedIs<MutableMap<*, *>>(mmap)"}
|
||||
assert(reifiedIs<MutableMap<*, *>>(hashMap)) { "reifiedIs<MutableMap<*, *>>(hashMap)" }
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
assert(reifiedIsNot<MutableMap.MutableEntry<*, *>>(entry)) { "reifiedIsNot<MutableMap.MutableEntry<*, *>>(entry)"}
|
||||
assert(reifiedIs<MutableMap.MutableEntry<*, *>>(mentry)) { "reifiedIs<MutableMap.MutableEntry<*, *>>(mentry)"}
|
||||
assert(reifiedIs<MutableMap.MutableEntry<*, *>>(hashMapEntry)) { "reifiedIs<MutableMap.MutableEntry<*, *>>(hashMapEntry)"}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
inline fun <reified T> reifiedSafeAsReturnsNonNull(x: Any?, operation: String) {
|
||||
val y = try {
|
||||
x as? T
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should not throw exceptions, got $e")
|
||||
}
|
||||
if (y == null) {
|
||||
throw AssertionError("$operation: should return non-null, got null")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> reifiedSafeAsReturnsNull(x: Any?, operation: String) {
|
||||
val y = try {
|
||||
x as? T
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw AssertionError("$operation: should not throw exceptions, got $e")
|
||||
}
|
||||
if (y != null) {
|
||||
throw AssertionError("$operation: should return null, got $y")
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableIterator<*>>(itr, "reifiedSafeAs<MutableIterator<*>>(itr)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterator<*>>(mitr, "reifiedSafeAs<MutableIterator<*>>(mitr)")
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableIterator<*>>(litr, "reifiedSafeAs<MutableIterator<*>>(litr)")
|
||||
reifiedSafeAsReturnsNull<MutableListIterator<*>>(litr, "reifiedSafeAs<MutableListIterator<*>>(litr)")
|
||||
reifiedSafeAsReturnsNonNull<MutableListIterator<*>>(mlitr, "reifiedSafeAs<MutableListIterator<*>>(mlitr)")
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableIterable<*>>(it, "reifiedSafeAs<MutableIterable<*>>(it)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(mit, "reifiedSafeAs<MutableIterable<*>>(mit)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(arrayList, "reifiedSafeAs<MutableIterable<*>>(arrayList)")
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableCollection<*>>(coll, "reifiedSafeAs<MutableCollection<*>>(coll)")
|
||||
reifiedSafeAsReturnsNull<MutableIterable<*>>(coll, "reifiedSafeAs<MutableIterable<*>>(coll)")
|
||||
reifiedSafeAsReturnsNonNull<MutableCollection<*>>(mcoll, "reifiedSafeAs<MutableCollection<*>>(mcoll)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(mcoll, "reifiedSafeAs<MutableIterable<*>>(mcoll)")
|
||||
reifiedSafeAsReturnsNonNull<MutableCollection<*>>(arrayList, "reifiedSafeAs<MutableCollection<*>>(arrayList)")
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableList<*>>(list, "reifiedSafeAs<MutableList<*>>(list)")
|
||||
reifiedSafeAsReturnsNull<MutableCollection<*>>(list, "reifiedSafeAs<MutableCollection<*>>(list)")
|
||||
reifiedSafeAsReturnsNull<MutableIterable<*>>(list, "reifiedSafeAs<MutableIterable<*>>(list)")
|
||||
reifiedSafeAsReturnsNonNull<MutableList<*>>(mlist, "reifiedSafeAs<MutableList<*>>(mlist)")
|
||||
reifiedSafeAsReturnsNonNull<MutableCollection<*>>(mlist, "reifiedSafeAs<MutableCollection<*>>(mlist)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(mlist, "reifiedSafeAs<MutableIterable<*>>(mlist)")
|
||||
reifiedSafeAsReturnsNonNull<MutableList<*>>(arrayList, "reifiedSafeAs<MutableList<*>>(arrayList)")
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableSet<*>>(set, "reifiedSafeAs<MutableSet<*>>(set)")
|
||||
reifiedSafeAsReturnsNull<MutableCollection<*>>(set, "reifiedSafeAs<MutableCollection<*>>(set)")
|
||||
reifiedSafeAsReturnsNull<MutableIterable<*>>(set, "reifiedSafeAs<MutableIterable<*>>(set)")
|
||||
reifiedSafeAsReturnsNonNull<MutableSet<*>>(mset, "reifiedSafeAs<MutableSet<*>>(mset)")
|
||||
reifiedSafeAsReturnsNonNull<MutableCollection<*>>(mset, "reifiedSafeAs<MutableCollection<*>>(mset)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(mset, "reifiedSafeAs<MutableIterable<*>>(mset)")
|
||||
reifiedSafeAsReturnsNonNull<MutableSet<*>>(hashSet, "reifiedSafeAs<MutableSet<*>>(hashSet)")
|
||||
reifiedSafeAsReturnsNonNull<MutableCollection<*>>(hashSet, "reifiedSafeAs<MutableCollection<*>>(hashSet)")
|
||||
reifiedSafeAsReturnsNonNull<MutableIterable<*>>(hashSet, "reifiedSafeAs<MutableIterable<*>>(hashSet)")
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableMap<*, *>>(map, "reifiedSafeAs<MutableMap<*, *>>(map)")
|
||||
reifiedSafeAsReturnsNonNull<MutableMap<*, *>>(mmap, "reifiedSafeAs<MutableMap<*, *>>(mmap)")
|
||||
reifiedSafeAsReturnsNonNull<MutableMap<*, *>>(hashMap, "reifiedSafeAs<MutableMap<*, *>>(hashMap)")
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableMap.MutableEntry<*, *>>(entry, "reifiedSafeAs<MutableMap.MutableEntry<*, *>>(entry)")
|
||||
reifiedSafeAsReturnsNonNull<MutableMap.MutableEntry<*, *>>(mentry, "reifiedSafeAs<MutableMap.MutableEntry<*, *>>(mentry)")
|
||||
reifiedSafeAsReturnsNonNull<MutableMap.MutableEntry<*, *>>(hashMapEntry, "reifiedSafeAs<MutableMap.MutableEntry<*, *>>(hashMapEntry)")
|
||||
|
||||
reifiedSafeAsReturnsNull<MutableIterator<*>>(null, "reifiedSafeAs<MutableIterator<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableListIterator<*>>(null, "reifiedSafeAs<MutableListIterator<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableIterable<*>>(null, "reifiedSafeAs<MutableIterable<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableCollection<*>>(null, "reifiedSafeAs<MutableCollection<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableList<*>>(null, "reifiedSafeAs<MutableList<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableSet<*>>(null, "reifiedSafeAs<MutableSet<*>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableMap<*, *>>(null, "reifiedSafeAs<MutableMap<*, *>>(null)")
|
||||
reifiedSafeAsReturnsNull<MutableMap.MutableEntry<*, *>>(null, "reifiedSafeAs<MutableMap.MutableEntry<*, *>>(null)")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import java.util.*
|
||||
|
||||
class Itr : Iterator<String> by ArrayList<String>().iterator()
|
||||
class MItr : MutableIterator<String> by ArrayList<String>().iterator()
|
||||
class LItr : ListIterator<String> by ArrayList<String>().listIterator()
|
||||
class MLItr : MutableListIterator<String> by ArrayList<String>().listIterator()
|
||||
|
||||
class It : Iterable<String> by ArrayList<String>()
|
||||
class MIt : MutableIterable<String> by ArrayList<String>()
|
||||
class C : Collection<String> by ArrayList<String>()
|
||||
class MC : MutableCollection<String> by ArrayList<String>()
|
||||
class L : List<String> by ArrayList<String>()
|
||||
class ML : MutableList<String> by ArrayList<String>()
|
||||
class S : Set<String> by HashSet<String>()
|
||||
class MS : MutableSet<String> by HashSet<String>()
|
||||
|
||||
class M : Map<String, String> by HashMap<String, String>()
|
||||
class MM : MutableMap<String, String> by HashMap<String, String>()
|
||||
|
||||
class ME : Map.Entry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MME : MutableMap.MutableEntry<String, String> {
|
||||
override fun getKey(): String = throw UnsupportedOperationException()
|
||||
override fun getValue(): String = throw UnsupportedOperationException()
|
||||
override fun setValue(value: String): String = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
inline fun safeAsReturnsNull(operation: String, block: () -> Any?) {
|
||||
try {
|
||||
val x = block()
|
||||
assert(x == null) { "$operation: should return null, got $x" }
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
assert(false) { "$operation: should not throw exceptions, got $e" }
|
||||
}
|
||||
}
|
||||
|
||||
inline fun safeAsReturnsNonNull(operation: String, block: () -> Any?) {
|
||||
try {
|
||||
val x = block()
|
||||
assert(x != null) { "$operation: should return non-null" }
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
assert(false) { "$operation: should not throw exceptions, got $e" }
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val itr = Itr() as Any
|
||||
val mitr = MItr()
|
||||
|
||||
safeAsReturnsNull("itr as? MutableIterator") { itr as? MutableIterator<*> }
|
||||
safeAsReturnsNonNull("mitr as? MutableIterator") { mitr as? MutableIterator<*> }
|
||||
|
||||
val litr = LItr() as Any
|
||||
val mlitr = MLItr()
|
||||
|
||||
safeAsReturnsNull("litr as? MutableIterator") { litr as? MutableIterator<*> }
|
||||
safeAsReturnsNull("litr as? MutableListIterator") { litr as? MutableListIterator<*> }
|
||||
safeAsReturnsNonNull("mlitr as? MutableIterator") { mlitr as? MutableIterator<*> }
|
||||
safeAsReturnsNonNull("mlitr as? MutableListIterator") { mlitr as? MutableListIterator<*> }
|
||||
|
||||
val it = It() as Any
|
||||
val mit = MIt()
|
||||
val arrayList = ArrayList<String>()
|
||||
|
||||
safeAsReturnsNull("it as? MutableIterable") { it as? MutableIterable<*> }
|
||||
safeAsReturnsNonNull("mit as? MutableIterable") { mit as? MutableIterable<*> }
|
||||
safeAsReturnsNonNull("arrayList as? MutableIterable") { arrayList as? MutableIterable<*> }
|
||||
|
||||
val coll = C() as Any
|
||||
val mcoll = MC()
|
||||
|
||||
safeAsReturnsNull("coll as? MutableIterable") { coll as? MutableIterable<*> }
|
||||
safeAsReturnsNull("coll as? MutableCollection") { coll as? MutableCollection<*> }
|
||||
safeAsReturnsNonNull("mcoll as? MutableIterable") { mcoll as? MutableIterable<*> }
|
||||
safeAsReturnsNonNull("mcoll as? MutableCollection") { mcoll as? MutableCollection<*> }
|
||||
safeAsReturnsNonNull("arrayList as? MutableCollection") { arrayList as? MutableCollection<*> }
|
||||
|
||||
val list = L() as Any
|
||||
val mlist = ML()
|
||||
|
||||
safeAsReturnsNull("list as? MutableIterable") { list as? MutableIterable<*> }
|
||||
safeAsReturnsNull("list as? MutableCollection") { list as? MutableCollection<*> }
|
||||
safeAsReturnsNull("list as? MutableList") { list as? MutableList<*> }
|
||||
safeAsReturnsNonNull("mlist as? MutableIterable") { mlist as? MutableIterable<*> }
|
||||
safeAsReturnsNonNull("mlist as? MutableCollection") { mlist as? MutableCollection<*> }
|
||||
safeAsReturnsNonNull("mlist as? MutableList") { mlist as? MutableList<*> }
|
||||
|
||||
val set = S() as Any
|
||||
val mset = MS()
|
||||
val hashSet = HashSet<String>()
|
||||
|
||||
safeAsReturnsNull("set as? MutableIterable") { set as? MutableIterable<*> }
|
||||
safeAsReturnsNull("set as? MutableCollection") { set as? MutableCollection<*> }
|
||||
safeAsReturnsNull("set as? MutableSet") { set as? MutableSet<*> }
|
||||
safeAsReturnsNonNull("mset as? MutableIterable") { mset as? MutableIterable<*> }
|
||||
safeAsReturnsNonNull("mset as? MutableCollection") { mset as? MutableCollection<*> }
|
||||
safeAsReturnsNonNull("mset as? MutableSet") { mset as? MutableSet<*> }
|
||||
safeAsReturnsNonNull("hashSet as? MutableSet") { hashSet as? MutableSet<*> }
|
||||
|
||||
val map = M() as Any
|
||||
val mmap = MM()
|
||||
val hashMap = HashMap<String, String>()
|
||||
|
||||
safeAsReturnsNull("map as? MutableMap") { map as? MutableMap<*, *> }
|
||||
safeAsReturnsNonNull("mmap as? MutableMap") { mmap as? MutableMap<*, *> }
|
||||
|
||||
val entry = ME() as Any
|
||||
val mentry = MME()
|
||||
|
||||
safeAsReturnsNull("entry as? MutableMap.MutableEntry") { entry as? MutableMap.MutableEntry<*, *> }
|
||||
safeAsReturnsNonNull("mentry as? MutableMap.MutableEntry") { mentry as? MutableMap.MutableEntry<*, *> }
|
||||
|
||||
hashMap[""] = ""
|
||||
val hashMapEntry = hashMap.entrySet().first()
|
||||
|
||||
safeAsReturnsNonNull("hashMapEntry as? MutableMap.MutableEntry") { hashMapEntry as? MutableMap.MutableEntry<*, *> }
|
||||
|
||||
safeAsReturnsNull("null as? MutableIterator") { null as? MutableIterator<*> }
|
||||
safeAsReturnsNull("null as? MutableListIterator") { null as? MutableListIterator<*> }
|
||||
safeAsReturnsNull("null as? MutableIterable") { null as? MutableIterable<*> }
|
||||
safeAsReturnsNull("null as? MutableCollection") { null as? MutableCollection<*> }
|
||||
safeAsReturnsNull("null as? MutableList") { null as? MutableList<*> }
|
||||
safeAsReturnsNull("null as? MutableSet") { null as? MutableSet<*> }
|
||||
safeAsReturnsNull("null as? MutableMap") { null as? MutableMap<*, *> }
|
||||
safeAsReturnsNull("null as? MutableMap.MutableEntry") { null as? MutableMap.MutableEntry<*, *> }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+36
@@ -922,6 +922,42 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("asWithMutable.kt")
|
||||
public void testAsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/asWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("isWithMutable.kt")
|
||||
public void testIsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/isWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("reifiedAsWithMutable.kt")
|
||||
public void testReifiedAsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedAsWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("reifiedIsWithMutable.kt")
|
||||
public void testReifiedIsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedIsWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("reifiedSafeAsWithMutable.kt")
|
||||
public void testReifiedSafeAsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsWithMutable.kt")
|
||||
public void testSafeAsWithMutable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/safeAsWithMutable.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unitAsInt.kt")
|
||||
public void testUnitAsInt() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/unitAsInt.kt");
|
||||
|
||||
@@ -19,8 +19,7 @@ package kotlin.jvm.internal;
|
||||
import kotlin.KotlinNullPointerException;
|
||||
import kotlin.UninitializedPropertyAccessException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Intrinsics {
|
||||
@@ -35,6 +34,10 @@ public class Intrinsics {
|
||||
throw sanitizeStackTrace(new KotlinNullPointerException());
|
||||
}
|
||||
|
||||
public static void throwCce(String message) {
|
||||
throw sanitizeStackTrace(new ClassCastException(message));
|
||||
}
|
||||
|
||||
public static void throwUninitializedPropertyAccessException(String propertyName) {
|
||||
throw sanitizeStackTrace(new UninitializedPropertyAccessException(propertyName));
|
||||
}
|
||||
@@ -137,4 +140,268 @@ public class Intrinsics {
|
||||
throwable.setStackTrace(list.toArray(new StackTraceElement[list.size()]));
|
||||
return throwable;
|
||||
}
|
||||
|
||||
public static boolean isMutableIterator(Object obj) {
|
||||
return (obj instanceof Iterator) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableIterator));
|
||||
}
|
||||
|
||||
public static Iterator asMutableIterator(Object obj) {
|
||||
Iterator result = null;
|
||||
try {
|
||||
result = (Iterator) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not an Iterator");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableIterator)) {
|
||||
throwCce("argument is not a MutableIterator");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Iterator safeAsMutableIterator(Object obj) {
|
||||
Iterator result;
|
||||
try {
|
||||
result = (Iterator) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableIterator)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableListIterator(Object obj) {
|
||||
return (obj instanceof ListIterator) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableListIterator));
|
||||
}
|
||||
|
||||
public static ListIterator asMutableListIterator(Object obj) {
|
||||
ListIterator result = null;
|
||||
try {
|
||||
result = (ListIterator) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a ListIterator");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableListIterator)) {
|
||||
throwCce("argument is not a MutableListIterator");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ListIterator safeAsMutableListIterator(Object obj) {
|
||||
ListIterator result;
|
||||
try {
|
||||
result = (ListIterator) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableListIterator)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableIterable(Object obj) {
|
||||
return (obj instanceof Iterable) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableIterable));
|
||||
}
|
||||
|
||||
public static Iterable asMutableIterable(Object obj) {
|
||||
Iterable result = null;
|
||||
try {
|
||||
result = (Iterable) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not an Iterable");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableIterable)) {
|
||||
throwCce("argument is not a MutableIterable");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Iterable safeAsMutableIterable(Object obj) {
|
||||
Iterable result;
|
||||
try {
|
||||
result = (Iterable) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableIterable)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableCollection(Object obj) {
|
||||
return (obj instanceof Collection) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableCollection));
|
||||
}
|
||||
|
||||
public static Collection asMutableCollection(Object obj) {
|
||||
Collection result = null;
|
||||
try {
|
||||
result = (Collection) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a Collection");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableCollection)) {
|
||||
throwCce("argument is not a MutableCollection");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Collection safeAsMutableCollection(Object obj) {
|
||||
Collection result;
|
||||
try {
|
||||
result = (Collection) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableCollection)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableList(Object obj) {
|
||||
return (obj instanceof List) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableList));
|
||||
}
|
||||
|
||||
public static List asMutableList(Object obj) {
|
||||
List result = null;
|
||||
try {
|
||||
result = (List) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a List");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableList)) {
|
||||
throwCce("argument is not a MutableList");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List safeAsMutableList(Object obj) {
|
||||
List result;
|
||||
try {
|
||||
result = (List) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableList)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableSet(Object obj) {
|
||||
return (obj instanceof Set) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableSet));
|
||||
}
|
||||
|
||||
public static Set asMutableSet(Object obj) {
|
||||
Set result = null;
|
||||
try {
|
||||
result = (Set) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a Set");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableSet)) {
|
||||
throwCce("argument is not a MutableSet");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set safeAsMutableSet(Object obj) {
|
||||
Set result;
|
||||
try {
|
||||
result = (Set) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableSet)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableMap(Object obj) {
|
||||
return (obj instanceof Map) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableMap));
|
||||
}
|
||||
|
||||
public static Map asMutableMap(Object obj) {
|
||||
Map result = null;
|
||||
try {
|
||||
result = (Map) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a Map");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableMap)) {
|
||||
throwCce("argument is not a MutableMap");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Map safeAsMutableMap(Object obj) {
|
||||
Map result = null;
|
||||
try {
|
||||
result = (Map) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableMap)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMutableMapEntry(Object obj) {
|
||||
return (obj instanceof Map.Entry) &&
|
||||
(!(obj instanceof KMappedMarker) || (obj instanceof KMutableMap.Entry));
|
||||
}
|
||||
|
||||
public static Map.Entry asMutableMapEntry(Object obj) {
|
||||
Map.Entry result = null;
|
||||
try {
|
||||
result = (Map.Entry) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
throwCce("argument is not a Map.Entry");
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableMap.Entry)) {
|
||||
throwCce("argument is not a MutableMap.MutableEntry");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Map.Entry safeAsMutableMapEntry(Object obj) {
|
||||
Map.Entry result = null;
|
||||
try {
|
||||
result = (Map.Entry) obj;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
if ((obj instanceof KMappedMarker) && !(obj instanceof KMutableMap.Entry)) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
|
||||
private var size: Int = 0
|
||||
|
||||
override fun iterator(): MutableIterator<T> = when {
|
||||
size == 0 -> emptySet<T>().iterator()
|
||||
size == 1 -> SingletonIterator(data as T)
|
||||
size < ARRAY_THRESHOLD -> (data as Array<T>).iterator()
|
||||
else -> (data as MutableSet<T>).iterator()
|
||||
} as MutableIterator<T>
|
||||
size == 0 -> Collections.emptySet<T>().iterator()
|
||||
size == 1 -> SingletonIterator(data as T)
|
||||
size < ARRAY_THRESHOLD -> ArrayIterator(data as Array<T>)
|
||||
else -> (data as MutableSet<T>).iterator()
|
||||
}
|
||||
|
||||
override fun add(e: T): Boolean {
|
||||
when {
|
||||
@@ -87,7 +87,7 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
|
||||
else -> o in data as Set<T>
|
||||
}
|
||||
|
||||
private class SingletonIterator<T>(private val element: T) : Iterator<T> {
|
||||
private class SingletonIterator<T>(private val element: T) : MutableIterator<T> {
|
||||
private var hasNext = true
|
||||
|
||||
override fun next(): T =
|
||||
@@ -98,5 +98,15 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
|
||||
else throw NoSuchElementException()
|
||||
|
||||
override fun hasNext() = hasNext
|
||||
|
||||
override fun remove() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
private class ArrayIterator<T>(array: Array<T>) : MutableIterator<T> {
|
||||
private val arrayIterator = array.iterator()
|
||||
|
||||
override fun hasNext(): Boolean = arrayIterator.hasNext()
|
||||
override fun next(): T = arrayIterator.next()
|
||||
override fun remove() = throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user