Saving "SAM interface" mark when resolving Java class.

This commit is contained in:
Evgeny Gerashchenko
2013-04-12 22:52:17 +04:00
parent 0ae0941e43
commit 37eccdb01f
6 changed files with 36 additions and 24 deletions
@@ -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;
}
}
@@ -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;
}
@@ -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;
@@ -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()));
@@ -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);
@@ -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(),