Kapt3: Use annotation simple name if the annotation declaration is inside the same package as the current source file's package

This commit is contained in:
Yan Zhulanow
2016-11-01 22:13:09 +03:00
committed by Yan Zhulanow
parent 1f1491f1ca
commit 90cbf172d2
4 changed files with 107 additions and 26 deletions
@@ -85,12 +85,12 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
// Nested classes will be processed during the outer classes conversion // Nested classes will be processed during the outer classes conversion
if ((descriptor as? ClassDescriptor)?.isNested ?: false) return null if ((descriptor as? ClassDescriptor)?.isNested ?: false) return null
val classDeclaration = convertClass(clazz) ?: return null
val packageAnnotations = JavacList.nil<JCAnnotation>() val packageAnnotations = JavacList.nil<JCAnnotation>()
val packageName = ktFile.packageFqName.asString() val packageName = ktFile.packageFqName.asString()
val packageClause = if (packageName.isEmpty()) null else treeMaker.FqName(packageName) val packageClause = if (packageName.isEmpty()) null else treeMaker.FqName(packageName)
val classDeclaration = convertClass(clazz, packageName, true) ?: return null
val imports = JavacList.nil<JCTree>() val imports = JavacList.nil<JCTree>()
val classes = JavacList.of<JCTree>(classDeclaration) val classes = JavacList.of<JCTree>(classDeclaration)
@@ -103,7 +103,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
/** /**
* Returns false for the inner classes or if the origin for the class was not found. * Returns false for the inner classes or if the origin for the class was not found.
*/ */
private fun convertClass(clazz: ClassNode): JCClassDecl? { private fun convertClass(clazz: ClassNode, packageFqName: String, isTopLevel: Boolean): JCClassDecl? {
if (isSynthetic(clazz.access)) return null if (isSynthetic(clazz.access)) return null
val descriptor = kaptContext.origins[clazz]?.descriptor as? DeclarationDescriptor ?: return null val descriptor = kaptContext.origins[clazz]?.descriptor as? DeclarationDescriptor ?: return null
@@ -112,7 +112,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
val modifiers = convertModifiers( val modifiers = convertModifiers(
if (!isInner && isNested) (clazz.access or Opcodes.ACC_STATIC) else clazz.access, if (!isInner && isNested) (clazz.access or Opcodes.ACC_STATIC) else clazz.access,
ElementKind.CLASS, clazz.visibleAnnotations, clazz.invisibleAnnotations) ElementKind.CLASS, packageFqName, clazz.visibleAnnotations, clazz.invisibleAnnotations)
val isEnum = clazz.isEnum() val isEnum = clazz.isEnum()
val isAnnotation = clazz.isAnnotation() val isAnnotation = clazz.isAnnotation()
@@ -123,7 +123,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
&& descriptor.kind == ClassKind.INTERFACE && descriptor.kind == ClassKind.INTERFACE
// DefaultImpls without any contents don't have INNERCLASS'es inside it (and inside the parent interface) // DefaultImpls without any contents don't have INNERCLASS'es inside it (and inside the parent interface)
if (isDefaultImpls && clazz.fields.isNullOrEmpty() && clazz.methods.isNullOrEmpty()) { if (isDefaultImpls && (isTopLevel || (clazz.fields.isNullOrEmpty() && clazz.methods.isNullOrEmpty()))) {
return null return null
} }
@@ -139,19 +139,19 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
val hasSuperClass = clazz.superName != "java/lang/Object" && !isEnum val hasSuperClass = clazz.superName != "java/lang/Object" && !isEnum
val genericType = signatureParser.parseClassSignature(clazz.signature, superClass, interfaces) val genericType = signatureParser.parseClassSignature(clazz.signature, superClass, interfaces)
val fields = mapJList<FieldNode, JCTree>(clazz.fields) { convertField(it) } val fields = mapJList<FieldNode, JCTree>(clazz.fields) { convertField(it, packageFqName) }
val methods = mapJList<MethodNode, JCTree>(clazz.methods) { val methods = mapJList<MethodNode, JCTree>(clazz.methods) {
if (isEnum) { if (isEnum) {
if (it.name == "values" && it.desc == "()[L${clazz.name};") return@mapJList null if (it.name == "values" && it.desc == "()[L${clazz.name};") return@mapJList null
if (it.name == "valueOf" && it.desc == "(Ljava/lang/String;)L${clazz.name};") return@mapJList null if (it.name == "valueOf" && it.desc == "(Ljava/lang/String;)L${clazz.name};") return@mapJList null
} }
convertMethod(it, clazz) convertMethod(it, clazz, packageFqName)
} }
val nestedClasses = mapJList<InnerClassNode, JCTree>(clazz.innerClasses) { innerClass -> val nestedClasses = mapJList<InnerClassNode, JCTree>(clazz.innerClasses) { innerClass ->
if (innerClass.outerName != clazz.name) return@mapJList null if (innerClass.outerName != clazz.name) return@mapJList null
val innerClassNode = kaptContext.compiledClasses.firstOrNull { it.name == innerClass.name } ?: return@mapJList null val innerClassNode = kaptContext.compiledClasses.firstOrNull { it.name == innerClass.name } ?: return@mapJList null
convertClass(innerClassNode) convertClass(innerClassNode, packageFqName, false)
} }
return treeMaker.ClassDef( return treeMaker.ClassDef(
@@ -163,10 +163,10 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
fields + methods + nestedClasses) fields + methods + nestedClasses)
} }
private fun convertField(field: FieldNode): JCVariableDecl? { private fun convertField(field: FieldNode, packageFqName: String): JCVariableDecl? {
if (isSynthetic(field.access)) return null if (isSynthetic(field.access)) return null
val modifiers = convertModifiers(field.access, ElementKind.FIELD, field.visibleAnnotations, field.invisibleAnnotations) val modifiers = convertModifiers(field.access, ElementKind.FIELD, packageFqName, field.visibleAnnotations, field.invisibleAnnotations)
val name = treeMaker.name(field.name) val name = treeMaker.name(field.name)
val type = Type.getType(field.desc) val type = Type.getType(field.desc)
@@ -188,7 +188,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
return treeMaker.VarDef(modifiers, name, typeExpression, initializer) return treeMaker.VarDef(modifiers, name, typeExpression, initializer)
} }
private fun convertMethod(method: MethodNode, containingClass: ClassNode): JCMethodDecl? { private fun convertMethod(method: MethodNode, containingClass: ClassNode, packageFqName: String): JCMethodDecl? {
if (isSynthetic(method.access)) return null if (isSynthetic(method.access)) return null
val descriptor = kaptContext.origins[method]?.descriptor as? CallableDescriptor ?: return null val descriptor = kaptContext.origins[method]?.descriptor as? CallableDescriptor ?: return null
@@ -207,7 +207,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
(method.access.toLong() and VISIBILITY_MODIFIERS.inv()) (method.access.toLong() and VISIBILITY_MODIFIERS.inv())
else else
method.access.toLong(), method.access.toLong(),
ElementKind.METHOD, visibleAnnotations, method.invisibleAnnotations) ElementKind.METHOD, packageFqName, visibleAnnotations, method.invisibleAnnotations)
val returnType = Type.getReturnType(method.desc) val returnType = Type.getReturnType(method.desc)
val jcReturnType = if (isConstructor) null else treeMaker.Type(returnType) val jcReturnType = if (isConstructor) null else treeMaker.Type(returnType)
@@ -222,6 +222,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
val modifiers = convertModifiers( val modifiers = convertModifiers(
info.flags or varargs or Flags.PARAMETER, info.flags or varargs or Flags.PARAMETER,
ElementKind.PARAMETER, ElementKind.PARAMETER,
packageFqName,
info.visibleAnnotations, info.visibleAnnotations,
info.invisibleAnnotations) info.invisibleAnnotations)
@@ -276,21 +277,23 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
private inline fun convertModifiers( private inline fun convertModifiers(
access: Int, access: Int,
kind: ElementKind, kind: ElementKind,
packageFqName: String,
visibleAnnotations: List<AnnotationNode>?, visibleAnnotations: List<AnnotationNode>?,
invisibleAnnotations: List<AnnotationNode>? invisibleAnnotations: List<AnnotationNode>?
): JCModifiers = convertModifiers(access.toLong(), kind, visibleAnnotations, invisibleAnnotations) ): JCModifiers = convertModifiers(access.toLong(), kind, packageFqName, visibleAnnotations, invisibleAnnotations)
private fun convertModifiers( private fun convertModifiers(
access: Long, access: Long,
kind: ElementKind, kind: ElementKind,
packageFqName: String,
visibleAnnotations: List<AnnotationNode>?, visibleAnnotations: List<AnnotationNode>?,
invisibleAnnotations: List<AnnotationNode>? invisibleAnnotations: List<AnnotationNode>?
): JCModifiers { ): JCModifiers {
var annotations = visibleAnnotations?.fold(JavacList.nil<JCAnnotation>()) { list, anno -> var annotations = visibleAnnotations?.fold(JavacList.nil<JCAnnotation>()) { list, anno ->
convertAnnotation(anno)?.let { list.prepend(it) } ?: list convertAnnotation(anno, packageFqName)?.let { list.prepend(it) } ?: list
} ?: JavacList.nil() } ?: JavacList.nil()
annotations = invisibleAnnotations?.fold(annotations) { list, anno -> annotations = invisibleAnnotations?.fold(annotations) { list, anno ->
convertAnnotation(anno)?.let { list.prepend(it) } ?: list convertAnnotation(anno, packageFqName)?.let { list.prepend(it) } ?: list
} ?: annotations } ?: annotations
val flags = when (kind) { val flags = when (kind) {
@@ -303,7 +306,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
return treeMaker.Modifiers(flags, annotations) return treeMaker.Modifiers(flags, annotations)
} }
private fun convertAnnotation(annotation: AnnotationNode, filtered: Boolean = true): JCAnnotation? { private fun convertAnnotation(annotation: AnnotationNode, packageFqName: String? = "", filtered: Boolean = true): JCAnnotation? {
val annotationType = Type.getType(annotation.desc) val annotationType = Type.getType(annotation.desc)
val fqName = annotationType.className val fqName = annotationType.className
@@ -311,7 +314,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
if (BLACKLISTED_ANNOTATIONS.any { fqName.startsWith(it) }) return null if (BLACKLISTED_ANNOTATIONS.any { fqName.startsWith(it) }) return null
} }
val name = treeMaker.Type(annotationType) val useSimpleName = '.' in fqName && fqName.substringBeforeLast('.', "") == packageFqName
val name = if (useSimpleName) treeMaker.FqName(fqName.substring(packageFqName!!.length + 1)) else treeMaker.Type(annotationType)
val values = mapPairedValuesJList<JCExpression>(annotation.values) { key, value -> val values = mapPairedValuesJList<JCExpression>(annotation.values) { key, value ->
treeMaker.Assign(treeMaker.SimpleName(key), convertLiteralExpression(value)) treeMaker.Assign(treeMaker.SimpleName(key), convertLiteralExpression(value))
} }
@@ -341,7 +345,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value) { convertLiteralExpression(it) }) is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value) { convertLiteralExpression(it) })
is Type -> treeMaker.Select(treeMaker.Type(value), treeMaker.name("class")) is Type -> treeMaker.Select(treeMaker.Type(value), treeMaker.name("class"))
is AnnotationNode -> convertAnnotation(value, false)!! is AnnotationNode -> convertAnnotation(value, packageFqName = null, filtered = false)!!
else -> throw IllegalArgumentException("Illegal literal expression value: $value (${value.javaClass.canonicalName})") else -> throw IllegalArgumentException("Illegal literal expression value: $value (${value.javaClass.canonicalName})")
} }
} }
+1 -2
View File
@@ -3,8 +3,7 @@ package test
@Anno("anno-class") @Anno("anno-class")
annotation class Anno @Anno("anno-constructor") constructor( annotation class Anno @Anno("anno-constructor") constructor(
@Anno("anno-value") val value: String, @Anno("anno-value") val value: String
val anno: Anno = Anno("anno-default")
) )
@Anno("clazz") @Anno("clazz")
+78
View File
@@ -0,0 +1,78 @@
package test;
@Anno(value = "anno-class")
public abstract @interface Anno {
public abstract java.lang.String value();
}
////////////////////
package test;
@Anno(value = "clazz")
public abstract class Test {
private java.lang.String v;
@Anno(value = "abstract-method")
public abstract java.lang.String abstractMethod();
public abstract java.lang.String getAbstractVal();
@Anno(value = "v-get")
public final java.lang.String getV() {
return null;
}
@Anno(value = "v-set")
public final void setV(@Anno(value = "v-setparam")
java.lang.String p0) {
}
@Anno(value = "test-constructor")
protected Test(@Anno(value = "v-param")
java.lang.String v) {
super();
}
}
////////////////////
package test;
@Anno(value = "enum")
public enum Enum {
/*public static final*/ WHITE /* = null */,
/*public static final*/ BLACK /* = null */;
private final int x = 0;
public final int getX() {
return 0;
}
@Anno(value = "enum-constructor")
Enum(@Anno(value = "x")
int x) {
}
}
////////////////////
package test;
public final class test {
public test() {
super();
}
@Anno(value = "top-level-fun")
public static final void topLevelFun(@Anno(value = "top-level-fun-receiver")
java.lang.String $receiver) {
}
public static final java.lang.String getTopLevelVal(@Anno(value = "top-level-val-receiver")
int $receiver) {
return null;
}
}
+6 -6
View File
@@ -32,19 +32,19 @@ public final class another {
return null; return null;
} }
public static final void extensionFunction(@test.another.Anno(value = "rec") public static final void extensionFunction(@Anno(value = "rec")
java.lang.String $receiver, @test.another.Anno(value = "1") java.lang.String $receiver, @Anno(value = "1")
java.lang.String a, @test.another.Anno(value = "2") java.lang.String a, @Anno(value = "2")
java.lang.String b) { java.lang.String b) {
} }
public static final <T extends java.lang.Object>java.lang.String getExtensionProperty(@test.another.Anno(value = "propRec") public static final <T extends java.lang.Object>java.lang.String getExtensionProperty(@Anno(value = "propRec")
T $receiver) { T $receiver) {
return null; return null;
} }
public static final <T extends java.lang.Object>void setExtensionProperty(@test.another.Anno(value = "propRec") public static final <T extends java.lang.Object>void setExtensionProperty(@Anno(value = "propRec")
T $receiver, @test.another.Anno(value = "setparam") T $receiver, @Anno(value = "setparam")
java.lang.String setParamName) { java.lang.String setParamName) {
} }
} }