Move SAM function type calculation to SamConversionResolver
This commit is contained in:
+47
@@ -24,6 +24,15 @@ import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.TypeUtils
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
|
||||
import org.jetbrains.jet.lang.resolve.java.sources.JavaSourceElement
|
||||
|
||||
public object SamConversionResolverImpl : SamConversionResolver {
|
||||
override fun resolveSamConstructor(name: Name, scope: JetScope): SamConstructorDescriptor? {
|
||||
@@ -41,4 +50,42 @@ public object SamConversionResolverImpl : SamConversionResolver {
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveFunctionTypeIfSamInterface(
|
||||
classDescriptor: JavaClassDescriptor,
|
||||
resolveMethod: (JavaMethod) -> FunctionDescriptor
|
||||
): JetType? {
|
||||
val jClass = (classDescriptor.getSource() as? JavaSourceElement)?.javaElement as? JavaClass ?: return null
|
||||
val samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(jClass) ?: return null
|
||||
val abstractMethod = if (jClass.getFqName() == samInterfaceMethod.getContainingClass().getFqName()) {
|
||||
resolveMethod(samInterfaceMethod)
|
||||
}
|
||||
else {
|
||||
findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(classDescriptor.getDefaultType()))
|
||||
}
|
||||
return SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod)
|
||||
}
|
||||
|
||||
private fun findFunctionWithMostSpecificReturnType(supertypes: Set<JetType>): SimpleFunctionDescriptor {
|
||||
val candidates = ArrayList<SimpleFunctionDescriptor>(supertypes.size())
|
||||
for (supertype in supertypes) {
|
||||
val abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype)
|
||||
if (!abstractMembers.isEmpty()) {
|
||||
candidates.add((abstractMembers[0] as SimpleFunctionDescriptor))
|
||||
}
|
||||
}
|
||||
if (candidates.isEmpty()) {
|
||||
throw IllegalStateException("Couldn't find abstract method in supertypes " + supertypes)
|
||||
}
|
||||
var currentMostSpecificType = candidates[0]
|
||||
for (candidate in candidates) {
|
||||
val candidateReturnType = candidate.getReturnType()
|
||||
val currentMostSpecificReturnType = currentMostSpecificType.getReturnType()
|
||||
assert(candidateReturnType != null && currentMostSpecificReturnType != null) { "$candidate, $currentMostSpecificReturnType" }
|
||||
if (JetTypeChecker.DEFAULT.isSubtypeOf(candidateReturnType!!, currentMostSpecificReturnType!!)) {
|
||||
currentMostSpecificType = candidate
|
||||
}
|
||||
}
|
||||
return currentMostSpecificType
|
||||
}
|
||||
}
|
||||
|
||||
+2
-45
@@ -31,13 +31,8 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
|
||||
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
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.types.TypeUtils
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.types.AbstractClassTypeConstructor
|
||||
|
||||
class LazyJavaClassDescriptor(
|
||||
@@ -96,51 +91,13 @@ class LazyJavaClassDescriptor(
|
||||
override fun getAnnotations() = _annotations()
|
||||
|
||||
private val _functionTypeForSamInterface = c.storageManager.createNullableLazyValue {
|
||||
val samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(jClass);
|
||||
if (samInterfaceMethod != null) {
|
||||
val abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod);
|
||||
SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod);
|
||||
c.samConversionResolver.resolveFunctionTypeIfSamInterface(this) { method ->
|
||||
_scopeForMemberLookup.resolveMethodToFunctionDescriptor(method, false)
|
||||
}
|
||||
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 findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(getDefaultType()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun findFunctionWithMostSpecificReturnType(supertypes: Set<JetType>): SimpleFunctionDescriptor {
|
||||
val candidates = ArrayList<SimpleFunctionDescriptor>(supertypes.size())
|
||||
for (supertype in supertypes) {
|
||||
val abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype)
|
||||
if (!abstractMembers.isEmpty()) {
|
||||
candidates.add((abstractMembers[0] as SimpleFunctionDescriptor))
|
||||
}
|
||||
}
|
||||
if (candidates.isEmpty()) {
|
||||
throw IllegalStateException("Couldn't find abstract method in supertypes " + supertypes)
|
||||
}
|
||||
var currentMostSpecificType = candidates[0]
|
||||
for (candidate in candidates) {
|
||||
val candidateReturnType = candidate.getReturnType()
|
||||
val currentMostSpecificReturnType = currentMostSpecificType.getReturnType()
|
||||
assert(candidateReturnType != null && currentMostSpecificReturnType != null, "$candidate, $currentMostSpecificReturnType")
|
||||
if (JetTypeChecker.DEFAULT.isSubtypeOf(candidateReturnType!!, currentMostSpecificReturnType!!)) {
|
||||
currentMostSpecificType = candidate
|
||||
}
|
||||
}
|
||||
return currentMostSpecificType
|
||||
}
|
||||
|
||||
override fun toString() = "lazy java class $fqName"
|
||||
|
||||
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor() {
|
||||
|
||||
+8
@@ -20,9 +20,17 @@ import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor
|
||||
|
||||
public trait SamConversionResolver {
|
||||
public fun resolveSamConstructor(name: Name, scope: JetScope): SamConstructorDescriptor?
|
||||
|
||||
public fun <D : FunctionDescriptor> resolveSamAdapter(original: D): D?
|
||||
|
||||
public fun resolveFunctionTypeIfSamInterface(
|
||||
classDescriptor: JavaClassDescriptor,
|
||||
resolveMethod: (JavaMethod) -> FunctionDescriptor
|
||||
): JetType?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user