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 @NotNull
private static Variance getVarianceForWildcard( public static Variance getVarianceForWildcard(
@NotNull TypeParameterDescriptor parameter, @NotNull TypeParameterDescriptor parameter,
@NotNull TypeProjection projection, @NotNull TypeProjection projection,
@NotNull TypeMappingMode mode @NotNull TypeMappingMode mode
@@ -75,7 +75,7 @@ private val METHODS_WITH_DECLARATION_SITE_WILDCARDS = setOf(
BUILTIN_NAMES.mutableMap.child("putAll") BUILTIN_NAMES.mutableMap.child("putAll")
) )
internal fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode { fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode {
type.suppressWildcardsMode()?.let { type.suppressWildcardsMode()?.let {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode( return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it, isForAnnotationParameter = isForAnnotationParameter) 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.code.BoundKind
import com.sun.tools.javac.tree.JCTree import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter 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.mapJList
import org.jetbrains.kotlin.kapt3.mapJListIndexed
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
internal fun convertKtType( internal fun convertKtType(
reference: KtTypeReference?, reference: KtTypeReference?,
@@ -46,7 +51,7 @@ internal fun convertKtType(
} }
return when (type) { return when (type) {
is KtUserType -> convertUserType(type, converter) is KtUserType -> convertUserType(type, converter, reference)
is KtNullableType -> { is KtNullableType -> {
// Prevent infinite recursion // Prevent infinite recursion
val innerType = type.innerType ?: return getDefaultTypeForUnknownType(converter) 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 getDefaultTypeForUnknownType(converter: ClassFileToSourceStubConverter) = converter.treeMaker.FqName("error.NonExistentClass")
private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubConverter): JCTree.JCExpression { private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubConverter, reference: KtTypeReference?): JCTree.JCExpression {
val qualifierExpression = type.qualifier?.let { convertUserType(it, converter) } val qualifierExpression = type.qualifier?.let { convertUserType(it, converter, null) }
val referencedName = type.referencedName ?: "error" val referencedName = type.referencedName ?: "error"
val treeMaker = converter.treeMaker val treeMaker = converter.treeMaker
val baseExpression = if (qualifierExpression == null) { 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 { } else {
treeMaker.Select(qualifierExpression, treeMaker.name(referencedName)) treeMaker.Select(qualifierExpression, treeMaker.name(referencedName))
} }
@@ -75,20 +87,41 @@ private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubCo
return baseExpression 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 reference = type.typeReference
val treeMaker = converter.treeMaker val treeMaker = converter.treeMaker
val projectionKind = type.projectionKind
return when (type.projectionKind) { if (variance === Variance.INVARIANT) {
KtProjectionKind.IN -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.SUPER), return convertKtType(reference, converter, shouldBeBoxed = true)
convertKtType(reference, converter, shouldBeBoxed = true)) }
KtProjectionKind.OUT -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.EXTENDS),
convertKtType(reference, converter, shouldBeBoxed = true)) return when {
KtProjectionKind.STAR -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.UNBOUND), null) projectionKind === KtProjectionKind.STAR -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.UNBOUND), null)
KtProjectionKind.NONE -> return convertKtType(reference, converter, shouldBeBoxed = true) 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"}) @kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
public final class NonExistentType { public final class NonExistentType {
private static final ABCDEF a = null; 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 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 static final NonExistentType INSTANCE = null;
public final ABCDEF getA() { public final ABCDEF getA() {
return null; return null;
} }
public final List<ABCDEF> getB() { public final java.util.List<ABCDEF> getB() {
return null; return null;
} }
@@ -18,7 +18,7 @@ public final class NonExistentType {
return null; 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; return null;
} }
@@ -1,6 +1,8 @@
// NON_EXISTENT_CLASS // NON_EXISTENT_CLASS
// NO_VALIDATION // NO_VALIDATION
import java.util.Calendar
@Suppress("UNRESOLVED_REFERENCE") @Suppress("UNRESOLVED_REFERENCE")
class Test { class Test {
lateinit var a: ABC 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 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 o10: List<List<List<List<List<List<List<List<List<ABC>>>>>>>>>
lateinit var p: Calendar.Builder
fun f1(a: ABC): BCD? { fun f1(a: ABC): BCD? {
return null return null
} }
@@ -12,20 +12,21 @@ public final class MyType<T extends java.lang.Object> {
public final class Test { public final class Test {
public ABC a; public ABC a;
private final ABC b = null; private final ABC b = null;
private final List<ABC> c = null; private final java.util.List<ABC> c = null;
private final List<Map<BCD, ABC<List<BCD>>>> d = null; private final java.util.List<java.util.Map<BCD, ABC<? extends java.util.List<BCD>>>> d = null;
public List<? extends Map<? extends ABC, ? extends BCD>> e; public java.util.List<? extends java.util.Map<? extends ABC, ? extends BCD>> e;
public ABC<?> f; public ABC<?> f;
public java.util.List<?> g; public java.util.List<?> g;
public ABC<java.lang.Integer, java.lang.String> h; 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 Function0<CDE> j;
public Function2<ABC, List<BCD>, CDE> k; public Function2<ABC, java.util.List<BCD>, CDE> k;
public ABC.BCD.EFG l; public ABC.BCD.EFG l;
private final error.NonExistentClass m = null; private final error.NonExistentClass m = null;
private final java.lang.String n = ""; 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 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() { public final ABC getA() {
return null; return null;
@@ -38,19 +39,19 @@ public final class Test {
return null; return null;
} }
public final List<ABC> getC() { public final java.util.List<ABC> getC() {
return null; 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; 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; 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() { 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 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; 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() { public final Function0<CDE> getJ() {
@@ -88,11 +89,11 @@ public final class Test {
public final void setJ(Function0<CDE> p0) { 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; 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() { 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 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; 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) { public final BCD f1(ABC a) {