Saving "SAM interface" mark when resolving Java class.
This commit is contained in:
+8
-1
@@ -30,15 +30,18 @@ import java.util.Collection;
|
||||
* @see org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor
|
||||
*/
|
||||
public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite {
|
||||
private final boolean isSamInterface;
|
||||
|
||||
private JavaClassNonStaticMembersScope scopeForConstructorResolve;
|
||||
|
||||
public ClassDescriptorFromJvmBytecode(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull ClassKind kind,
|
||||
boolean isInner
|
||||
boolean isInner,
|
||||
boolean isSamInterface
|
||||
) {
|
||||
super(containingDeclaration, kind, isInner);
|
||||
this.isSamInterface = isSamInterface;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,4 +61,8 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite {
|
||||
public void setScopeForConstructorResolve(@NotNull JavaClassNonStaticMembersScope scopeForConstructorResolve) {
|
||||
this.scopeForConstructorResolve = scopeForConstructorResolve;
|
||||
}
|
||||
|
||||
public boolean isSamInterface() {
|
||||
return isSamInterface;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -336,7 +336,10 @@ public final class MembersCache {
|
||||
}
|
||||
|
||||
public static boolean isSamInterface(@NotNull PsiClass psiClass) {
|
||||
if (!psiClass.isInterface()) {
|
||||
if (DescriptorResolverUtils.isKotlinClass(psiClass)) {
|
||||
return false;
|
||||
}
|
||||
if (!psiClass.isInterface() || psiClass.isAnnotationType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -26,11 +26,9 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassObjectAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProviderFactory;
|
||||
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
@@ -102,7 +100,7 @@ public final class JavaClassObjectResolver {
|
||||
FqName fqName = new FqName(qualifiedName);
|
||||
ClassPsiDeclarationProvider classObjectData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(classObjectPsiClass);
|
||||
ClassDescriptorFromJvmBytecode classObjectDescriptor
|
||||
= new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false);
|
||||
= new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false, false);
|
||||
classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor,
|
||||
new PsiClassWrapper(classObjectPsiClass),
|
||||
classObjectData,
|
||||
@@ -131,7 +129,7 @@ public final class JavaClassObjectResolver {
|
||||
) {
|
||||
FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass);
|
||||
ClassDescriptorFromJvmBytecode classObjectDescriptor =
|
||||
new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false);
|
||||
new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false, false);
|
||||
ClassPsiDeclarationProvider data = semanticServices.getPsiDeclarationProviderFactory().createSyntheticClassObjectClassData(psiClass);
|
||||
setUpClassObjectDescriptor(classObjectDescriptor, containing, fqName, data, getClassObjectName(containing.getName().getName()));
|
||||
return classObjectDescriptor;
|
||||
|
||||
+3
-2
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.MembersCache;
|
||||
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
@@ -227,8 +228,8 @@ public final class JavaClassResolver {
|
||||
|
||||
ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
|
||||
ClassPsiDeclarationProvider classData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(psiClass);
|
||||
ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(containingDeclaration, kind,
|
||||
isInnerClass(psiClass));
|
||||
ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(
|
||||
containingDeclaration, kind, isInnerClass(psiClass), MembersCache.isSamInterface(psiClass));
|
||||
|
||||
cache(javaClassToKotlinFqName(fqName), classDescriptor);
|
||||
classDescriptor.setName(Name.identifier(psiClass.getName()));
|
||||
|
||||
+1
-1
@@ -357,7 +357,7 @@ public final class JavaFunctionResolver {
|
||||
PsiClass samInterface = namedMembers.getSamInterface();
|
||||
if (samInterface != null) {
|
||||
ClassDescriptor klass = findClassInNamespace(ownerDescriptor, namedMembers.getName());
|
||||
if (klass != null && SingleAbstractMethodUtils.isSamInterface(klass)) {
|
||||
if (klass != null) {
|
||||
SimpleFunctionDescriptor constructorFunction = SingleAbstractMethodUtils.createSamConstructorFunction(ownerDescriptor,
|
||||
klass);
|
||||
trace.record(BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, constructorFunction, klass);
|
||||
|
||||
+18
-15
@@ -36,21 +36,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SingleAbstractMethodUtils {
|
||||
public static boolean isSamInterface(@NotNull ClassDescriptor klass) {
|
||||
if (klass.getKind() != ClassKind.TRAIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass.getDefaultType());
|
||||
if (abstractMembers.size() == 1) {
|
||||
CallableMemberDescriptor member = abstractMembers.get(0);
|
||||
if (member instanceof SimpleFunctionDescriptor) {
|
||||
return member.getTypeParameters().isEmpty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
||||
List<CallableMemberDescriptor> abstractMembers = Lists.newArrayList();
|
||||
@@ -73,10 +58,28 @@ public class SingleAbstractMethodUtils {
|
||||
return KotlinBuiltIns.getInstance().getFunctionType(Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType);
|
||||
}
|
||||
|
||||
private static boolean isSamInterface(@NotNull ClassDescriptor klass) {
|
||||
if (klass.getKind() != ClassKind.TRAIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass.getDefaultType());
|
||||
if (abstractMembers.size() == 1) {
|
||||
CallableMemberDescriptor member = abstractMembers.get(0);
|
||||
if (member instanceof SimpleFunctionDescriptor) {
|
||||
return member.getTypeParameters().isEmpty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleFunctionDescriptor createSamConstructorFunction(
|
||||
@NotNull ClassOrNamespaceDescriptor owner,
|
||||
@NotNull ClassDescriptor samInterface
|
||||
) {
|
||||
assert isSamInterface(samInterface) : samInterface;
|
||||
|
||||
SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl(
|
||||
owner,
|
||||
samInterface.getAnnotations(),
|
||||
|
||||
Reference in New Issue
Block a user