Support SAM adapters for functions and constructors
This commit is contained in:
+31
-8
@@ -11,7 +11,6 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver
|
||||
import org.jetbrains.jet.utils.emptyOrSingletonList
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import java.util.Collections
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
|
||||
@@ -23,20 +22,21 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
|
||||
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType
|
||||
import org.jetbrains.jet.utils.*
|
||||
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.jet.lang.types.TypeUtils
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor
|
||||
|
||||
class LazyJavaClassDescriptor(
|
||||
private val c: LazyJavaResolverContextWithTypes,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
internal val fqName: FqName,
|
||||
private val jClass: JavaClass
|
||||
) : ClassDescriptorBase(containingDeclaration, fqName.shortName()), LazyJavaDescriptor {
|
||||
) : ClassDescriptorBase(containingDeclaration, fqName.shortName()), LazyJavaDescriptor, JavaClassDescriptor {
|
||||
|
||||
private val innerC: LazyJavaResolverContextWithTypes = c.child(this, jClass.getTypeParameters().toSet())
|
||||
|
||||
@@ -73,6 +73,29 @@ class LazyJavaClassDescriptor(
|
||||
private val _annotations = c.resolveAnnotations(jClass.getAnnotations())
|
||||
override fun getAnnotations(): List<AnnotationDescriptor> = _annotations
|
||||
|
||||
private val _functionTypeForSamInterface = c.storageManager.createNullableLazyValue {
|
||||
val samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(jClass);
|
||||
if (samInterfaceMethod != null) {
|
||||
val abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod);
|
||||
SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod);
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
override fun getFunctionTypeForSamInterface(): JetType? = _functionTypeForSamInterface()
|
||||
|
||||
private fun resolveFunctionOfSamInterface(samInterfaceMethod: JavaMethod): SimpleFunctionDescriptor {
|
||||
val methodContainer = samInterfaceMethod.getContainingClass()
|
||||
val containerFqName = methodContainer.getFqName()
|
||||
assert(containerFqName != null, "qualified name is null for " + methodContainer)
|
||||
if (fqName == containerFqName) {
|
||||
return _scopeForMemberLookup.resolveMethodToFunctionDescriptor(samInterfaceMethod, false)
|
||||
}
|
||||
else {
|
||||
return JavaClassResolver.findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(getDefaultType()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString() = "lazy java class $fqName"
|
||||
|
||||
private inner class LazyJavaClassTypeConstructor : TypeConstructor {
|
||||
|
||||
+10
-2
@@ -60,8 +60,16 @@ public class LazyJavaClassMemberScope(
|
||||
override fun computeMemberIndex(): MemberIndex = ClassMemberIndex(jClass, mustBeStatic = false)
|
||||
|
||||
internal val _constructors = c.storageManager.createLazyValue {
|
||||
jClass.getConstructors().map {
|
||||
jCtor -> resolveConstructor(jCtor, getContainingDeclaration(), jClass.isStatic())
|
||||
jClass.getConstructors().flatMap {
|
||||
jCtor ->
|
||||
val constructor = resolveConstructor(jCtor, getContainingDeclaration(), jClass.isStatic())
|
||||
val samAdapter = JavaConstructorResolver.resolveSamAdapter(constructor)
|
||||
if (samAdapter != null) {
|
||||
(samAdapter as ConstructorDescriptorImpl).setReturnType(containingDeclaration.getDefaultType())
|
||||
listOf(constructor, samAdapter)
|
||||
}
|
||||
else
|
||||
listOf(constructor)
|
||||
} ifEmpty {
|
||||
emptyOrSingletonList(createDefaultConstructor())
|
||||
}
|
||||
|
||||
+10
-2
@@ -66,7 +66,15 @@ public abstract class LazyJavaMemberScope(
|
||||
(name: Name): Collection<FunctionDescriptor>
|
||||
->
|
||||
val methods = memberIndex().findMethodsByName(name)
|
||||
val functions = LinkedHashSet(methods.map {m -> resolveMethodToFunctionDescriptor(m, true)})
|
||||
val functions = LinkedHashSet(methods.flatMap {
|
||||
m ->
|
||||
val function = resolveMethodToFunctionDescriptor(m, true)
|
||||
val samAdapter = JavaFunctionResolver.resolveSamAdapter(function)
|
||||
if (samAdapter != null)
|
||||
listOf(function, samAdapter)
|
||||
else
|
||||
listOf(function)
|
||||
})
|
||||
|
||||
if (_containingDeclaration is ClassDescriptor) {
|
||||
val functionsFromSupertypes = JavaFunctionResolver.getFunctionsFromSupertypes(name, _containingDeclaration);
|
||||
@@ -84,7 +92,7 @@ public abstract class LazyJavaMemberScope(
|
||||
functions
|
||||
}
|
||||
|
||||
private fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): SimpleFunctionDescriptor {
|
||||
internal fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): SimpleFunctionDescriptor {
|
||||
|
||||
val functionDescriptorImpl = JavaMethodDescriptor(_containingDeclaration, c.resolveAnnotations(method.getAnnotations()), method.getName())
|
||||
|
||||
|
||||
+1
-1
@@ -331,7 +331,7 @@ public final class JavaClassResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SimpleFunctionDescriptor findFunctionWithMostSpecificReturnType(@NotNull Set<JetType> supertypes) {
|
||||
public static SimpleFunctionDescriptor findFunctionWithMostSpecificReturnType(@NotNull Set<JetType> supertypes) {
|
||||
List<SimpleFunctionDescriptor> candidates = new ArrayList<SimpleFunctionDescriptor>(supertypes.size());
|
||||
for (JetType supertype : supertypes) {
|
||||
List<CallableMemberDescriptor> abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype);
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ public final class JavaConstructorResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) {
|
||||
public static ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) {
|
||||
return isSamAdapterNecessary(original) ? (ConstructorDescriptor) createSamAdapterConstructor(original) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ public final class JavaFunctionResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static SimpleFunctionDescriptor resolveSamAdapter(@NotNull SimpleFunctionDescriptor original) {
|
||||
public static SimpleFunctionDescriptor resolveSamAdapter(@NotNull SimpleFunctionDescriptor original) {
|
||||
return isSamAdapterNecessary(original) ? (SimpleFunctionDescriptor) createSamAdapterFunction(original) : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user