Make sure that RestrictTo used on file is recorded correctly am: 8ebac3744d
Original change: https://android-review.googlesource.com/c/platform/tools/metalava/+/1945632
Change-Id: I792f2a948c5e64ec9e03f7449f68931cc3d5623e
diff --git a/src/main/java/com/android/tools/metalava/AnnotationFilter.kt b/src/main/java/com/android/tools/metalava/AnnotationFilter.kt
index 172c32a..89b0edf 100644
--- a/src/main/java/com/android/tools/metalava/AnnotationFilter.kt
+++ b/src/main/java/com/android/tools/metalava/AnnotationFilter.kt
@@ -1,8 +1,10 @@
package com.android.tools.metalava
import com.android.SdkConstants.ATTR_VALUE
+import com.android.tools.metalava.model.AnnotationArrayAttributeValue
import com.android.tools.metalava.model.AnnotationAttribute
import com.android.tools.metalava.model.AnnotationItem
+import com.android.tools.metalava.model.AnnotationSingleAttributeValue
import com.android.tools.metalava.model.DefaultAnnotationAttribute
interface AnnotationFilter {
@@ -93,9 +95,29 @@
return false
}
for (attribute in filter.attributes) {
- val existingValue = existingAnnotation.findAttribute(attribute.name)?.value?.toSource()
- if (existingValue != attribute.value.toSource()) {
- return false
+ val existingValue = existingAnnotation.findAttribute(attribute.name)?.value
+ val existingValueSource = existingValue?.toSource()
+ val attributeValueSource = attribute.value.toSource()
+ if (attribute.name == "value") {
+ // Special-case where varargs value annotation attribute can be specified with
+ // either @Foo(BAR) or @Foo({BAR}) and they are equivalent.
+ when {
+ attribute.value is AnnotationSingleAttributeValue &&
+ existingValue is AnnotationArrayAttributeValue -> {
+ if (existingValueSource != "{$attributeValueSource}") return false
+ }
+ attribute.value is AnnotationArrayAttributeValue &&
+ existingValue is AnnotationSingleAttributeValue -> {
+ if ("{$existingValueSource}" != attributeValueSource) return false
+ }
+ else -> {
+ if (existingValueSource != attributeValueSource) return false
+ }
+ }
+ } else {
+ if (existingValueSource != attributeValueSource) {
+ return false
+ }
}
}
return true
diff --git a/src/main/java/com/android/tools/metalava/model/psi/CodePrinter.kt b/src/main/java/com/android/tools/metalava/model/psi/CodePrinter.kt
index 44323b2..83b58b9 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/CodePrinter.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/CodePrinter.kt
@@ -37,6 +37,7 @@
import com.intellij.psi.PsiTypeCastExpression
import com.intellij.psi.PsiVariable
import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.Name
import org.jetbrains.uast.UAnnotation
import org.jetbrains.uast.UBinaryExpression
import org.jetbrains.uast.UBinaryExpressionWithType
@@ -439,8 +440,15 @@
is Pair<*, *> -> {
val first = value.first
+ val second = value.second
if (first is ClassId) {
- return first.packageFqName.asString() + "." + first.relativeClassName.asString()
+ val qualifiedName = first.packageFqName.asString() + "." +
+ first.relativeClassName.asString()
+ return if (second is Name) {
+ qualifiedName + "." + second.asString()
+ } else {
+ qualifiedName
+ }
}
}
}
diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
index 36cbd0a..1a04de5 100644
--- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
@@ -4595,4 +4595,55 @@
"""
)
}
+
+ @Test
+ fun `Constants in a file scope annotation`() {
+ check(
+ format = FileFormat.V4,
+ sourceFiles = arrayOf(
+ kotlin(
+ """
+ @file:RestrictTo(RestrictTo.Scope.LIBRARY)
+ package test.pkg
+ import androidx.annotation.RestrictTo
+ private fun veryFun(): Boolean = true
+ """
+ ),
+ restrictToSource
+ ),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
+ api = """
+ // Signature format: 4.0
+ package test.pkg {
+ @RestrictTo({androidx.annotation.RestrictTo.Scope.LIBRARY}) public final class TestKt {
+ }
+ }
+ """
+ )
+ }
+
+ @Test
+ fun `RestrictTo on a file hiding it`() {
+ check(
+ format = FileFormat.V4,
+ sourceFiles = arrayOf(
+ kotlin(
+ """
+ @file:RestrictTo(RestrictTo.Scope.LIBRARY)
+ package test.pkg
+ import androidx.annotation.RestrictTo
+ private fun veryFun(): Boolean = true
+ """
+ ),
+ restrictToSource
+ ),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation", "--show-unannotated"),
+ hideAnnotations = arrayOf(
+ "androidx.annotation.RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY)"
+ ),
+ api = """
+ // Signature format: 4.0
+ """
+ )
+ }
}
diff --git a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
index 0fdfad6..d578242 100644
--- a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
+++ b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
@@ -2326,6 +2326,7 @@
enum_constant @Deprecated public static final androidx.annotation.RestrictTo.Scope GROUP_ID;
enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY;
enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY_GROUP;
+ enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY_GROUP_PREFIX;
enum_constant public static final androidx.annotation.RestrictTo.Scope SUBCLASSES;
enum_constant public static final androidx.annotation.RestrictTo.Scope TESTS;
}
@@ -2432,6 +2433,7 @@
enum_constant public static final deprecated androidx.annotation.RestrictTo.Scope GROUP_ID;
enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY;
enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY_GROUP;
+ enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY_GROUP_PREFIX;
enum_constant public static final androidx.annotation.RestrictTo.Scope SUBCLASSES;
enum_constant public static final androidx.annotation.RestrictTo.Scope TESTS;
}
diff --git a/src/test/java/com/android/tools/metalava/DriverTest.kt b/src/test/java/com/android/tools/metalava/DriverTest.kt
index caea8ad..cf24bb2 100644
--- a/src/test/java/com/android/tools/metalava/DriverTest.kt
+++ b/src/test/java/com/android/tools/metalava/DriverTest.kt
@@ -1942,22 +1942,35 @@
"""
).indented()
-val restrictToSource: TestFile = java(
+val restrictToSource: TestFile = kotlin(
"""
- package androidx.annotation;
- import java.lang.annotation.*;
- import static java.lang.annotation.ElementType.*;
- import static java.lang.annotation.RetentionPolicy.*;
- @SuppressWarnings("WeakerAccess")
- @Retention(CLASS)
- @Target({ANNOTATION_TYPE, TYPE, METHOD, CONSTRUCTOR, FIELD, PACKAGE})
- public @interface RestrictTo {
- Scope[] value();
- enum Scope {
+ package androidx.annotation
+
+ import androidx.annotation.RestrictTo.Scope
+ import java.lang.annotation.ElementType.*
+
+ @MustBeDocumented
+ @kotlin.annotation.Retention(AnnotationRetention.BINARY)
+ @Target(
+ AnnotationTarget.ANNOTATION_CLASS,
+ AnnotationTarget.CLASS,
+ AnnotationTarget.FUNCTION,
+ AnnotationTarget.PROPERTY_GETTER,
+ AnnotationTarget.PROPERTY_SETTER,
+ AnnotationTarget.CONSTRUCTOR,
+ AnnotationTarget.FIELD,
+ AnnotationTarget.FILE
+ )
+ // Needed due to Kotlin's lack of PACKAGE annotation target
+ // https://youtrack.jetbrains.com/issue/KT-45921
+ @Suppress("DEPRECATED_JAVA_ANNOTATION")
+ @java.lang.annotation.Target(ANNOTATION_TYPE, TYPE, METHOD, CONSTRUCTOR, FIELD, PACKAGE)
+ public annotation class RestrictTo(vararg val value: Scope) {
+ public enum class Scope {
LIBRARY,
LIBRARY_GROUP,
- /** @deprecated */
- @Deprecated
+ LIBRARY_GROUP_PREFIX,
+ @Deprecated("Use LIBRARY_GROUP_PREFIX instead.")
GROUP_ID,
TESTS,
SUBCLASSES,