Fixed loading SAM interfaces when they inherit abstract methods.
This commit is contained in:
-3
@@ -409,9 +409,6 @@ public final class MembersCache {
|
||||
// Returns null if not SAM interface
|
||||
@Nullable
|
||||
public static PsiMethod getSamInterfaceMethod(@NotNull PsiClass psiClass) {
|
||||
if (psiClass.hasModifierProperty(PsiModifier.PRIVATE)) { // TODO hacky
|
||||
return null;
|
||||
}
|
||||
if (DescriptorResolverUtils.isKotlinClass(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+32
-2
@@ -44,6 +44,8 @@ import org.jetbrains.jet.lang.resolve.name.FqNameBase;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
@@ -275,14 +277,42 @@ public final class JavaClassResolver {
|
||||
|
||||
PsiMethod samInterfaceMethod = MembersCache.getSamInterfaceMethod(psiClass);
|
||||
if (samInterfaceMethod != null) {
|
||||
SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely(
|
||||
psiClass, new PsiMethodWrapper(samInterfaceMethod), classDescriptor);
|
||||
SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(psiClass, samInterfaceMethod, classDescriptor);
|
||||
classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod));
|
||||
}
|
||||
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SimpleFunctionDescriptor resolveFunctionOfSamInterface(
|
||||
@NotNull PsiClass psiClass,
|
||||
@NotNull PsiMethod samInterfaceMethod,
|
||||
@NotNull ClassDescriptorFromJvmBytecode samInterface
|
||||
) {
|
||||
PsiClass methodContainer = samInterfaceMethod.getContainingClass();
|
||||
assert methodContainer != null : "method container is null for " + methodContainer;
|
||||
String containerQualifiedName = methodContainer.getQualifiedName();
|
||||
assert containerQualifiedName != null : "qualified name is null for " + psiClass;
|
||||
|
||||
if (DescriptorUtils.getFQName(samInterface).getFqName().equals(containerQualifiedName)) {
|
||||
SimpleFunctionDescriptor abstractMethod =
|
||||
functionResolver.resolveFunctionMutely(new PsiMethodWrapper(samInterfaceMethod), samInterface);
|
||||
assert abstractMethod != null : "couldn't resolve method " + samInterfaceMethod;
|
||||
return abstractMethod;
|
||||
}
|
||||
else {
|
||||
Set<JetType> supertypes = TypeUtils.getAllSupertypes(samInterface.getDefaultType());
|
||||
for (JetType supertype : supertypes) {
|
||||
List<CallableMemberDescriptor> abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype);
|
||||
if (!abstractMembers.isEmpty()) {
|
||||
return (SimpleFunctionDescriptor) abstractMembers.get(0);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Couldn't find abstract method in supertypes " + supertypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void cache(@NotNull FqNameBase fqName, @Nullable ClassDescriptor classDescriptor) {
|
||||
if (classDescriptor == null) {
|
||||
cacheNegativeValue(fqName);
|
||||
|
||||
+4
-2
@@ -92,10 +92,12 @@ public final class JavaFunctionResolver {
|
||||
|
||||
@Nullable
|
||||
SimpleFunctionDescriptor resolveFunctionMutely(
|
||||
@NotNull PsiClass psiClass, PsiMethodWrapper method,
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull ClassOrNamespaceDescriptor ownerDescriptor
|
||||
) {
|
||||
return resolveMethodToFunctionDescriptor(psiClass, method, DeclarationOrigin.JAVA, ownerDescriptor, false);
|
||||
PsiClass containingClass = method.getPsiMethod().getContainingClass();
|
||||
assert containingClass != null : "containing class is null for " + method;
|
||||
return resolveMethodToFunctionDescriptor(containingClass, method, DeclarationOrigin.JAVA, ownerDescriptor, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import static org.jetbrains.jet.lang.types.Variance.INVARIANT;
|
||||
public class SingleAbstractMethodUtils {
|
||||
|
||||
@NotNull
|
||||
private static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
||||
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
||||
List<CallableMemberDescriptor> abstractMembers = Lists.newArrayList();
|
||||
for (DeclarationDescriptor member : type.getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof CallableMemberDescriptor &&
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package test;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public interface SubstitutedSamInterface extends Comparator<String> {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
public /*synthesized*/ fun SubstitutedSamInterface(/*0*/ function: (jet.String?, jet.String?) -> jet.Int): test.SubstitutedSamInterface
|
||||
|
||||
public trait SubstitutedSamInterface : java.util.Comparator<jet.String> {
|
||||
public abstract override /*1*/ /*fake_override*/ fun compare(/*0*/ p0: jet.String?, /*1*/ p1: jet.String?): jet.Int
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package test;
|
||||
|
||||
public interface SubstitutedSamInterfaceSubclassOfBuiltin extends Comparable<SubstitutedSamInterfaceSubclassOfBuiltin> {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
public /*synthesized*/ fun SubstitutedSamInterfaceSubclassOfBuiltin(/*0*/ function: (test.SubstitutedSamInterfaceSubclassOfBuiltin) -> jet.Int): test.SubstitutedSamInterfaceSubclassOfBuiltin
|
||||
|
||||
public trait SubstitutedSamInterfaceSubclassOfBuiltin : jet.Comparable<test.SubstitutedSamInterfaceSubclassOfBuiltin> {
|
||||
public abstract override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.SubstitutedSamInterfaceSubclassOfBuiltin): jet.Int
|
||||
}
|
||||
@@ -1218,6 +1218,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/Runnable.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSamInterface.java")
|
||||
public void testSubstitutedSamInterface() throws Exception {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSamInterfaceSubclassOfBuiltin.java")
|
||||
public void testSubstitutedSamInterfaceSubclassOfBuiltin() throws Exception {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter")
|
||||
public static class Adapter extends AbstractLoadJavaTest {
|
||||
public void testAllFilesPresentInAdapter() throws Exception {
|
||||
|
||||
+5
@@ -130,6 +130,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritClassWithParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InheritSubstitutedMethod.kt")
|
||||
public void testInheritSubstitutedMethod() throws Exception {
|
||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InheritTraitWithParam.kt")
|
||||
public void testInheritTraitWithParam() throws Exception {
|
||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritTraitWithParam.kt");
|
||||
|
||||
Reference in New Issue
Block a user