Kapt3: Write qualified name of classes on error type conversion, handle declaration-site variance properly.

This commit is contained in:
Yan Zhulanow
2017-01-22 00:07:06 +09:00
parent 72bbf9697b
commit 3b4a8e0f33
6 changed files with 80 additions and 35 deletions
@@ -634,7 +634,7 @@ public class KotlinTypeMapper {
}
@NotNull
private static Variance getVarianceForWildcard(
public static Variance getVarianceForWildcard(
@NotNull TypeParameterDescriptor parameter,
@NotNull TypeProjection projection,
@NotNull TypeMappingMode mode
@@ -75,7 +75,7 @@ private val METHODS_WITH_DECLARATION_SITE_WILDCARDS = setOf(
BUILTIN_NAMES.mutableMap.child("putAll")
)
internal fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode {
fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode {
type.suppressWildcardsMode()?.let {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it, isForAnnotationParameter = isForAnnotationParameter)
@@ -19,11 +19,16 @@ package org.jetbrains.kotlin.kapt3.stubs
import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.state.updateArgumentModeFromAnnotations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.kapt3.mapJList
import org.jetbrains.kotlin.kapt3.mapJListIndexed
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
internal fun convertKtType(
reference: KtTypeReference?,
@@ -46,7 +51,7 @@ internal fun convertKtType(
}
return when (type) {
is KtUserType -> convertUserType(type, converter)
is KtUserType -> convertUserType(type, converter, reference)
is KtNullableType -> {
// Prevent infinite recursion
val innerType = type.innerType ?: return getDefaultTypeForUnknownType(converter)
@@ -59,13 +64,20 @@ internal fun convertKtType(
private fun getDefaultTypeForUnknownType(converter: ClassFileToSourceStubConverter) = converter.treeMaker.FqName("error.NonExistentClass")
private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubConverter): JCTree.JCExpression {
val qualifierExpression = type.qualifier?.let { convertUserType(it, converter) }
private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubConverter, reference: KtTypeReference?): JCTree.JCExpression {
val qualifierExpression = type.qualifier?.let { convertUserType(it, converter, null) }
val referencedName = type.referencedName ?: "error"
val treeMaker = converter.treeMaker
val baseExpression = if (qualifierExpression == null) {
treeMaker.SimpleName(referencedName)
// This could be List<SomeErrorType> or similar. List should be converted to java.util.List in this case.
val referenceTarget = converter.kaptContext.bindingContext[BindingContext.REFERENCE_TARGET, type.referenceExpression]
if (referenceTarget is ClassDescriptor) {
treeMaker.FqName(converter.typeMapper.mapType(referenceTarget.defaultType).className)
}
else {
treeMaker.SimpleName(referencedName)
}
} else {
treeMaker.Select(qualifierExpression, treeMaker.name(referencedName))
}
@@ -75,20 +87,41 @@ private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubCo
return baseExpression
}
return treeMaker.TypeApply(baseExpression, mapJList(arguments) { convertTypeProjection(it, converter) })
val baseType = reference?.let { converter.kaptContext.bindingContext[BindingContext.TYPE, it] }
return treeMaker.TypeApply(baseExpression, mapJListIndexed(arguments) { index, projection ->
val argumentType = projection.typeReference?.let { converter.kaptContext.bindingContext[BindingContext.TYPE, it] }
val typeParameter = argumentType?.constructor?.parameters?.getOrNull(index)
val argument = baseType?.arguments?.getOrNull(index)
val variance = if (argument != null && typeParameter != null) {
val argumentMode = TypeMappingMode.GENERIC_ARGUMENT.updateArgumentModeFromAnnotations(argument.type)
KotlinTypeMapper.getVarianceForWildcard(typeParameter, argument, argumentMode)
}
else {
null
}
convertTypeProjection(projection, variance, converter)
})
}
private fun convertTypeProjection(type: KtTypeProjection, converter: ClassFileToSourceStubConverter): JCTree.JCExpression {
private fun convertTypeProjection(type: KtTypeProjection, variance: Variance?, converter: ClassFileToSourceStubConverter): JCTree.JCExpression {
val reference = type.typeReference
val treeMaker = converter.treeMaker
val projectionKind = type.projectionKind
return when (type.projectionKind) {
KtProjectionKind.IN -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.SUPER),
convertKtType(reference, converter, shouldBeBoxed = true))
KtProjectionKind.OUT -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.EXTENDS),
convertKtType(reference, converter, shouldBeBoxed = true))
KtProjectionKind.STAR -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.UNBOUND), null)
KtProjectionKind.NONE -> return convertKtType(reference, converter, shouldBeBoxed = true)
if (variance === Variance.INVARIANT) {
return convertKtType(reference, converter, shouldBeBoxed = true)
}
return when {
projectionKind === KtProjectionKind.STAR -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.UNBOUND), null)
projectionKind === KtProjectionKind.IN || variance === Variance.IN_VARIANCE ->
treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.SUPER), convertKtType(reference, converter, shouldBeBoxed = true))
projectionKind === KtProjectionKind.OUT || variance === Variance.OUT_VARIANCE ->
treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.EXTENDS), convertKtType(reference, converter, shouldBeBoxed = true))
else -> convertKtType(reference, converter, shouldBeBoxed = true) // invariant
}
}
+4 -4
View File
@@ -1,16 +1,16 @@
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
public final class NonExistentType {
private static final ABCDEF a = null;
private static final List<ABCDEF> b = null;
private static final java.util.List<ABCDEF> b = null;
private static final Function1<ABCDEF, kotlin.Unit> c = null;
private static final ABCDEF<java.lang.String, Function1<List<ABCDEF>, kotlin.Unit>> d = null;
private static final ABCDEF<java.lang.String, ? extends Function1<java.util.List<ABCDEF>, kotlin.Unit>> d = null;
public static final NonExistentType INSTANCE = null;
public final ABCDEF getA() {
return null;
}
public final List<ABCDEF> getB() {
public final java.util.List<ABCDEF> getB() {
return null;
}
@@ -18,7 +18,7 @@ public final class NonExistentType {
return null;
}
public final ABCDEF<java.lang.String, Function1<List<ABCDEF>, kotlin.Unit>> getD() {
public final ABCDEF<java.lang.String, ? extends Function1<java.util.List<ABCDEF>, kotlin.Unit>> getD() {
return null;
}
@@ -1,6 +1,8 @@
// NON_EXISTENT_CLASS
// NO_VALIDATION
import java.util.Calendar
@Suppress("UNRESOLVED_REFERENCE")
class Test {
lateinit var a: ABC
@@ -23,6 +25,8 @@ class Test {
lateinit var o11: List<List<List<List<List<List<List<List<List<List<ABC>>>>>>>>>>
lateinit var o10: List<List<List<List<List<List<List<List<List<ABC>>>>>>>>>
lateinit var p: Calendar.Builder
fun f1(a: ABC): BCD? {
return null
}
@@ -12,20 +12,21 @@ public final class MyType<T extends java.lang.Object> {
public final class Test {
public ABC a;
private final ABC b = null;
private final List<ABC> c = null;
private final List<Map<BCD, ABC<List<BCD>>>> d = null;
public List<? extends Map<? extends ABC, ? extends BCD>> e;
private final java.util.List<ABC> c = null;
private final java.util.List<java.util.Map<BCD, ABC<? extends java.util.List<BCD>>>> d = null;
public java.util.List<? extends java.util.Map<? extends ABC, ? extends BCD>> e;
public ABC<?> f;
public java.util.List<?> g;
public ABC<java.lang.Integer, java.lang.String> h;
public Function2<ABC, List<BCD>, CDE> i;
public Function2<ABC, java.util.List<BCD>, CDE> i;
public Function0<CDE> j;
public Function2<ABC, List<BCD>, CDE> k;
public Function2<ABC, java.util.List<BCD>, CDE> k;
public ABC.BCD.EFG l;
private final error.NonExistentClass m = null;
private final java.lang.String n = "";
public java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends error.NonExistentClass>>>>>>>>>> o11;
public List<List<List<List<List<List<List<List<List<ABC>>>>>>>>> o10;
public java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<ABC>>>>>>>>> o10;
public java.util.Calendar.Builder p;
public final ABC getA() {
return null;
@@ -38,19 +39,19 @@ public final class Test {
return null;
}
public final List<ABC> getC() {
public final java.util.List<ABC> getC() {
return null;
}
public final List<Map<BCD, ABC<List<BCD>>>> getD() {
public final java.util.List<java.util.Map<BCD, ABC<? extends java.util.List<BCD>>>> getD() {
return null;
}
public final List<? extends Map<? extends ABC, ? extends BCD>> getE() {
public final java.util.List<? extends java.util.Map<? extends ABC, ? extends BCD>> getE() {
return null;
}
public final void setE(List<? extends Map<? extends ABC, ? extends BCD>> p0) {
public final void setE(java.util.List<? extends java.util.Map<? extends ABC, ? extends BCD>> p0) {
}
public final ABC<?> getF() {
@@ -74,11 +75,11 @@ public final class Test {
public final void setH(ABC<java.lang.Integer, java.lang.String> p0) {
}
public final Function2<ABC, List<BCD>, CDE> getI() {
public final Function2<ABC, java.util.List<BCD>, CDE> getI() {
return null;
}
public final void setI(Function2<ABC, List<BCD>, CDE> p0) {
public final void setI(Function2<ABC, java.util.List<BCD>, CDE> p0) {
}
public final Function0<CDE> getJ() {
@@ -88,11 +89,11 @@ public final class Test {
public final void setJ(Function0<CDE> p0) {
}
public final Function2<ABC, List<BCD>, CDE> getK() {
public final Function2<ABC, java.util.List<BCD>, CDE> getK() {
return null;
}
public final void setK(Function2<ABC, List<BCD>, CDE> p0) {
public final void setK(Function2<ABC, java.util.List<BCD>, CDE> p0) {
}
public final ABC.BCD.EFG getL() {
@@ -117,11 +118,18 @@ public final class Test {
public final void setO11(java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends error.NonExistentClass>>>>>>>>>> p0) {
}
public final List<List<List<List<List<List<List<List<List<ABC>>>>>>>>> getO10() {
public final java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<ABC>>>>>>>>> getO10() {
return null;
}
public final void setO10(List<List<List<List<List<List<List<List<List<ABC>>>>>>>>> p0) {
public final void setO10(java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<? extends java.util.List<ABC>>>>>>>>> p0) {
}
public final java.util.Calendar.Builder getP() {
return null;
}
public final void setP(java.util.Calendar.Builder p0) {
}
public final BCD f1(ABC a) {