UAST: Implement getFunctionalInterfaceType for KotlinULambdaExpression
This commit is contained in:
+5
-1
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.uast.kotlin
|
package org.jetbrains.uast.kotlin
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||||
import org.jetbrains.uast.UBlockExpression
|
import org.jetbrains.uast.UBlockExpression
|
||||||
import org.jetbrains.uast.UElement
|
import org.jetbrains.uast.UElement
|
||||||
@@ -27,6 +28,9 @@ class KotlinULambdaExpression(
|
|||||||
override val psi: KtLambdaExpression,
|
override val psi: KtLambdaExpression,
|
||||||
override val uastParent: UElement?
|
override val uastParent: UElement?
|
||||||
) : KotlinAbstractUExpression(), ULambdaExpression, KotlinUElementWithType {
|
) : KotlinAbstractUExpression(), ULambdaExpression, KotlinUElementWithType {
|
||||||
|
val functionalInterfaceType: PsiType?
|
||||||
|
get() = getFunctionalInterfaceType()
|
||||||
|
|
||||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
||||||
|
|
||||||
override val valueParameters by lz {
|
override val valueParameters by lz {
|
||||||
@@ -43,6 +47,6 @@ class KotlinULambdaExpression(
|
|||||||
val expressions = (body as? UBlockExpression)?.expressions
|
val expressions = (body as? UBlockExpression)?.expressions
|
||||||
?.joinToString("\n") { it.asRenderString().withMargin } ?: body.asRenderString()
|
?.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
|
package org.jetbrains.uast.kotlin.expressions
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
import com.intellij.psi.PsiVariable
|
import com.intellij.psi.PsiVariable
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
@@ -29,6 +30,8 @@ private class KotlinLocalFunctionULambdaExpression(
|
|||||||
override val psi: KtFunction,
|
override val psi: KtFunction,
|
||||||
override val uastParent: UElement?
|
override val uastParent: UElement?
|
||||||
): KotlinAbstractUExpression(), ULambdaExpression {
|
): KotlinAbstractUExpression(), ULambdaExpression {
|
||||||
|
val functionalInterfaceType: PsiType?
|
||||||
|
get() = null
|
||||||
|
|
||||||
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
|
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 com.intellij.psi.util.PsiTypesUtil
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightElements
|
import org.jetbrains.kotlin.asJava.toLightElements
|
||||||
|
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
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.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.isError
|
import org.jetbrains.kotlin.types.isError
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isInterface
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.text.StringCharacterIterator
|
import java.text.StringCharacterIterator
|
||||||
@@ -180,3 +183,18 @@ internal inline fun <reified T : UDeclaration, reified P : PsiElement> unwrap(el
|
|||||||
assert(unwrapped !is UElement)
|
assert(unwrapped !is UElement)
|
||||||
return unwrapped as P
|
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