diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 6410c478cfb..16991bbb30f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -1505,7 +1505,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { DeclarationDescriptor containingDeclaration = traitFun.getContainingDeclaration(); 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(); @@ -1522,7 +1523,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { 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(); StackValue.onStack(traitMethod.getReturnType()).put(returnType, iv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Clone.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Clone.java new file mode 100644 index 00000000000..229a899b6e1 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Clone.java @@ -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 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; + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 50bcb93347c..25864f197be 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -61,6 +61,7 @@ public class IntrinsicMethods { private static final EnumValues ENUM_VALUES = new EnumValues(); private static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf(); 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_STRING_FQ_NAME = DescriptorUtils.getFqName(KotlinBuiltIns.getInstance().getString()); @@ -121,6 +122,8 @@ public class IntrinsicMethods { declareIntrinsicFunction("CharSequence", "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, "equals", 1, 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); declareIntrinsicFunction("Array", "set", 2, ARRAY_SET); declareIntrinsicFunction("Array", "get", 1, ARRAY_GET); + declareIntrinsicFunction("Array", "clone", 0, CLONE); declareIterator("Array"); } @@ -157,6 +161,7 @@ public class IntrinsicMethods { declareIntrinsicProperty(arrayTypeName, "indices", ARRAY_INDICES); declareIntrinsicFunction(arrayTypeName, "set", 2, ARRAY_SET); declareIntrinsicFunction(arrayTypeName, "get", 1, ARRAY_GET); + declareIntrinsicFunction(arrayTypeName, "clone", 0, CLONE); declareIterator(arrayTypeName); } diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index 5f9938510fd..d5a5cdb94ef 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -13,12 +13,13 @@ public open class Any { /*primary*/ public constructor Any() } -public final class Array { +public final class Array : kotlin.Cloneable { /*primary*/ public constructor Array(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.Array public final fun get(/*0*/ index: kotlin.Int): T public final fun iterator(): kotlin.Iterator public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: T): kotlin.Unit @@ -33,12 +34,13 @@ public final class Boolean : kotlin.Comparable { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.BooleanArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Boolean public final fun iterator(): kotlin.BooleanIterator 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 { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.ByteArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Byte public final fun iterator(): kotlin.ByteIterator public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Byte): kotlin.Unit @@ -235,12 +238,13 @@ public final class Char : kotlin.Comparable { public final fun toShort(): kotlin.Short } -public final class CharArray { +public final class CharArray : kotlin.Cloneable { /*primary*/ public constructor CharArray(/*0*/ size: kotlin.Int) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.CharArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Char public final fun iterator(): kotlin.CharIterator 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 trait Cloneable { + protected open fun clone(): kotlin.Any +} + public trait Collection : kotlin.Iterable { public abstract fun contains(/*0*/ o: kotlin.Any?): kotlin.Boolean public abstract fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean @@ -382,12 +390,13 @@ public final class Double : kotlin.Number, kotlin.Comparable { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.DoubleArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Double public final fun iterator(): kotlin.DoubleIterator 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 { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.FloatArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Float public final fun iterator(): kotlin.FloatIterator 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 { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.IntArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Int public final fun iterator(): kotlin.IntIterator 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 { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.LongArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Long public final fun iterator(): kotlin.LongIterator 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 { 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) public final val indices: kotlin.IntRange public final fun (): kotlin.IntRange public final val size: kotlin.Int public final fun (): kotlin.Int + public open override /*1*/ fun clone(): kotlin.ShortArray public final fun get(/*0*/ index: kotlin.Int): kotlin.Short public final fun iterator(): kotlin.ShortIterator public final fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Short): kotlin.Unit diff --git a/compiler/testData/codegen/box/classes/kt2288.kt b/compiler/testData/codegen/box/classes/kt2288.kt index cbd3385265b..5aa04a53b0a 100644 --- a/compiler/testData/codegen/box/classes/kt2288.kt +++ b/compiler/testData/codegen/box/classes/kt2288.kt @@ -1,6 +1,6 @@ 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" } diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsConstructor.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsConstructor.kt new file mode 100644 index 00000000000..b1fa6ed8434 --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsConstructor.kt @@ -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" +} diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuper.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuper.kt new file mode 100644 index 00000000000..d225016bc2a --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuper.kt @@ -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" +} diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt new file mode 100644 index 00000000000..f9ed0541f5e --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt @@ -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" +} diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHashSet.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHashSet.kt new file mode 100644 index 00000000000..8b912dde27f --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHashSet.kt @@ -0,0 +1,12 @@ +import java.util.HashSet + +fun box(): String { + val a = HashSet() + 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" +} diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHierarchy.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHierarchy.kt new file mode 100644 index 00000000000..59ebd371d4d --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneHierarchy.kt @@ -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): B(s) { + override fun clone(): C { + val result = super.clone() as C + result.l = l.clone() as ArrayList + return result + } +} + +fun box(): String { + val l = ArrayList() + 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" +} diff --git a/compiler/testData/codegen/box/javaInterop/objectMethods/cloneableClassWithoutClone.kt b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneableClassWithoutClone.kt new file mode 100644 index 00000000000..0c5115e23a7 --- /dev/null +++ b/compiler/testData/codegen/box/javaInterop/objectMethods/cloneableClassWithoutClone.kt @@ -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 +} diff --git a/compiler/testData/codegen/boxWithStdlib/arrays/cloneArray.kt b/compiler/testData/codegen/boxWithStdlib/arrays/cloneArray.kt new file mode 100644 index 00000000000..656b19794e3 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/arrays/cloneArray.kt @@ -0,0 +1,17 @@ +import java.util.Arrays.equals + +fun box(): String { + val s = array("live", "long") + val t = s.clone() + t : Array + 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> + if (!equals(ss, tt)) return "Fail string[]" + if (ss identityEquals tt) return "Fail string[] identity" + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/arrays/clonePrimitiveArrays.kt b/compiler/testData/codegen/boxWithStdlib/arrays/clonePrimitiveArrays.kt new file mode 100644 index 00000000000..413033f31cf --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/arrays/clonePrimitiveArrays.kt @@ -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" +} diff --git a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.txt b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.txt index 33cc5556db6..844834a8316 100644 --- a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.txt +++ b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.txt @@ -1,7 +1,7 @@ package test -public /*synthesized*/ fun ?, /*1*/ B : kotlin.List?> GenericInterfaceParametersWithBounds(/*0*/ function: (kotlin.Array?, B?) -> kotlin.Unit): test.GenericInterfaceParametersWithBounds where A : java.lang.Cloneable? +public /*synthesized*/ fun ?, /*1*/ B : kotlin.List?> GenericInterfaceParametersWithBounds(/*0*/ function: (kotlin.Array?, B?) -> kotlin.Unit): test.GenericInterfaceParametersWithBounds where A : kotlin.Cloneable? -public trait GenericInterfaceParametersWithBounds?, /*1*/ B : kotlin.List?> where A : java.lang.Cloneable? { +public trait GenericInterfaceParametersWithBounds?, /*1*/ B : kotlin.List?> where A : kotlin.Cloneable? { public abstract fun method(/*0*/ p0: kotlin.Array?, /*1*/ p1: B?): kotlin.Unit } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePOneUpperBound.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePOneUpperBound.txt index e16b6d36e18..e60e910fb46 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePOneUpperBound.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePOneUpperBound.txt @@ -2,5 +2,5 @@ package test public open class MethodTypePOneUpperBound { public constructor MethodTypePOneUpperBound() - public open fun bar(): kotlin.Unit + public open fun bar(): kotlin.Unit } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePTwoUpperBounds.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePTwoUpperBounds.txt index da9a0129e27..f17d46f2b20 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePTwoUpperBounds.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/MethodTypePTwoUpperBounds.txt @@ -2,5 +2,5 @@ package test public open class MethodTypePTwoUpperBounds { public constructor MethodTypePTwoUpperBounds() - public open fun foo(): kotlin.Unit where T : java.lang.Runnable? + public open fun foo(): kotlin.Unit where T : java.lang.Runnable? } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/MethodWithTypeParameters.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/MethodWithTypeParameters.txt index f5426a90bb6..b82685a7bc8 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/MethodWithTypeParameters.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/MethodWithTypeParameters.txt @@ -2,5 +2,5 @@ package test public open class MethodWithTypeParameters { public constructor MethodWithTypeParameters() - public open fun foo(/*0*/ a: A, /*1*/ b: kotlin.List, /*2*/ c: kotlin.MutableList): kotlin.Unit where B : kotlin.List + public open fun foo(/*0*/ a: A, /*1*/ b: kotlin.List, /*2*/ c: kotlin.MutableList): kotlin.Unit where B : kotlin.List } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.txt index 000e64ee276..989185d4f9e 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.txt @@ -2,5 +2,5 @@ package test public open class MissingUpperBound { public constructor MissingUpperBound() - public open fun foo(): kotlin.String? where A : java.lang.Cloneable? + public open fun foo(): kotlin.String? where A : kotlin.Cloneable? } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure1.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure1.txt index 492924b65f4..6ebf0f583fa 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure1.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure1.txt @@ -2,5 +2,5 @@ package test public open class WrongTypeParameterBoundStructure1 { public constructor WrongTypeParameterBoundStructure1() - public open fun foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List?): kotlin.Unit where B : kotlin.List? + public open fun foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List?): kotlin.Unit where B : kotlin.List? } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.java b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.java index 7d2e669b6d7..eaff297d920 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.java +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.java @@ -6,7 +6,7 @@ import jet.runtime.typeinfo.KotlinSignature; import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; public class WrongTypeParameterBoundStructure2 { - @ExpectLoadError("'kotlin.List?' type in method signature has 1 type arguments, while 'List' in alternative signature has 0 of them") + @ExpectLoadError("'kotlin.List?' type in method signature has 1 type arguments, while 'List' in alternative signature has 0 of them") @KotlinSignature("fun foo(a : A, b : List) where B : List") public > void foo(A a, List b) { } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.txt index 5d2c7e53930..d4b9db26d72 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/WrongTypeParameterBoundStructure2.txt @@ -2,5 +2,5 @@ package test public open class WrongTypeParameterBoundStructure2 { public constructor WrongTypeParameterBoundStructure2() - public open fun foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List?): kotlin.Unit where B : kotlin.List? + public open fun foo(/*0*/ p0: A?, /*1*/ p1: kotlin.List?): kotlin.Unit where B : kotlin.List? } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoBounds.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoBounds.txt index 912ed04a8bb..088088c39b9 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoBounds.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoBounds.txt @@ -3,10 +3,10 @@ package test public trait TwoBounds { public trait Sub : test.TwoBounds.Super { - public abstract override /*1*/ fun foo(/*0*/ a: B): kotlin.Unit where B : java.lang.Cloneable + public abstract override /*1*/ fun foo(/*0*/ a: B): kotlin.Unit where B : kotlin.Cloneable } public trait Super { - public abstract fun foo(/*0*/ a: A): kotlin.Unit where A : java.lang.Cloneable + public abstract fun foo(/*0*/ a: A): kotlin.Unit where A : kotlin.Cloneable } } diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoTypeParameters.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoTypeParameters.txt index 4e824b9b925..6e9f31a72a9 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoTypeParameters.txt +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/propagation/typeParameter/TwoTypeParameters.txt @@ -3,10 +3,10 @@ package test public trait TwoTypeParameters { public trait Sub : test.TwoTypeParameters.Super { - public abstract override /*1*/ fun foo(/*0*/ a: B, /*1*/ b: A): kotlin.Unit + public abstract override /*1*/ fun foo(/*0*/ a: B, /*1*/ b: A): kotlin.Unit } public trait Super { - public abstract fun foo(/*0*/ a: A, /*1*/ b: B): kotlin.Unit + public abstract fun foo(/*0*/ a: A, /*1*/ b: B): kotlin.Unit } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 683c65b6b78..78066c76dd7 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -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 */ @SuppressWarnings("all") @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 void testAllFilesPresentInBox() throws Exception { 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") public static class Labels extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInLabels() throws Exception { @@ -5394,6 +5447,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { suite.addTestSuite(InnerNested.class); suite.addTest(Instructions.innerSuite()); suite.addTestSuite(Intrinsics.class); + suite.addTest(JavaInterop.innerSuite()); suite.addTestSuite(Labels.class); suite.addTestSuite(LocalClasses.class); suite.addTest(MultiDecl.innerSuite()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 5f2d399e55e..6590b774d59 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -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); } + @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") public void testKt3771() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/arrays/kt3771.kt"); diff --git a/core/builtins/native/kotlin/Array.kt b/core/builtins/native/kotlin/Array.kt index 4ed8a5dc7f5..42b10ed4c94 100644 --- a/core/builtins/native/kotlin/Array.kt +++ b/core/builtins/native/kotlin/Array.kt @@ -16,11 +16,13 @@ package kotlin -public class Array(public val size: Int, init: (Int) -> T) { +public class Array(public val size: Int, init: (Int) -> T) : Cloneable { public fun get(index: Int): T public fun set(index: Int, value: T): Unit public fun iterator(): Iterator public val indices: IntRange + + public override fun clone(): Array } diff --git a/core/builtins/native/kotlin/Arrays.kt b/core/builtins/native/kotlin/Arrays.kt index 3090550d74f..9c4604819a2 100644 --- a/core/builtins/native/kotlin/Arrays.kt +++ b/core/builtins/native/kotlin/Arrays.kt @@ -18,75 +18,91 @@ 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 set(index: Int, value: Byte): Unit public fun iterator(): ByteIterator 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 set(index: Int, value: Char): Unit public fun iterator(): CharIterator 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 set(index: Int, value: Short): Unit public fun iterator(): ShortIterator 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 set(index: Int, value: Int): Unit public fun iterator(): IntIterator 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 set(index: Int, value: Long): Unit public fun iterator(): LongIterator 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 set(index: Int, value: Float): Unit public fun iterator(): FloatIterator 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 set(index: Int, value: Double): Unit public fun iterator(): DoubleIterator 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 set(index: Int, value: Boolean): Unit public fun iterator(): BooleanIterator public val indices: IntRange + + public override fun clone(): BooleanArray } diff --git a/core/builtins/native/kotlin/Cloneable.kt b/core/builtins/native/kotlin/Cloneable.kt new file mode 100644 index 00000000000..0929e1e6455 --- /dev/null +++ b/core/builtins/native/kotlin/Cloneable.kt @@ -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 */ } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/mapping/JavaToKotlinClassMapBuilder.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/mapping/JavaToKotlinClassMapBuilder.java index fffdfc45c4d..6786d357ab0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/mapping/JavaToKotlinClassMapBuilder.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/mapping/JavaToKotlinClassMapBuilder.java @@ -38,6 +38,7 @@ public abstract class JavaToKotlinClassMapBuilder { register(String.class, kotlinBuiltIns.getString()); register(CharSequence.class, kotlinBuiltIns.getCharSequence()); register(Throwable.class, kotlinBuiltIns.getThrowable()); + register(Cloneable.class, kotlinBuiltIns.getCloneable()); register(Number.class, kotlinBuiltIns.getNumber()); register(Comparable.class, kotlinBuiltIns.getComparable()); register(Enum.class, kotlinBuiltIns.getEnum()); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java index 892d60c30b3..22b4cbc53a9 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java @@ -138,6 +138,7 @@ public class KotlinBuiltIns { private static class FqNames { public final FqNameUnsafe any = fqName("Any"); public final FqNameUnsafe nothing = fqName("Nothing"); + public final FqNameUnsafe cloneable = fqName("Cloneable"); public final FqNameUnsafe suppress = fqName("suppress"); public final ImmutableSet functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT); @@ -300,6 +301,11 @@ public class KotlinBuiltIns { return getBuiltInClassByName("Throwable"); } + @NotNull + public ClassDescriptor getCloneable() { + return getBuiltInClassByName("Cloneable"); + } + @NotNull public ClassDescriptor getDataClassAnnotation() { return getBuiltInClassByName("data"); @@ -841,6 +847,10 @@ public class KotlinBuiltIns { 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) { return containsAnnotation(classDescriptor, getDataClassAnnotation()); } diff --git a/generators/src/org/jetbrains/jet/generators/builtins/arrays.kt b/generators/src/org/jetbrains/jet/generators/builtins/arrays.kt index 5c55665edac..9ac46f55810 100644 --- a/generators/src/org/jetbrains/jet/generators/builtins/arrays.kt +++ b/generators/src/org/jetbrains/jet/generators/builtins/arrays.kt @@ -26,13 +26,15 @@ class GenerateArrays(out: PrintWriter) : BuiltInsSourceGenerator(out) { override fun generateBody() { for (kind in PrimitiveType.values()) { 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 set(index: Int, value: $s): Unit") out.println() out.println(" public fun iterator(): ${s}Iterator") out.println() out.println(" public val indices: IntRange") + out.println() + out.println(" public override fun clone(): ${s}Array") out.println("}") out.println() } diff --git a/idea/testData/diagnosticMessage/conflictingSubstitutions1.html b/idea/testData/diagnosticMessage/conflictingSubstitutions1.html index ca36f85d8a8..f8038e2adc1 100644 --- a/idea/testData/diagnosticMessage/conflictingSubstitutions1.html +++ b/idea/testData/diagnosticMessage/conflictingSubstitutions1.html @@ -4,7 +4,7 @@ Type inference failed: Cannot infer type parameter T in - + diff --git a/idea/testData/diagnosticMessage/conflictingSubstitutions2.html b/idea/testData/diagnosticMessage/conflictingSubstitutions2.html index c1e2155fcac..2032183caa6 100644 --- a/idea/testData/diagnosticMessage/conflictingSubstitutions2.html +++ b/idea/testData/diagnosticMessage/conflictingSubstitutions2.html @@ -4,7 +4,7 @@ Type inference failed: Cannot infer type parameter T in
fun <`T, E : java.lang.Cloneable> writeToMyListfun <`T, E : kotlin.Cloneable> writeToMyList ( l: MyList<`in T>, t: T
- +
constructor Cons<`T, E : java.lang.Cloneable>constructor Cons<`T, E : kotlin.Cloneable> ( l: MyList<`in T>, t: T