UAST: Implement getFunctionalInterfaceType for KotlinULambdaExpression
This commit is contained in:
+5
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.uast.UBlockExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
@@ -27,6 +28,9 @@ class KotlinULambdaExpression(
|
||||
override val psi: KtLambdaExpression,
|
||||
override val uastParent: UElement?
|
||||
) : KotlinAbstractUExpression(), ULambdaExpression, KotlinUElementWithType {
|
||||
val functionalInterfaceType: PsiType?
|
||||
get() = getFunctionalInterfaceType()
|
||||
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
||||
|
||||
override val valueParameters by lz {
|
||||
@@ -43,6 +47,6 @@ class KotlinULambdaExpression(
|
||||
val expressions = (body as? UBlockExpression)?.expressions
|
||||
?.joinToString("\n") { it.asRenderString().withMargin } ?: body.asRenderString()
|
||||
|
||||
return "{ " + renderedValueParameters + "\n" + expressions + "\n}"
|
||||
return "{ $renderedValueParameters\n$expressions\n}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.uast.kotlin.expressions
|
||||
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.PsiVariable
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.uast.*
|
||||
@@ -29,6 +30,8 @@ private class KotlinLocalFunctionULambdaExpression(
|
||||
override val psi: KtFunction,
|
||||
override val uastParent: UElement?
|
||||
): KotlinAbstractUExpression(), ULambdaExpression {
|
||||
val functionalInterfaceType: PsiType?
|
||||
get() = null
|
||||
|
||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
||||
|
||||
|
||||
@@ -30,11 +30,13 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightElements
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -43,6 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.typeUtil.isInterface
|
||||
import org.jetbrains.uast.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.StringCharacterIterator
|
||||
@@ -180,3 +183,18 @@ internal inline fun <reified T : UDeclaration, reified P : PsiElement> unwrap(el
|
||||
assert(unwrapped !is UElement)
|
||||
return unwrapped as P
|
||||
}
|
||||
|
||||
internal fun KtExpression.getExpectedType(): KotlinType? = analyze()[BindingContext.EXPECTED_EXPRESSION_TYPE, this]
|
||||
|
||||
internal fun KtTypeReference.getType(): KotlinType? = analyze()[BindingContext.TYPE, this]
|
||||
|
||||
internal fun KotlinType.getFunctionalInterfaceType(source: UElement, element: KtElement): PsiType? =
|
||||
takeIf { it.isInterface() && !it.isBuiltinFunctionalTypeOrSubtype }?.toPsiType(source, element, false)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
|
||||
val notSam = { /* Not SAM */ }
|
||||
var foo: java.lang.Runnable = {/* Variable */}
|
||||
fun bar(): java.lang.Runnable {
|
||||
foo = {/* Assignment */}
|
||||
val a = {/* Type Cast */} as java.lang.Runnable
|
||||
runRunnable {/* Argument */}
|
||||
return {/* Return */}
|
||||
}
|
||||
|
||||
fun runRunnable(r: java.lang.Runnable) = r()
|
||||
Reference in New Issue
Block a user