From 37eccdb01f6e9c1b42a1b59cbd88d40ed14ba87b Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 12 Apr 2013 22:52:17 +0400 Subject: [PATCH] Saving "SAM interface" mark when resolving Java class. --- .../ClassDescriptorFromJvmBytecode.java | 9 ++++- .../resolve/java/provider/MembersCache.java | 5 ++- .../resolver/JavaClassObjectResolver.java | 6 ++-- .../java/resolver/JavaClassResolver.java | 5 +-- .../java/resolver/JavaFunctionResolver.java | 2 +- .../java/sam/SingleAbstractMethodUtils.java | 33 ++++++++++--------- 6 files changed, 36 insertions(+), 24 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java index d121fd76ffc..e2e95710cb7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java @@ -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; + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index e9294a2925e..5972f315d50 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -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; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index 12a1be64245..2a9c3c3f286 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -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; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 658f2544160..2d0dcf5c172 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -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())); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index c0db9157e23..3ec5bf7f34c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -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); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index d231c2fbf9d..7d021335ae8 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -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 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 getAbstractMembers(@NotNull JetType type) { List abstractMembers = Lists.newArrayList(); @@ -73,10 +58,28 @@ public class SingleAbstractMethodUtils { return KotlinBuiltIns.getInstance().getFunctionType(Collections.emptyList(), null, parameterTypes, returnType); } + private static boolean isSamInterface(@NotNull ClassDescriptor klass) { + if (klass.getKind() != ClassKind.TRAIT) { + return false; + } + + List 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(),