From 90cbf172d273f7a3b73e680d6dd5611e4cfb1c26 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 1 Nov 2016 22:13:09 +0300 Subject: [PATCH] Kapt3: Use annotation simple name if the annotation declaration is inside the same package as the current source file's package --- .../stubs/ClassFileToSourceStubConverter.kt | 40 +++++----- .../kapt3/testData/converter/annotations2.kt | 3 +- .../kapt3/testData/converter/annotations2.txt | 78 +++++++++++++++++++ plugins/kapt3/testData/converter/topLevel.txt | 12 +-- 4 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 plugins/kapt3/testData/converter/annotations2.txt diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index 315900de718..b618c8c319a 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -85,12 +85,12 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe // Nested classes will be processed during the outer classes conversion if ((descriptor as? ClassDescriptor)?.isNested ?: false) return null - val classDeclaration = convertClass(clazz) ?: return null - val packageAnnotations = JavacList.nil() val packageName = ktFile.packageFqName.asString() val packageClause = if (packageName.isEmpty()) null else treeMaker.FqName(packageName) + val classDeclaration = convertClass(clazz, packageName, true) ?: return null + val imports = JavacList.nil() val classes = JavacList.of(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. */ - private fun convertClass(clazz: ClassNode): JCClassDecl? { + private fun convertClass(clazz: ClassNode, packageFqName: String, isTopLevel: Boolean): JCClassDecl? { if (isSynthetic(clazz.access)) 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( 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 isAnnotation = clazz.isAnnotation() @@ -123,7 +123,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe && descriptor.kind == ClassKind.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 } @@ -139,19 +139,19 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe val hasSuperClass = clazz.superName != "java/lang/Object" && !isEnum val genericType = signatureParser.parseClassSignature(clazz.signature, superClass, interfaces) - val fields = mapJList(clazz.fields) { convertField(it) } + val fields = mapJList(clazz.fields) { convertField(it, packageFqName) } val methods = mapJList(clazz.methods) { if (isEnum) { 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 } - convertMethod(it, clazz) + convertMethod(it, clazz, packageFqName) } val nestedClasses = mapJList(clazz.innerClasses) { innerClass -> if (innerClass.outerName != clazz.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( @@ -163,10 +163,10 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe fields + methods + nestedClasses) } - private fun convertField(field: FieldNode): JCVariableDecl? { + private fun convertField(field: FieldNode, packageFqName: String): JCVariableDecl? { 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 type = Type.getType(field.desc) @@ -188,7 +188,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe 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 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()) else method.access.toLong(), - ElementKind.METHOD, visibleAnnotations, method.invisibleAnnotations) + ElementKind.METHOD, packageFqName, visibleAnnotations, method.invisibleAnnotations) val returnType = Type.getReturnType(method.desc) val jcReturnType = if (isConstructor) null else treeMaker.Type(returnType) @@ -222,6 +222,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe val modifiers = convertModifiers( info.flags or varargs or Flags.PARAMETER, ElementKind.PARAMETER, + packageFqName, info.visibleAnnotations, info.invisibleAnnotations) @@ -276,21 +277,23 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe private inline fun convertModifiers( access: Int, kind: ElementKind, + packageFqName: String, visibleAnnotations: List?, invisibleAnnotations: List? - ): JCModifiers = convertModifiers(access.toLong(), kind, visibleAnnotations, invisibleAnnotations) + ): JCModifiers = convertModifiers(access.toLong(), kind, packageFqName, visibleAnnotations, invisibleAnnotations) private fun convertModifiers( access: Long, kind: ElementKind, + packageFqName: String, visibleAnnotations: List?, invisibleAnnotations: List? ): JCModifiers { var annotations = visibleAnnotations?.fold(JavacList.nil()) { list, anno -> - convertAnnotation(anno)?.let { list.prepend(it) } ?: list + convertAnnotation(anno, packageFqName)?.let { list.prepend(it) } ?: list } ?: JavacList.nil() annotations = invisibleAnnotations?.fold(annotations) { list, anno -> - convertAnnotation(anno)?.let { list.prepend(it) } ?: list + convertAnnotation(anno, packageFqName)?.let { list.prepend(it) } ?: list } ?: annotations val flags = when (kind) { @@ -303,7 +306,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe 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 fqName = annotationType.className @@ -311,7 +314,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe 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(annotation.values) { key, 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 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})") } } diff --git a/plugins/kapt3/testData/converter/annotations2.kt b/plugins/kapt3/testData/converter/annotations2.kt index 2d65d65529f..f2024f84ae5 100644 --- a/plugins/kapt3/testData/converter/annotations2.kt +++ b/plugins/kapt3/testData/converter/annotations2.kt @@ -3,8 +3,7 @@ package test @Anno("anno-class") annotation class Anno @Anno("anno-constructor") constructor( - @Anno("anno-value") val value: String, - val anno: Anno = Anno("anno-default") + @Anno("anno-value") val value: String ) @Anno("clazz") diff --git a/plugins/kapt3/testData/converter/annotations2.txt b/plugins/kapt3/testData/converter/annotations2.txt new file mode 100644 index 00000000000..37070deab7d --- /dev/null +++ b/plugins/kapt3/testData/converter/annotations2.txt @@ -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; + } +} diff --git a/plugins/kapt3/testData/converter/topLevel.txt b/plugins/kapt3/testData/converter/topLevel.txt index b913a60ccfa..480bf83740c 100644 --- a/plugins/kapt3/testData/converter/topLevel.txt +++ b/plugins/kapt3/testData/converter/topLevel.txt @@ -32,19 +32,19 @@ public final class another { return null; } - public static final void extensionFunction(@test.another.Anno(value = "rec") - java.lang.String $receiver, @test.another.Anno(value = "1") - java.lang.String a, @test.another.Anno(value = "2") + public static final void extensionFunction(@Anno(value = "rec") + java.lang.String $receiver, @Anno(value = "1") + java.lang.String a, @Anno(value = "2") java.lang.String b) { } - public static final java.lang.String getExtensionProperty(@test.another.Anno(value = "propRec") + public static final java.lang.String getExtensionProperty(@Anno(value = "propRec") T $receiver) { return null; } - public static final void setExtensionProperty(@test.another.Anno(value = "propRec") - T $receiver, @test.another.Anno(value = "setparam") + public static final void setExtensionProperty(@Anno(value = "propRec") + T $receiver, @Anno(value = "setparam") java.lang.String setParamName) { } }