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