Don't generate bridges for equals(), hashCode(), toString()
Otherwise an assertion is failing in the algorithm which is related to an inconsistency of java.lang.Object inheritance in JDR (KT-4890)
This commit is contained in:
@@ -47,6 +47,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.constants.JavaClassValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -427,6 +428,9 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
||||
if (owner.getContextKind() == OwnerKind.TRAIT_IMPL) return;
|
||||
if (isTrait(descriptor.getContainingDeclaration())) return;
|
||||
|
||||
// equals(Any?), hashCode(), toString() never need bridges
|
||||
if (isMethodOfAny(descriptor)) return;
|
||||
|
||||
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
|
||||
if (CallResolverUtil.isOrOverridesSynthesized(descriptor)) return;
|
||||
|
||||
@@ -448,6 +452,19 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMethodOfAny(@NotNull FunctionDescriptor descriptor) {
|
||||
String name = descriptor.getName().asString();
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
||||
if (parameters.isEmpty()) {
|
||||
return name.equals("hashCode") || name.equals("toString");
|
||||
}
|
||||
else if (parameters.size() == 1 && name.equals("equals")) {
|
||||
ValueParameterDescriptor parameter = parameters.get(0);
|
||||
return parameter.getType().equals(KotlinBuiltIns.getInstance().getNullableAnyType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) {
|
||||
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws"));
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import java.util.HashSet
|
||||
|
||||
trait A : Set<String>
|
||||
|
||||
class B : A, HashSet<String>() {
|
||||
override fun clone(): B = throw AssertionError()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return try {
|
||||
B().clone()
|
||||
"Fail 1"
|
||||
} catch (e: AssertionError) {
|
||||
try {
|
||||
(B() : HashSet<String>).clone()
|
||||
"Fail 2"
|
||||
} catch (e: AssertionError) {
|
||||
"OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import java.util.HashSet
|
||||
|
||||
trait A : Set<String>
|
||||
|
||||
class B : A, HashSet<String>()
|
||||
|
||||
fun box(): String {
|
||||
val b = B()
|
||||
b.add("OK")
|
||||
return b.iterator().next()
|
||||
}
|
||||
@@ -405,6 +405,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/bridges/noBridgeOnMutableCollectionInheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectClone.kt")
|
||||
public void testObjectClone() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/bridges/objectClone.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAbstractProperty.kt")
|
||||
public void testOverrideAbstractProperty() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/bridges/overrideAbstractProperty.kt");
|
||||
@@ -1086,6 +1091,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/classes/funDelegation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritSetAndHashSet.kt")
|
||||
public void testInheritSetAndHashSet() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/classes/inheritSetAndHashSet.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/classes/inheritance.kt");
|
||||
|
||||
Reference in New Issue
Block a user