Uast: properly handling explicit SAM (KT-25297)

This commit is contained in:
Nicolay Mitropolsky
2018-07-07 00:36:03 +03:00
committed by xiexed
parent 38e2d474b7
commit 2c7687195c
4 changed files with 20 additions and 3 deletions
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -297,10 +298,14 @@ internal fun KotlinType.getFunctionalInterfaceType(source: UElement, element: Kt
internal fun KotlinULambdaExpression.getFunctionalInterfaceType(): PsiType? {
val parent = psi.parent
return when (parent) {
is KtBinaryExpressionWithTypeRHS -> parent.right?.getType()?.getFunctionalInterfaceType(this, psi)
else -> psi.getExpectedType()?.getFunctionalInterfaceType(this, psi)
if (parent is KtBinaryExpressionWithTypeRHS) return parent.right?.getType()?.getFunctionalInterfaceType(this, psi)
if (parent is KtLambdaArgument) run {
val callExpression = parent.parent as? KtCallExpression ?: return@run
val resolvedCall = callExpression.getResolvedCall(callExpression.analyze()) ?: return@run
val samConstructorDescriptor = resolvedCall.candidateDescriptor as? SamConstructorDescriptor ?: return@run
return samConstructorDescriptor.returnType?.getFunctionalInterfaceType(this, psi)
}
return psi.getExpectedType()?.getFunctionalInterfaceType(this, psi)
}
internal fun unwrapFakeFileForLightClass(file: PsiFile): PsiFile = (file as? FakeFileForLightClass)?.ktFile ?: file
+2
View File
@@ -8,4 +8,6 @@ fun bar(): java.lang.Runnable {
return {/* Return */}
}
val baz = java.lang.Runnable { /* SAM */ }
fun runRunnable(r: java.lang.Runnable) = r()
@@ -98,6 +98,11 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Return */}").functionalInterfaceType?.canonicalText)
assertEquals(
"java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{ /* SAM */ }").functionalInterfaceType?.canonicalText
)
}
}
@@ -99,6 +99,11 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Return */}").functionalInterfaceType?.canonicalText)
assertEquals(
"java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{ /* SAM */ }").functionalInterfaceType?.canonicalText
)
}
}