Kapt: Fix erasure() for executable types (KT-13629)
(cherry picked from commit 461c29d)
This commit is contained in:
committed by
Yan Zhulanow
parent
941d016cef
commit
9127788f4a
+13
-2
@@ -18,8 +18,7 @@ package org.jetbrains.kotlin.annotation.processing.impl
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import com.intellij.psi.util.*
|
||||
import org.jetbrains.kotlin.java.model.elements.JeClassInitializerExecutableElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JeMethodExecutableElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
@@ -104,7 +103,19 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager,
|
||||
override fun erasure(t: TypeMirror): TypeMirror {
|
||||
if (t.kind == TypeKind.PACKAGE) throw IllegalArgumentException("Invalid type: $t")
|
||||
return when (t) {
|
||||
is JeTypeVariableType -> TypeConversionUtil.typeParameterErasure(t.parameter).toJeType(t.psiManager)
|
||||
is JePsiType -> TypeConversionUtil.erasure(t.psiType).toJeType(psiManager)
|
||||
is JeMethodExecutableTypeMirror -> {
|
||||
val oldSignature = t.signature
|
||||
val parameterTypes = oldSignature?.parameterTypes?.toList() ?: t.psi.parameterList.parameters.map { it.type }
|
||||
val newSignature = MethodSignatureUtil.createMethodSignature(
|
||||
oldSignature?.name ?: t.psi.name,
|
||||
parameterTypes.map { TypeConversionUtil.erasure(it) }.toTypedArray(),
|
||||
emptyArray(),
|
||||
PsiSubstitutor.EMPTY,
|
||||
oldSignature?.isConstructor ?: t.psi.isConstructor)
|
||||
JeMethodExecutableTypeMirror(t.psi, newSignature, TypeConversionUtil.erasure(t.returnType ?: t.psi.returnType))
|
||||
}
|
||||
else -> t
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
abstract class Base<A> {
|
||||
fun baseF(): A = null!!
|
||||
}
|
||||
|
||||
@Deprecated("")
|
||||
class Test<T> : Base<Int>() {
|
||||
fun a(): String = ""
|
||||
fun b(i: String, b: CharSequence) {}
|
||||
fun c(): Int = 5
|
||||
fun d(): T = null!!
|
||||
fun <D : Any> e(item: D): D = item
|
||||
fun f(items: List<Map<String, Int>>, i: Int) {}
|
||||
fun <D : String> g(item: D) {}
|
||||
}
|
||||
+12
-1
@@ -55,7 +55,18 @@ class JeMethodExecutableTypeMirror(
|
||||
return typeParameters.map { JeTypeVariableType(PsiTypesUtil.getClassType(it), it) }
|
||||
}
|
||||
|
||||
override fun toString() = (psi.containingClass?.qualifiedName?.let { it + "." } ?: "") + psi.name
|
||||
override fun toString() = buildString {
|
||||
val typeVariables = this@JeMethodExecutableTypeMirror.typeVariables
|
||||
if (typeVariables.isNotEmpty()) {
|
||||
append('<')
|
||||
typeVariables.joinTo(this, ",")
|
||||
append('>')
|
||||
}
|
||||
append('(')
|
||||
parameterTypes.joinTo(this, ",")
|
||||
append(')')
|
||||
append((this@JeMethodExecutableTypeMirror as ExecutableType).returnType)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
+2
@@ -57,5 +57,7 @@ class JeTypeVariableType(
|
||||
return psiType == (other as? JeTypeVariableType)?.psiType
|
||||
}
|
||||
|
||||
override fun toString() = parameter.name ?: "<none>"
|
||||
|
||||
override fun hashCode() = psiType.hashCode()
|
||||
}
|
||||
+23
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.annotation.processing.test.processor
|
||||
|
||||
import org.jetbrains.kotlin.java.model.elements.*
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredType
|
||||
import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.type.DeclaredType
|
||||
@@ -161,4 +162,26 @@ class ProcessorTests : AbstractProcessorTest() {
|
||||
assertEquals(int, env.typeUtils.erasure(int))
|
||||
assertEquals(void, env.typeUtils.erasure(void))
|
||||
}
|
||||
|
||||
fun testErasure2() = test("Erasure2", "*") { set, roundEnv, env ->
|
||||
val test = env.findClass("Test")
|
||||
|
||||
val erasure = fun (t: JeMethodExecutableTypeMirror) = env.typeUtils.erasure(t)
|
||||
fun check(methodName: String, toString: String, transform: (JeMethodExecutableTypeMirror) -> TypeMirror = { it }) {
|
||||
val method = test.enclosedElements.first { it is JeMethodExecutableElement && it.simpleName.toString() == methodName }
|
||||
assertEquals(toString, transform((method as JeMethodExecutableElement).asType()).toString())
|
||||
}
|
||||
|
||||
check("a", "()java.lang.String")
|
||||
check("b", "(java.lang.String,java.lang.CharSequence)void")
|
||||
check("c", "()int")
|
||||
|
||||
check("d", "()T")
|
||||
check("e", "<D>(D)D")
|
||||
check("e", "(java.lang.Object)java.lang.Object", erasure)
|
||||
check("f", "(java.util.List<? extends java.util.Map<java.lang.String,java.lang.Integer>>,int)void")
|
||||
check("f", "(java.util.List,int)void", erasure)
|
||||
check("g", "<D>(D)void")
|
||||
check("g", "(java.lang.String)void", erasure)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user