FIR: Do not load hashCode/toString/equals methods from Java interface
As it's done in FE 1.0, and there are subtle semantics in the language that depends on it
This commit is contained in:
@@ -205,6 +205,7 @@ class JavaSymbolProvider(
|
||||
val classIsAnnotation = classKind == ClassKind.ANNOTATION_CLASS
|
||||
|
||||
for (javaMethod in javaClass.methods) {
|
||||
if (javaMethod.isObjectMethodInInterface()) continue
|
||||
declarations += convertJavaMethodToFir(
|
||||
javaMethod,
|
||||
classId,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
public abstract interface Comparator<T : R|ft<kotlin/Any, kotlin/Any?>!|> : R|kotlin/Any| {
|
||||
public abstract fun compare(o1: R|ft<T, T?>!|, o2: R|ft<T, T?>!|): R|kotlin/Int|
|
||||
|
||||
public abstract operator fun equals(obj: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
public abstract interface InterfaceWithObjectMethod : R|kotlin/Any| {
|
||||
public abstract fun toString(): R|kotlin/String|
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure
|
||||
|
||||
|
||||
fun JavaMember.isObjectMethodInInterface(): Boolean {
|
||||
return containingClass.isInterface && this is JavaMethod && isObjectMethod(this)
|
||||
}
|
||||
|
||||
private fun isObjectMethod(method: JavaMethod): Boolean {
|
||||
return when (method.name.asString()) {
|
||||
"toString", "hashCode" -> {
|
||||
method.valueParameters.isEmpty()
|
||||
}
|
||||
"equals" -> {
|
||||
isMethodWithOneObjectParameter(method)
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun isMethodWithOneObjectParameter(method: JavaMethod): Boolean {
|
||||
val parameters = method.valueParameters
|
||||
val type = parameters.singleOrNull()?.type as? JavaClassifierType ?: return false
|
||||
val classifier = type.classifier
|
||||
if (classifier is JavaClass) {
|
||||
val classFqName = classifier.fqName
|
||||
return classFqName != null && classFqName.asString() == "java.lang.Object"
|
||||
}
|
||||
return false
|
||||
}
|
||||
-32
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.structure.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy;
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil;
|
||||
@@ -33,7 +31,6 @@ import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class DescriptorResolverUtils {
|
||||
@@ -121,33 +118,4 @@ public final class DescriptorResolverUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isObjectMethodInInterface(@NotNull JavaMember member) {
|
||||
return member.getContainingClass().isInterface() && member instanceof JavaMethod && isObjectMethod((JavaMethod) member);
|
||||
}
|
||||
|
||||
private static boolean isObjectMethod(@NotNull JavaMethod method) {
|
||||
String name = method.getName().asString();
|
||||
if (name.equals("toString") || name.equals("hashCode")) {
|
||||
return method.getValueParameters().isEmpty();
|
||||
}
|
||||
else if (name.equals("equals")) {
|
||||
return isMethodWithOneObjectParameter(method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isMethodWithOneObjectParameter(@NotNull JavaMethod method) {
|
||||
List<JavaValueParameter> parameters = method.getValueParameters();
|
||||
if (parameters.size() == 1) {
|
||||
JavaType type = parameters.get(0).getType();
|
||||
if (type instanceof JavaClassifierType) {
|
||||
JavaClassifier classifier = ((JavaClassifierType) type).getClassifier();
|
||||
if (classifier instanceof JavaClass) {
|
||||
FqName classFqName = ((JavaClass) classifier).getFqName();
|
||||
return classFqName != null && classFqName.asString().equals("java.lang.Object");
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.lazy.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaMember
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaMethod
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface DeclaredMemberIndex {
|
||||
@@ -44,7 +40,7 @@ open class ClassDeclaredMemberIndex(
|
||||
private val memberFilter: (JavaMember) -> Boolean
|
||||
) : DeclaredMemberIndex {
|
||||
private val methodFilter = { m: JavaMethod ->
|
||||
memberFilter(m) && !DescriptorResolverUtils.isObjectMethodInInterface(m)
|
||||
memberFilter(m) && !m.isObjectMethodInInterface()
|
||||
}
|
||||
|
||||
private val methods = jClass.methods.asSequence().filter(methodFilter).groupBy { m -> m.name }
|
||||
|
||||
Reference in New Issue
Block a user