From 9127788f4a76f54b510885216286f1cf26493b35 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 29 Aug 2016 21:13:17 +0300 Subject: [PATCH] Kapt: Fix erasure() for executable types (KT-13629) (cherry picked from commit 461c29d) --- .../annotation/processing/impl/KotlinTypes.kt | 15 ++++++++++-- .../testData/processors/Erasure2.kt | 14 +++++++++++ .../types/JeMethodExecutableTypeMirror.kt | 13 ++++++++++- .../java/model/types/JeTypeVariableType.kt | 2 ++ .../test/processor/ProcessorTests.kt | 23 +++++++++++++++++++ 5 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 plugins/annotation-processing/testData/processors/Erasure2.kt diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt index 2f7309aac63..5148fb61470 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt @@ -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 } } diff --git a/plugins/annotation-processing/testData/processors/Erasure2.kt b/plugins/annotation-processing/testData/processors/Erasure2.kt new file mode 100644 index 00000000000..ec6d6270f7a --- /dev/null +++ b/plugins/annotation-processing/testData/processors/Erasure2.kt @@ -0,0 +1,14 @@ +abstract class Base { + fun baseF(): A = null!! +} + +@Deprecated("") +class Test : Base() { + fun a(): String = "" + fun b(i: String, b: CharSequence) {} + fun c(): Int = 5 + fun d(): T = null!! + fun e(item: D): D = item + fun f(items: List>, i: Int) {} + fun g(item: D) {} +} \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt index ad7a3d8a22a..038d693511a 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt @@ -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 diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt index 197eff47a91..9b2d31c0f02 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt @@ -57,5 +57,7 @@ class JeTypeVariableType( return psiType == (other as? JeTypeVariableType)?.psiType } + override fun toString() = parameter.name ?: "" + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt index 0871062ee63..d3d7245811f 100644 --- a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt @@ -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") + check("e", "(java.lang.Object)java.lang.Object", erasure) + check("f", "(java.util.List>,int)void") + check("f", "(java.util.List,int)void", erasure) + check("g", "(D)void") + check("g", "(java.lang.String)void", erasure) + } } \ No newline at end of file