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 &&
|
||||
|
||||
Reference in New Issue
Block a user