Kapt: Fix array of anonymous type handling (KT-22468)

This commit is contained in:
Yan Zhulanow
2018-01-23 23:35:46 +03:00
parent 144ec9285f
commit 4e8969e1c2
3 changed files with 67 additions and 2 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.kapt3.stubs
import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.resolve.DescriptorUtils.isAnonymousObject
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.builtIns
class AnonymousTypeHandler(private val converter: ClassFileToSourceStubConverter) {
fun <T : JCTree.JCExpression?> getNonAnonymousType(descriptor: DeclarationDescriptor?, f: () -> T): T {
@@ -62,6 +64,16 @@ class AnonymousTypeHandler(private val converter: ClassFileToSourceStubConverter
private fun convertPossiblyAnonymousType(type: KotlinType): KotlinType {
val declaration = type.constructor.declarationDescriptor as? ClassDescriptor ?: return type
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.singleOrNull()
if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
return type.builtIns.getArrayType(
elementTypeProjection.projectionKind,
convertPossiblyAnonymousType(elementTypeProjection.type)
)
}
}
val actualType = when {
isAnonymousObject(declaration) -> findMostSuitableParentForAnonymousType(declaration)
else -> type
@@ -91,9 +103,22 @@ class AnonymousTypeHandler(private val converter: ClassFileToSourceStubConverter
}
private fun convertKotlinType(type: KotlinType): JCTree.JCExpression {
val treeMaker = converter.treeMaker
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.single()
val elementType = if (elementTypeProjection.isStarProjection || elementTypeProjection.projectionKind == Variance.IN_VARIANCE) {
type.builtIns.anyType
} else {
elementTypeProjection.type
}
return treeMaker.TypeArray(convertKotlinType(elementType))
}
val typeMapper = converter.kaptContext.generationState.typeMapper
val treeMaker = converter.treeMaker
// Primitive types can't be anonymous, so if we get here, we want to map a class type or its generic argument
val selfType = treeMaker.Type(typeMapper.mapType(type, null, TypeMappingMode.GENERIC_ARGUMENT))
if (type.arguments.isEmpty()) return selfType
+15 -1
View File
@@ -1,3 +1,4 @@
// WITH_RUNTIME
@file:Suppress("AMBIGUOUS_ANONYMOUS_TYPE_INFERRED")
open class CrashMe {
@@ -18,4 +19,17 @@ fun b() = object : java.io.Serializable, Runnable {
fun c() = object : CrashMe(), Runnable {
override fun run() {}
}
}
fun d() = listOf(object : Runnable {
override fun run() {}
})
fun e() = arrayOf(object : Runnable {
override fun run() {}
})
fun e1(a: Array<CharSequence>) {}
fun e2(a: Array<in CharSequence>) {}
fun e3(a: Array<out CharSequence>) {}
fun e3(a: Array<*>) {}
@@ -36,4 +36,30 @@ public final class Kt14997Kt {
public static final CrashMe c() {
return null;
}
@org.jetbrains.annotations.NotNull()
public static final java.util.List<java.lang.Runnable> d() {
return null;
}
@org.jetbrains.annotations.NotNull()
public static final java.lang.Runnable[] e() {
return null;
}
public static final void e1(@org.jetbrains.annotations.NotNull()
java.lang.CharSequence[] a) {
}
public static final void e2(@org.jetbrains.annotations.NotNull()
java.lang.Object[] a) {
}
public static final void e3(@org.jetbrains.annotations.NotNull()
java.lang.CharSequence[] a) {
}
public static final void e3(@org.jetbrains.annotations.NotNull()
java.lang.Object[] a) {
}
}