Uast: the returnType support for light methods for reified functions (KT-35610)
This commit is contained in:
@@ -16,23 +16,21 @@
|
||||
|
||||
package org.jetbrains.uast.kotlin.declarations
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder
|
||||
import com.intellij.psi.impl.light.LightModifierList
|
||||
import com.intellij.psi.impl.light.LightParameterListBuilder
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.isGetter
|
||||
import org.jetbrains.kotlin.asJava.elements.isSetter
|
||||
import com.intellij.psi.impl.light.LightTypeParameterBuilder
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||
import org.jetbrains.uast.kotlin.*
|
||||
@@ -164,6 +162,22 @@ private fun buildLightMethodFake(original: KtFunction): PsiMethod = object : Lig
|
||||
containingClass = original.containingClassOrObject?.toLightClass() ?: original.containingKtFile.findFacadeClass()
|
||||
}
|
||||
|
||||
private val _buildTypeParameterList by lazy {
|
||||
KotlinLightTypeParameterListBuilder(this).also { paramList ->
|
||||
for ((i, p) in original.typeParameters.withIndex()) {
|
||||
paramList.addParameter(LightTypeParameterBuilder(p.name ?: "__no_name__", this, i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = _buildTypeParameterList
|
||||
|
||||
override fun getReturnType(): PsiType? {
|
||||
val context = original.analyze()
|
||||
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, original).safeAs<CallableDescriptor>() ?: return null
|
||||
return descriptor.returnType?.toPsiType(this, original, false)
|
||||
}
|
||||
|
||||
override fun getParent(): PsiElement? = containingClass
|
||||
}
|
||||
|
||||
|
||||
+21
-4
@@ -20,17 +20,18 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder
|
||||
import com.intellij.psi.impl.light.LightModifierList
|
||||
import com.intellij.psi.impl.light.LightParameterListBuilder
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.isGetter
|
||||
import org.jetbrains.kotlin.asJava.elements.isSetter
|
||||
import com.intellij.psi.impl.light.LightTypeParameterBuilder
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||
import org.jetbrains.uast.kotlin.*
|
||||
@@ -164,6 +165,22 @@ private fun buildLightMethodFake(original: KtFunction): PsiMethod = object : Lig
|
||||
containingClass = original.containingClassOrObject?.toLightClass() ?: original.containingKtFile.findFacadeClass()
|
||||
}
|
||||
|
||||
private val _buildTypeParameterList by lazy {
|
||||
KotlinLightTypeParameterListBuilder(this).also { paramList ->
|
||||
for ((i, p) in original.typeParameters.withIndex()) {
|
||||
paramList.addParameter(LightTypeParameterBuilder(p.name ?: "__no_name__", this, i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = _buildTypeParameterList
|
||||
|
||||
override fun getReturnType(): PsiType? {
|
||||
val context = original.analyze()
|
||||
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, original).safeAs<CallableDescriptor>() ?: return null
|
||||
return descriptor.returnType?.toPsiType(this, original, false)
|
||||
}
|
||||
|
||||
override fun getParent(): PsiElement? = containingClass
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,6 @@ public final class Test {
|
||||
}
|
||||
public fun Test() = UastEmptyExpression
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "nothing")
|
||||
fun test2() {
|
||||
fun test2() : void {
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -4,8 +4,8 @@ public final class ReifiedKt {
|
||||
public static final fun systemService2(@org.jetbrains.annotations.NotNull $this$systemService2: test.pkg.Context) : error.NonExistentClass {
|
||||
return <anonymous class>(java.lang.String.java)
|
||||
}
|
||||
fun systemService1() {
|
||||
return <anonymous class>(java.lang.Object.java)
|
||||
fun systemService1() : <ErrorType> {
|
||||
return <anonymous class>(T.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public final class Context {
|
||||
return <anonymous class>(java.lang.String.java)
|
||||
}
|
||||
public fun Context() = UastEmptyExpression
|
||||
fun ownSystemService1() {
|
||||
return <anonymous class>(java.lang.Object.java)
|
||||
fun ownSystemService1() : <ErrorType> {
|
||||
return <anonymous class>(T.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
inline fun <T> function1(t: T) {}
|
||||
inline fun <T> function2(t: T): T = t
|
||||
inline fun <reified T> function3(t: T) {}
|
||||
inline fun <reified T> function4(t: T): T = t
|
||||
inline fun <reified T> function5(t: T): Int = 42
|
||||
inline fun <reified T : Activity> T.function6(t: T): T = t
|
||||
inline fun <reified T> function7(t: T): T = t
|
||||
private inline fun <reified T> function8(t: T): T = t
|
||||
internal inline fun <reified T> function9(t: T): T = t
|
||||
public inline fun <reified T> function10(t: T): T = t
|
||||
inline fun <reified T> T.function11(t: T): T = t
|
||||
+1
-1
@@ -11,7 +11,7 @@ public final class Context {
|
||||
return suspendPrivate()
|
||||
}
|
||||
public fun Context() = UastEmptyExpression
|
||||
fun suspendPrivate() {
|
||||
fun suspendPrivate() : int {
|
||||
return inner()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,6 +595,26 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReifiedReturnTypes() {
|
||||
doTest("ReifiedReturnType") { _, file ->
|
||||
val methods = file.classes.flatMap { it.methods.asIterable() }
|
||||
assertEquals("""
|
||||
function1 -> PsiType:void
|
||||
function2 -> PsiType:T
|
||||
function3 -> PsiType:void
|
||||
function4 -> PsiType:T
|
||||
function5 -> PsiType:int
|
||||
function6 -> PsiType:T
|
||||
function7 -> PsiType:T
|
||||
function8 -> PsiType:T
|
||||
function9 -> PsiType:T
|
||||
function10 -> PsiType:T
|
||||
function11 -> PsiType:T
|
||||
""".trimIndent(), methods.joinToString("\n") { m -> m.name + " -> " + m.returnType.toString() })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T =
|
||||
|
||||
Reference in New Issue
Block a user