Support SAM adapters for functions and constructors

This commit is contained in:
Andrey Breslav
2013-10-29 14:49:33 +04:00
parent 834db7a7cc
commit 7619e8f3c7
6 changed files with 54 additions and 15 deletions
@@ -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 {
@@ -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())
}
@@ -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())
@@ -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);
@@ -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;
}
}
@@ -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;
}