Introduce kotlin.Cloneable

- Cloneable is a trait with a single protected member 'clone', which is mapped
  to java.lang.Cloneable on JVM
- 'clone' is non-abstract to be able to call 'super.clone()' in the
  implementations. Also if you need your class to be Cloneable, most of the
  time inheriting from Cloneable and calling 'super.clone()' will work
- hack 'super.clone()' in JVM intrinsics and TImpl delegation generation
- make arrays Cloneable, handle 'clone()' calls in the intrinsic

 #KT-4890 Fixed
This commit is contained in:
Alexander Udalov
2014-07-21 22:10:53 +04:00
parent f3309d1fa7
commit fb958897a9
33 changed files with 392 additions and 38 deletions
@@ -1505,7 +1505,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
DeclarationDescriptor containingDeclaration = traitFun.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = traitFun.getContainingDeclaration();
if (!DescriptorUtils.isTrait(containingDeclaration)) return; if (!DescriptorUtils.isTrait(containingDeclaration)) return;
Type traitImplType = typeMapper.mapTraitImpl((ClassDescriptor) containingDeclaration); ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
Type traitImplType = typeMapper.mapTraitImpl(containingTrait);
Method traitMethod = typeMapper.mapSignature(traitFun.getOriginal(), OwnerKind.TRAIT_IMPL).getAsmMethod(); Method traitMethod = typeMapper.mapSignature(traitFun.getOriginal(), OwnerKind.TRAIT_IMPL).getAsmMethod();
@@ -1522,7 +1523,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
reg += argTypes[i].getSize(); reg += argTypes[i].getSize();
} }
iv.invokestatic(traitImplType.getInternalName(), traitMethod.getName(), traitMethod.getDescriptor()); if (KotlinBuiltIns.getInstance().isCloneable(containingTrait) && traitMethod.getName().equals("clone")) {
// A special hack for Cloneable: there's no kotlin/Cloneable$$TImpl class at runtime,
// and its 'clone' method is actually located in java/lang/Object
iv.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false);
}
else {
iv.invokestatic(traitImplType.getInternalName(), traitMethod.getName(), traitMethod.getDescriptor());
}
Type returnType = signature.getReturnType(); Type returnType = signature.getReturnType();
StackValue.onStack(traitMethod.getReturnType()).put(returnType, iv); StackValue.onStack(traitMethod.getReturnType()).put(returnType, iv);
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2014 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.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSuperExpression;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getResolvedCallWithAssert;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
public class Clone extends IntrinsicMethod {
@NotNull
@Override
protected Type generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull InstructionAdapter v,
@NotNull Type returnType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
@Nullable StackValue receiver
) {
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(((JetElement) element), codegen.getBindingContext());
StackValue.receiver(resolvedCall, receiver, codegen, null).put(OBJECT_TYPE, v);
if (isSuperCall(resolvedCall)) {
v.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false);
}
else {
v.invokevirtual("java/lang/Object", "clone", "()Ljava/lang/Object;", false);
}
return OBJECT_TYPE;
}
private static boolean isSuperCall(@NotNull ResolvedCall<?> resolvedCall) {
ReceiverValue thisObject = resolvedCall.getThisObject();
return thisObject instanceof ExpressionReceiver &&
((ExpressionReceiver) thisObject).getExpression() instanceof JetSuperExpression;
}
}
@@ -61,6 +61,7 @@ public class IntrinsicMethods {
private static final EnumValues ENUM_VALUES = new EnumValues(); private static final EnumValues ENUM_VALUES = new EnumValues();
private static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf(); private static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf();
private static final ToString TO_STRING = new ToString(); private static final ToString TO_STRING = new ToString();
private static final Clone CLONE = new Clone();
private static final FqNameUnsafe KOTLIN_ANY_FQ_NAME = DescriptorUtils.getFqName(KotlinBuiltIns.getInstance().getAny()); private static final FqNameUnsafe KOTLIN_ANY_FQ_NAME = DescriptorUtils.getFqName(KotlinBuiltIns.getInstance().getAny());
private static final FqNameUnsafe KOTLIN_STRING_FQ_NAME = DescriptorUtils.getFqName(KotlinBuiltIns.getInstance().getString()); private static final FqNameUnsafe KOTLIN_STRING_FQ_NAME = DescriptorUtils.getFqName(KotlinBuiltIns.getInstance().getString());
@@ -121,6 +122,8 @@ public class IntrinsicMethods {
declareIntrinsicFunction("CharSequence", "get", 1, new StringGetChar()); declareIntrinsicFunction("CharSequence", "get", 1, new StringGetChar());
declareIntrinsicFunction("String", "get", 1, new StringGetChar()); declareIntrinsicFunction("String", "get", 1, new StringGetChar());
declareIntrinsicFunction("Cloneable", "clone", 0, CLONE);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "toString", 0, TO_STRING); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "toString", 0, TO_STRING);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "equals", 1, EQUALS); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "equals", 1, EQUALS);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "identityEquals", 1, IDENTITY_EQUALS); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "identityEquals", 1, IDENTITY_EQUALS);
@@ -148,6 +151,7 @@ public class IntrinsicMethods {
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES); declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
declareIntrinsicFunction("Array", "set", 2, ARRAY_SET); declareIntrinsicFunction("Array", "set", 2, ARRAY_SET);
declareIntrinsicFunction("Array", "get", 1, ARRAY_GET); declareIntrinsicFunction("Array", "get", 1, ARRAY_GET);
declareIntrinsicFunction("Array", "clone", 0, CLONE);
declareIterator("Array"); declareIterator("Array");
} }
@@ -157,6 +161,7 @@ public class IntrinsicMethods {
declareIntrinsicProperty(arrayTypeName, "indices", ARRAY_INDICES); declareIntrinsicProperty(arrayTypeName, "indices", ARRAY_INDICES);
declareIntrinsicFunction(arrayTypeName, "set", 2, ARRAY_SET); declareIntrinsicFunction(arrayTypeName, "set", 2, ARRAY_SET);
declareIntrinsicFunction(arrayTypeName, "get", 1, ARRAY_GET); declareIntrinsicFunction(arrayTypeName, "get", 1, ARRAY_GET);
declareIntrinsicFunction(arrayTypeName, "clone", 0, CLONE);
declareIterator(arrayTypeName); declareIterator(arrayTypeName);
} }
+22 -9
View File
@@ -13,12 +13,13 @@ public open class Any {
/*primary*/ public constructor Any() /*primary*/ public constructor Any()
} }
public final class Array</*0*/ reified T> { public final class Array</*0*/ reified T> : kotlin.Cloneable {
/*primary*/ public constructor Array</*0*/ reified T>(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1<kotlin.Int, T>) /*primary*/ public constructor Array</*0*/ reified T>(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1<kotlin.Int, T>)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.Array<T>
public final fun get(/*0*/ index: kotlin.Int): T public final fun get(/*0*/ index: kotlin.Int): T
public final fun iterator(): kotlin.Iterator<T> public final fun iterator(): kotlin.Iterator<T>
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: T): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: T): kotlin.Unit
@@ -33,12 +34,13 @@ public final class Boolean : kotlin.Comparable<kotlin.Boolean> {
public final fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean public final fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean
} }
public final class BooleanArray { public final class BooleanArray : kotlin.Cloneable {
/*primary*/ public constructor BooleanArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor BooleanArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.BooleanArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Boolean public final fun get(/*0*/ index: kotlin.Int): kotlin.Boolean
public final fun iterator(): kotlin.BooleanIterator public final fun iterator(): kotlin.BooleanIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Boolean): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Boolean): kotlin.Unit
@@ -115,12 +117,13 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
public open override /*1*/ fun toShort(): kotlin.Short public open override /*1*/ fun toShort(): kotlin.Short
} }
public final class ByteArray { public final class ByteArray : kotlin.Cloneable {
/*primary*/ public constructor ByteArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor ByteArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.ByteArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Byte public final fun get(/*0*/ index: kotlin.Int): kotlin.Byte
public final fun iterator(): kotlin.ByteIterator public final fun iterator(): kotlin.ByteIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Byte): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Byte): kotlin.Unit
@@ -235,12 +238,13 @@ public final class Char : kotlin.Comparable<kotlin.Char> {
public final fun toShort(): kotlin.Short public final fun toShort(): kotlin.Short
} }
public final class CharArray { public final class CharArray : kotlin.Cloneable {
/*primary*/ public constructor CharArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor CharArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.CharArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Char public final fun get(/*0*/ index: kotlin.Int): kotlin.Char
public final fun iterator(): kotlin.CharIterator public final fun iterator(): kotlin.CharIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Char): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Char): kotlin.Unit
@@ -307,6 +311,10 @@ public trait CharSequence {
public abstract fun get(/*0*/ index: kotlin.Int): kotlin.Char public abstract fun get(/*0*/ index: kotlin.Int): kotlin.Char
} }
public trait Cloneable {
protected open fun clone(): kotlin.Any
}
public trait Collection</*0*/ out E> : kotlin.Iterable<E> { public trait Collection</*0*/ out E> : kotlin.Iterable<E> {
public abstract fun contains(/*0*/ o: kotlin.Any?): kotlin.Boolean public abstract fun contains(/*0*/ o: kotlin.Any?): kotlin.Boolean
public abstract fun containsAll(/*0*/ c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean public abstract fun containsAll(/*0*/ c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean
@@ -382,12 +390,13 @@ public final class Double : kotlin.Number, kotlin.Comparable<kotlin.Double> {
public open override /*1*/ fun toShort(): kotlin.Short public open override /*1*/ fun toShort(): kotlin.Short
} }
public final class DoubleArray { public final class DoubleArray : kotlin.Cloneable {
/*primary*/ public constructor DoubleArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor DoubleArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.DoubleArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Double public final fun get(/*0*/ index: kotlin.Int): kotlin.Double
public final fun iterator(): kotlin.DoubleIterator public final fun iterator(): kotlin.DoubleIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Double): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Double): kotlin.Unit
@@ -607,12 +616,13 @@ public final class Float : kotlin.Number, kotlin.Comparable<kotlin.Float> {
public open override /*1*/ fun toShort(): kotlin.Short public open override /*1*/ fun toShort(): kotlin.Short
} }
public final class FloatArray { public final class FloatArray : kotlin.Cloneable {
/*primary*/ public constructor FloatArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor FloatArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.FloatArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Float public final fun get(/*0*/ index: kotlin.Int): kotlin.Float
public final fun iterator(): kotlin.FloatIterator public final fun iterator(): kotlin.FloatIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Float): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Float): kotlin.Unit
@@ -905,12 +915,13 @@ public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int> {
public final fun xor(/*0*/ other: kotlin.Int): kotlin.Int public final fun xor(/*0*/ other: kotlin.Int): kotlin.Int
} }
public final class IntArray { public final class IntArray : kotlin.Cloneable {
/*primary*/ public constructor IntArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor IntArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.IntArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Int public final fun get(/*0*/ index: kotlin.Int): kotlin.Int
public final fun iterator(): kotlin.IntIterator public final fun iterator(): kotlin.IntIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Int): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Int): kotlin.Unit
@@ -1074,12 +1085,13 @@ public final class Long : kotlin.Number, kotlin.Comparable<kotlin.Long> {
public final fun xor(/*0*/ other: kotlin.Long): kotlin.Long public final fun xor(/*0*/ other: kotlin.Long): kotlin.Long
} }
public final class LongArray { public final class LongArray : kotlin.Cloneable {
/*primary*/ public constructor LongArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor LongArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.LongArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Long public final fun get(/*0*/ index: kotlin.Int): kotlin.Long
public final fun iterator(): kotlin.LongIterator public final fun iterator(): kotlin.LongIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Long): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Long): kotlin.Unit
@@ -1378,12 +1390,13 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
public open override /*1*/ fun toShort(): kotlin.Short public open override /*1*/ fun toShort(): kotlin.Short
} }
public final class ShortArray { public final class ShortArray : kotlin.Cloneable {
/*primary*/ public constructor ShortArray(/*0*/ size: kotlin.Int) /*primary*/ public constructor ShortArray(/*0*/ size: kotlin.Int)
public final val indices: kotlin.IntRange public final val indices: kotlin.IntRange
public final fun <get-indices>(): kotlin.IntRange public final fun <get-indices>(): kotlin.IntRange
public final val size: kotlin.Int public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.ShortArray
public final fun get(/*0*/ index: kotlin.Int): kotlin.Short public final fun get(/*0*/ index: kotlin.Int): kotlin.Short
public final fun iterator(): kotlin.ShortIterator public final fun iterator(): kotlin.ShortIterator
public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Short): kotlin.Unit public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Short): kotlin.Unit
@@ -1,6 +1,6 @@
public open class Test(): java.util.RandomAccess, Cloneable, java.io.Serializable public open class Test(): java.util.RandomAccess, Cloneable, java.io.Serializable
{ {
public fun clone(): Test = Test() // Override 'clone()' with more precise type 'Test' public override fun clone(): Test = Test() // Override 'clone()' with more precise type 'Test'
public override fun toString() = "OK" public override fun toString() = "OK"
} }
@@ -0,0 +1,11 @@
data class A(var x: Int) : Cloneable {
public override fun clone(): A = A(x)
}
fun box(): String {
val a = A(42)
val b = a.clone()
if (b != a) return "Fail equals"
if (b identityEquals a) return "Fail identity"
return "OK"
}
@@ -0,0 +1,11 @@
data class A(var x: Int) : Cloneable {
public override fun clone(): A = super.clone() as A
}
fun box(): String {
val a = A(42)
val b = a.clone()
if (a != b) return "Fail equals"
if (a identityEquals b) return "Fail identity"
return "OK"
}
@@ -0,0 +1,16 @@
data class A(var x: Int) : Cloneable {
public override fun clone(): A {
val result = super.clone() as A
result.x = 239
return result
}
}
fun box(): String {
val a = A(42)
val b = a.clone()
if (a == b) return "Fail: $a == $b"
if (a identityEquals b) return "Fail: $a identityEquals $b"
if (b.x != 239) return "Fail: b.x = ${b.x}"
return "OK"
}
@@ -0,0 +1,12 @@
import java.util.HashSet
fun box(): String {
val a = HashSet<String>()
a.add("live")
a.add("long")
a.add("prosper")
val b = a.clone()
if (a != b) return "Fail equals"
if (a identityEquals b) return "Fail identity"
return "OK"
}
@@ -0,0 +1,32 @@
import java.util.ArrayList
open class A : Cloneable {
public override fun clone(): A = super.clone() as A
}
open class B(var s: String) : A() {
override fun clone(): B = super.clone() as B
}
open class C(s: String, var l: ArrayList<Any>): B(s) {
override fun clone(): C {
val result = super.clone() as C
result.l = l.clone() as ArrayList<Any>
return result
}
}
fun box(): String {
val l = ArrayList<Any>()
l.add(true)
val c = C("OK", l)
val d = c.clone()
if (c.s != d.s) return "Fail s: ${d.s}"
if (c.l != d.l) return "Fail l: ${d.l}"
if (c.l identityEquals d.l) return "Fail list identity"
if (c identityEquals d) return "Fail identity"
return "OK"
}
@@ -0,0 +1,11 @@
data class A(val s: String) : Cloneable {
fun externalClone(): A = clone() as A
}
fun box(): String {
val a = A("OK")
val b = a.externalClone()
if (a != b) return "Fail equals"
if (a identityEquals b) return "Fail identity"
return b.s
}
@@ -0,0 +1,17 @@
import java.util.Arrays.equals
fun box(): String {
val s = array("live", "long")
val t = s.clone()
t : Array<String>
if (!equals(s, t)) return "Fail string"
if (s identityEquals t) return "Fail string identity"
val ss = array(s, s)
val tt = ss.clone()
tt : Array<Array<String>>
if (!equals(ss, tt)) return "Fail string[]"
if (ss identityEquals tt) return "Fail string[] identity"
return "OK"
}
@@ -0,0 +1,37 @@
import java.util.Arrays.equals
fun box(): String {
val i = intArray(1, 2)
if (!equals(i, i.clone())) return "Fail int"
if (i.clone() identityEquals i) return "Fail int identity"
val j = longArray(1L, 2L)
if (!equals(j, j.clone())) return "Fail long"
if (j.clone() identityEquals j) return "Fail long identity"
val s = shortArray(1.toShort(), 2.toShort())
if (!equals(s, s.clone())) return "Fail short"
if (s.clone() identityEquals s) return "Fail short identity"
val b = byteArray(1.toByte(), 2.toByte())
if (!equals(b, b.clone())) return "Fail byte"
if (b.clone() identityEquals b) return "Fail byte identity"
val c = charArray('a', 'b')
if (!equals(c, c.clone())) return "Fail char"
if (c.clone() identityEquals c) return "Fail char identity"
val d = doubleArray(1.0, -1.0)
if (!equals(d, d.clone())) return "Fail double"
if (d.clone() identityEquals d) return "Fail double identity"
val f = floatArray(1f, -1f)
if (!equals(f, f.clone())) return "Fail float"
if (f.clone() identityEquals f) return "Fail float identity"
val z = booleanArray(true, false)
if (!equals(z, z.clone())) return "Fail boolean"
if (z.clone() identityEquals z) return "Fail boolean identity"
return "OK"
}
@@ -1,7 +1,7 @@
package test package test
public /*synthesized*/ fun </*0*/ A : kotlin.Comparable<A>?, /*1*/ B : kotlin.List<A>?> GenericInterfaceParametersWithBounds(/*0*/ function: (kotlin.Array<out A>?, B?) -> kotlin.Unit): test.GenericInterfaceParametersWithBounds<A, B> where A : java.lang.Cloneable? public /*synthesized*/ fun </*0*/ A : kotlin.Comparable<A>?, /*1*/ B : kotlin.List<A>?> GenericInterfaceParametersWithBounds(/*0*/ function: (kotlin.Array<out A>?, B?) -> kotlin.Unit): test.GenericInterfaceParametersWithBounds<A, B> where A : kotlin.Cloneable?
public trait GenericInterfaceParametersWithBounds</*0*/ A : kotlin.Comparable<A>?, /*1*/ B : kotlin.List<A>?> where A : java.lang.Cloneable? { public trait GenericInterfaceParametersWithBounds</*0*/ A : kotlin.Comparable<A>?, /*1*/ B : kotlin.List<A>?> where A : kotlin.Cloneable? {
public abstract fun method(/*0*/ p0: kotlin.Array<out A>?, /*1*/ p1: B?): kotlin.Unit public abstract fun method(/*0*/ p0: kotlin.Array<out A>?, /*1*/ p1: B?): kotlin.Unit
} }
@@ -2,5 +2,5 @@ package test
public open class MethodTypePOneUpperBound { public open class MethodTypePOneUpperBound {
public constructor MethodTypePOneUpperBound() public constructor MethodTypePOneUpperBound()
public open fun </*0*/ T : java.lang.Cloneable?> bar(): kotlin.Unit public open fun </*0*/ T : kotlin.Cloneable?> bar(): kotlin.Unit
} }
@@ -2,5 +2,5 @@ package test
public open class MethodTypePTwoUpperBounds { public open class MethodTypePTwoUpperBounds {
public constructor MethodTypePTwoUpperBounds() public constructor MethodTypePTwoUpperBounds()
public open fun </*0*/ T : java.lang.Cloneable?> foo(): kotlin.Unit where T : java.lang.Runnable? public open fun </*0*/ T : kotlin.Cloneable?> foo(): kotlin.Unit where T : java.lang.Runnable?
} }
@@ -2,5 +2,5 @@ package test
public open class MethodWithTypeParameters { public open class MethodWithTypeParameters {
public constructor MethodWithTypeParameters() public constructor MethodWithTypeParameters()
public open fun </*0*/ A, /*1*/ B : java.lang.Runnable> foo(/*0*/ a: A, /*1*/ b: kotlin.List<B>, /*2*/ c: kotlin.MutableList<in kotlin.String?>): kotlin.Unit where B : kotlin.List<java.lang.Cloneable> public open fun </*0*/ A, /*1*/ B : java.lang.Runnable> foo(/*0*/ a: A, /*1*/ b: kotlin.List<B>, /*2*/ c: kotlin.MutableList<in kotlin.String?>): kotlin.Unit where B : kotlin.List<kotlin.Cloneable>
} }
@@ -2,5 +2,5 @@ package test
public open class MissingUpperBound { public open class MissingUpperBound {
public constructor MissingUpperBound() public constructor MissingUpperBound()
public open fun </*0*/ A : java.lang.Runnable?> foo(): kotlin.String? where A : java.lang.Cloneable? public open fun </*0*/ A : java.lang.Runnable?> foo(): kotlin.String? where A : kotlin.Cloneable?
} }
@@ -2,5 +2,5 @@ package test
public open class WrongTypeParameterBoundStructure1 { public open class WrongTypeParameterBoundStructure1 {
public constructor WrongTypeParameterBoundStructure1() public constructor WrongTypeParameterBoundStructure1()
public open fun </*0*/ A, /*1*/ B : java.lang.Runnable?> foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List<B>?): kotlin.Unit where B : kotlin.List<java.lang.Cloneable>? public open fun </*0*/ A, /*1*/ B : java.lang.Runnable?> foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List<B>?): kotlin.Unit where B : kotlin.List<kotlin.Cloneable>?
} }
@@ -6,7 +6,7 @@ import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
public class WrongTypeParameterBoundStructure2 { public class WrongTypeParameterBoundStructure2 {
@ExpectLoadError("'kotlin.List<java.lang.Cloneable>?' type in method signature has 1 type arguments, while 'List' in alternative signature has 0 of them") @ExpectLoadError("'kotlin.List<kotlin.Cloneable>?' type in method signature has 1 type arguments, while 'List' in alternative signature has 0 of them")
@KotlinSignature("fun <A, B : Runnable> foo(a : A, b : List<B>) where B : List") @KotlinSignature("fun <A, B : Runnable> foo(a : A, b : List<B>) where B : List")
public <A, B extends Runnable & List<Cloneable>> void foo(A a, List<? extends B> b) { public <A, B extends Runnable & List<Cloneable>> void foo(A a, List<? extends B> b) {
} }
@@ -2,5 +2,5 @@ package test
public open class WrongTypeParameterBoundStructure2 { public open class WrongTypeParameterBoundStructure2 {
public constructor WrongTypeParameterBoundStructure2() public constructor WrongTypeParameterBoundStructure2()
public open fun </*0*/ A, /*1*/ B : java.lang.Runnable?> foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List<B>?): kotlin.Unit where B : kotlin.List<java.lang.Cloneable>? public open fun </*0*/ A, /*1*/ B : java.lang.Runnable?> foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List<B>?): kotlin.Unit where B : kotlin.List<kotlin.Cloneable>?
} }
@@ -3,10 +3,10 @@ package test
public trait TwoBounds { public trait TwoBounds {
public trait Sub : test.TwoBounds.Super { public trait Sub : test.TwoBounds.Super {
public abstract override /*1*/ fun </*0*/ B : kotlin.CharSequence> foo(/*0*/ a: B): kotlin.Unit where B : java.lang.Cloneable public abstract override /*1*/ fun </*0*/ B : kotlin.CharSequence> foo(/*0*/ a: B): kotlin.Unit where B : kotlin.Cloneable
} }
public trait Super { public trait Super {
public abstract fun </*0*/ A : kotlin.CharSequence> foo(/*0*/ a: A): kotlin.Unit where A : java.lang.Cloneable public abstract fun </*0*/ A : kotlin.CharSequence> foo(/*0*/ a: A): kotlin.Unit where A : kotlin.Cloneable
} }
} }
@@ -3,10 +3,10 @@ package test
public trait TwoTypeParameters { public trait TwoTypeParameters {
public trait Sub : test.TwoTypeParameters.Super { public trait Sub : test.TwoTypeParameters.Super {
public abstract override /*1*/ fun </*0*/ B : kotlin.CharSequence, /*1*/ A : java.lang.Cloneable> foo(/*0*/ a: B, /*1*/ b: A): kotlin.Unit public abstract override /*1*/ fun </*0*/ B : kotlin.CharSequence, /*1*/ A : kotlin.Cloneable> foo(/*0*/ a: B, /*1*/ b: A): kotlin.Unit
} }
public trait Super { public trait Super {
public abstract fun </*0*/ A : kotlin.CharSequence, /*1*/ B : java.lang.Cloneable> foo(/*0*/ a: A, /*1*/ b: B): kotlin.Unit public abstract fun </*0*/ A : kotlin.CharSequence, /*1*/ B : kotlin.Cloneable> foo(/*0*/ a: A, /*1*/ b: B): kotlin.Unit
} }
} }
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/box") @TestMetadata("compiler/testData/codegen/box")
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) @InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.JavaInterop.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBox() throws Exception { public void testAllFilesPresentInBox() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -3142,6 +3142,59 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
} }
@TestMetadata("compiler/testData/codegen/box/javaInterop")
@InnerTestClasses({JavaInterop.ObjectMethods.class})
public static class JavaInterop extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInJavaInterop() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/javaInterop"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("compiler/testData/codegen/box/javaInterop/objectMethods")
public static class ObjectMethods extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInObjectMethods() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/javaInterop/objectMethods"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("cloneCallsConstructor.kt")
public void testCloneCallsConstructor() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsConstructor.kt");
}
@TestMetadata("cloneCallsSuper.kt")
public void testCloneCallsSuper() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuper.kt");
}
@TestMetadata("cloneCallsSuperAndModifies.kt")
public void testCloneCallsSuperAndModifies() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt");
}
@TestMetadata("cloneHashSet.kt")
public void testCloneHashSet() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneHashSet.kt");
}
@TestMetadata("cloneHierarchy.kt")
public void testCloneHierarchy() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneHierarchy.kt");
}
@TestMetadata("cloneableClassWithoutClone.kt")
public void testCloneableClassWithoutClone() throws Exception {
doTest("compiler/testData/codegen/box/javaInterop/objectMethods/cloneableClassWithoutClone.kt");
}
}
public static Test innerSuite() {
TestSuite suite = new TestSuite("JavaInterop");
suite.addTestSuite(JavaInterop.class);
suite.addTestSuite(ObjectMethods.class);
return suite;
}
}
@TestMetadata("compiler/testData/codegen/box/labels") @TestMetadata("compiler/testData/codegen/box/labels")
public static class Labels extends AbstractBlackBoxCodegenTest { public static class Labels extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInLabels() throws Exception { public void testAllFilesPresentInLabels() throws Exception {
@@ -5394,6 +5447,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
suite.addTestSuite(InnerNested.class); suite.addTestSuite(InnerNested.class);
suite.addTest(Instructions.innerSuite()); suite.addTest(Instructions.innerSuite());
suite.addTestSuite(Intrinsics.class); suite.addTestSuite(Intrinsics.class);
suite.addTest(JavaInterop.innerSuite());
suite.addTestSuite(Labels.class); suite.addTestSuite(Labels.class);
suite.addTestSuite(LocalClasses.class); suite.addTestSuite(LocalClasses.class);
suite.addTest(MultiDecl.innerSuite()); suite.addTest(MultiDecl.innerSuite());
@@ -91,6 +91,16 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/arrays"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/arrays"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("cloneArray.kt")
public void testCloneArray() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/arrays/cloneArray.kt");
}
@TestMetadata("clonePrimitiveArrays.kt")
public void testClonePrimitiveArrays() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/arrays/clonePrimitiveArrays.kt");
}
@TestMetadata("kt3771.kt") @TestMetadata("kt3771.kt")
public void testKt3771() throws Exception { public void testKt3771() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/arrays/kt3771.kt"); doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/arrays/kt3771.kt");
+3 -1
View File
@@ -16,11 +16,13 @@
package kotlin package kotlin
public class Array<reified T>(public val size: Int, init: (Int) -> T) { public class Array<reified T>(public val size: Int, init: (Int) -> T) : Cloneable {
public fun get(index: Int): T public fun get(index: Int): T
public fun set(index: Int, value: T): Unit public fun set(index: Int, value: T): Unit
public fun iterator(): Iterator<T> public fun iterator(): Iterator<T>
public val indices: IntRange public val indices: IntRange
public override fun clone(): Array<T>
} }
+24 -8
View File
@@ -18,75 +18,91 @@
package kotlin package kotlin
public class ByteArray(public val size: Int) { public class ByteArray(public val size: Int) : Cloneable {
public fun get(index: Int): Byte public fun get(index: Int): Byte
public fun set(index: Int, value: Byte): Unit public fun set(index: Int, value: Byte): Unit
public fun iterator(): ByteIterator public fun iterator(): ByteIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): ByteArray
} }
public class CharArray(public val size: Int) { public class CharArray(public val size: Int) : Cloneable {
public fun get(index: Int): Char public fun get(index: Int): Char
public fun set(index: Int, value: Char): Unit public fun set(index: Int, value: Char): Unit
public fun iterator(): CharIterator public fun iterator(): CharIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): CharArray
} }
public class ShortArray(public val size: Int) { public class ShortArray(public val size: Int) : Cloneable {
public fun get(index: Int): Short public fun get(index: Int): Short
public fun set(index: Int, value: Short): Unit public fun set(index: Int, value: Short): Unit
public fun iterator(): ShortIterator public fun iterator(): ShortIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): ShortArray
} }
public class IntArray(public val size: Int) { public class IntArray(public val size: Int) : Cloneable {
public fun get(index: Int): Int public fun get(index: Int): Int
public fun set(index: Int, value: Int): Unit public fun set(index: Int, value: Int): Unit
public fun iterator(): IntIterator public fun iterator(): IntIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): IntArray
} }
public class LongArray(public val size: Int) { public class LongArray(public val size: Int) : Cloneable {
public fun get(index: Int): Long public fun get(index: Int): Long
public fun set(index: Int, value: Long): Unit public fun set(index: Int, value: Long): Unit
public fun iterator(): LongIterator public fun iterator(): LongIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): LongArray
} }
public class FloatArray(public val size: Int) { public class FloatArray(public val size: Int) : Cloneable {
public fun get(index: Int): Float public fun get(index: Int): Float
public fun set(index: Int, value: Float): Unit public fun set(index: Int, value: Float): Unit
public fun iterator(): FloatIterator public fun iterator(): FloatIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): FloatArray
} }
public class DoubleArray(public val size: Int) { public class DoubleArray(public val size: Int) : Cloneable {
public fun get(index: Int): Double public fun get(index: Int): Double
public fun set(index: Int, value: Double): Unit public fun set(index: Int, value: Double): Unit
public fun iterator(): DoubleIterator public fun iterator(): DoubleIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): DoubleArray
} }
public class BooleanArray(public val size: Int) { public class BooleanArray(public val size: Int) : Cloneable {
public fun get(index: Int): Boolean public fun get(index: Int): Boolean
public fun set(index: Int, value: Boolean): Unit public fun set(index: Int, value: Boolean): Unit
public fun iterator(): BooleanIterator public fun iterator(): BooleanIterator
public val indices: IntRange public val indices: IntRange
public override fun clone(): BooleanArray
} }
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2014 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 kotlin
public trait Cloneable {
protected fun clone(): Any { /* intrinsic */ }
}
@@ -38,6 +38,7 @@ public abstract class JavaToKotlinClassMapBuilder {
register(String.class, kotlinBuiltIns.getString()); register(String.class, kotlinBuiltIns.getString());
register(CharSequence.class, kotlinBuiltIns.getCharSequence()); register(CharSequence.class, kotlinBuiltIns.getCharSequence());
register(Throwable.class, kotlinBuiltIns.getThrowable()); register(Throwable.class, kotlinBuiltIns.getThrowable());
register(Cloneable.class, kotlinBuiltIns.getCloneable());
register(Number.class, kotlinBuiltIns.getNumber()); register(Number.class, kotlinBuiltIns.getNumber());
register(Comparable.class, kotlinBuiltIns.getComparable()); register(Comparable.class, kotlinBuiltIns.getComparable());
register(Enum.class, kotlinBuiltIns.getEnum()); register(Enum.class, kotlinBuiltIns.getEnum());
@@ -138,6 +138,7 @@ public class KotlinBuiltIns {
private static class FqNames { private static class FqNames {
public final FqNameUnsafe any = fqName("Any"); public final FqNameUnsafe any = fqName("Any");
public final FqNameUnsafe nothing = fqName("Nothing"); public final FqNameUnsafe nothing = fqName("Nothing");
public final FqNameUnsafe cloneable = fqName("Cloneable");
public final FqNameUnsafe suppress = fqName("suppress"); public final FqNameUnsafe suppress = fqName("suppress");
public final ImmutableSet<FqNameUnsafe> functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT); public final ImmutableSet<FqNameUnsafe> functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT);
@@ -300,6 +301,11 @@ public class KotlinBuiltIns {
return getBuiltInClassByName("Throwable"); return getBuiltInClassByName("Throwable");
} }
@NotNull
public ClassDescriptor getCloneable() {
return getBuiltInClassByName("Cloneable");
}
@NotNull @NotNull
public ClassDescriptor getDataClassAnnotation() { public ClassDescriptor getDataClassAnnotation() {
return getBuiltInClassByName("data"); return getBuiltInClassByName("data");
@@ -841,6 +847,10 @@ public class KotlinBuiltIns {
return !(type instanceof PackageType) && getStringType().equals(type); return !(type instanceof PackageType) && getStringType().equals(type);
} }
public boolean isCloneable(@NotNull ClassDescriptor descriptor) {
return fqNames.cloneable.equals(DescriptorUtils.getFqName(descriptor));
}
public boolean isData(@NotNull ClassDescriptor classDescriptor) { public boolean isData(@NotNull ClassDescriptor classDescriptor) {
return containsAnnotation(classDescriptor, getDataClassAnnotation()); return containsAnnotation(classDescriptor, getDataClassAnnotation());
} }
@@ -26,13 +26,15 @@ class GenerateArrays(out: PrintWriter) : BuiltInsSourceGenerator(out) {
override fun generateBody() { override fun generateBody() {
for (kind in PrimitiveType.values()) { for (kind in PrimitiveType.values()) {
val s = kind.capitalized val s = kind.capitalized
out.println("public class ${s}Array(public val size: Int) {") out.println("public class ${s}Array(public val size: Int) : Cloneable {")
out.println(" public fun get(index: Int): $s") out.println(" public fun get(index: Int): $s")
out.println(" public fun set(index: Int, value: $s): Unit") out.println(" public fun set(index: Int, value: $s): Unit")
out.println() out.println()
out.println(" public fun iterator(): ${s}Iterator") out.println(" public fun iterator(): ${s}Iterator")
out.println() out.println()
out.println(" public val indices: IntRange") out.println(" public val indices: IntRange")
out.println()
out.println(" public override fun clone(): ${s}Array")
out.println("}") out.println("}")
out.println() out.println()
} }
@@ -4,7 +4,7 @@ Type inference failed: Cannot infer type parameter <b>T</b> in
<table> <table>
<tr> <tr>
<td width="10%"></td> <td width="10%"></td>
<td align="right" colspan="2" style="white-space:nowrap;font-weight:bold;"><b>fun</b> <`T, E : java.lang.Cloneable> writeToMyList</td> <td align="right" colspan="2" style="white-space:nowrap;font-weight:bold;"><b>fun</b> <`T, E : kotlin.Cloneable> writeToMyList</td>
<td style="white-space:nowrap;font-weight:bold;">(</td> <td style="white-space:nowrap;font-weight:bold;">(</td>
<td align="right" style="white-space:nowrap;font-weight:bold;">l: MyList<`in T>,</td> <td align="right" style="white-space:nowrap;font-weight:bold;">l: MyList<`in T>,</td>
<td align="right" style="white-space:nowrap;font-weight:bold;">t: T</td> <td align="right" style="white-space:nowrap;font-weight:bold;">t: T</td>
@@ -4,7 +4,7 @@ Type inference failed: Cannot infer type parameter <b>T</b> in
<table> <table>
<tr> <tr>
<td width="10%"></td> <td width="10%"></td>
<td align="right" colspan="2" style="white-space:nowrap;font-weight:bold;"><b>constructor</b> Cons<`T, E : java.lang.Cloneable></td> <td align="right" colspan="2" style="white-space:nowrap;font-weight:bold;"><b>constructor</b> Cons<`T, E : kotlin.Cloneable></td>
<td style="white-space:nowrap;font-weight:bold;">(</td> <td style="white-space:nowrap;font-weight:bold;">(</td>
<td align="right" style="white-space:nowrap;font-weight:bold;">l: MyList<`in T>,</td> <td align="right" style="white-space:nowrap;font-weight:bold;">l: MyList<`in T>,</td>
<td align="right" style="white-space:nowrap;font-weight:bold;">t: T</td> <td align="right" style="white-space:nowrap;font-weight:bold;">t: T</td>