111506180: Metalava stubs are missing meta annotations on annotation classes
Test: Unit test included
Bug: 111506180
Change-Id: Id666c5e95a39f8caa94c1cbb1956ef44d8dd9360
Merged-In: I29fe18a74c16e501b27afb502898f4d0df1f87ed
diff --git a/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt b/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
index 56cdd2d..e065f58 100644
--- a/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
+++ b/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
@@ -189,7 +189,7 @@
if (annotation.isTypeDefAnnotation()) {
// Imported typedef
addItem(item, AnnotationHolder(null, annotation, null))
- } else if (annotation.isSignificant() && !annotation.hasClassRetention() &&
+ } else if (annotation.isSignificantInStubs() && !annotation.hasClassRetention() &&
!options.includeSourceRetentionAnnotations
) {
addItem(item, AnnotationHolder(null, annotation, null))
diff --git a/src/main/java/com/android/tools/metalava/SignatureWriter.kt b/src/main/java/com/android/tools/metalava/SignatureWriter.kt
index f15f039..5d7be95 100644
--- a/src/main/java/com/android/tools/metalava/SignatureWriter.kt
+++ b/src/main/java/com/android/tools/metalava/SignatureWriter.kt
@@ -162,6 +162,7 @@
skipNullnessAnnotations = options.outputKotlinStyleNulls,
omitCommonPackages = options.omitCommonPackages,
onlyIncludeSignatureAnnotations = true,
+ onlyIncludeStubAnnotations = false,
onlyIncludeClassRetentionAnnotations = false
)
}
diff --git a/src/main/java/com/android/tools/metalava/StubWriter.kt b/src/main/java/com/android/tools/metalava/StubWriter.kt
index e55138e..de41742 100644
--- a/src/main/java/com/android/tools/metalava/StubWriter.kt
+++ b/src/main/java/com/android/tools/metalava/StubWriter.kt
@@ -140,7 +140,8 @@
// Some bug in UAST triggers duplicate nullability annotations
// here; make sure the are filtered out
filterDuplicates = true,
- onlyIncludeSignatureAnnotations = true,
+ onlyIncludeSignatureAnnotations = false,
+ onlyIncludeStubAnnotations = true,
onlyIncludeClassRetentionAnnotations = true,
writer = writer
)
@@ -303,7 +304,8 @@
ModifierList.write(
writer, modifiers, item, removeAbstract = removeAbstract, removeFinal = removeFinal,
addPublic = addPublic, includeAnnotations = generateAnnotations,
- onlyIncludeSignatureAnnotations = true,
+ onlyIncludeSignatureAnnotations = false,
+ onlyIncludeStubAnnotations = true,
onlyIncludeClassRetentionAnnotations = true
)
}
diff --git a/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt b/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
index 52743fd..533abca 100644
--- a/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
@@ -24,6 +24,7 @@
import com.android.tools.lint.annotations.Extractor.ANDROID_INT_DEF
import com.android.tools.lint.annotations.Extractor.ANDROID_LONG_DEF
import com.android.tools.lint.annotations.Extractor.ANDROID_STRING_DEF
+import com.android.tools.lint.detector.api.startsWith
import com.android.tools.metalava.ANDROIDX_ANNOTATION_PREFIX
import com.android.tools.metalava.ANDROID_SUPPORT_ANNOTATION_PREFIX
import com.android.tools.metalava.JAVA_LANG_PREFIX
@@ -52,11 +53,16 @@
/** Generates source code for this annotation (using fully qualified names) */
fun toSource(): String
- /** Whether this annotation is significant and should be included in signature files, stubs, etc */
- fun isSignificant(): Boolean {
+ /** Whether this annotation is significant and should be included in signature files */
+ fun isSignificantInSignatures(): Boolean {
return includeInSignatures(qualifiedName() ?: return false)
}
+ /** Whether this annotation is significant and should be included in stub files etc */
+ fun isSignificantInStubs(): Boolean {
+ return includeInStubs(qualifiedName() ?: return false)
+ }
+
/**
* Whether this annotation has class retention. Only class retention annotations are
* inserted into the stubs, the rest are extracted into the separate external annotations file.
@@ -139,6 +145,17 @@
return false
}
+ /** Whether the given annotation name is "significant", e.g. should be included in signature files */
+ fun includeInStubs(qualifiedName: String?): Boolean {
+ qualifiedName ?: return false
+ if (includeInSignatures(qualifiedName)) {
+ return true
+ }
+
+ return qualifiedName.startsWith("java.lang.annotation") &&
+ !qualifiedName.endsWith("SuppressWarnings")
+ }
+
/** The simple name of an annotation, which is the annotation name (not qualified name) prefixed by @ */
fun simpleName(item: AnnotationItem): String {
val qualifiedName = item.qualifiedName() ?: return ""
@@ -410,7 +427,10 @@
return when (qualifiedName) {
"androidx.annotation.RecentlyNullable",
"androidx.annotation.RecentlyNonNull" -> true
- else -> false
+ else -> qualifiedName.startsWith("java.") ||
+ qualifiedName.startsWith("javax.") ||
+ qualifiedName.startsWith("kotlin.") ||
+ qualifiedName.startsWith("kotlinx.")
}
}
}
diff --git a/src/main/java/com/android/tools/metalava/model/ModifierList.kt b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
index d192cd3..a6c1b9f 100644
--- a/src/main/java/com/android/tools/metalava/model/ModifierList.kt
+++ b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
@@ -185,6 +185,7 @@
removeFinal: Boolean = false,
addPublic: Boolean = false,
onlyIncludeSignatureAnnotations: Boolean = true,
+ onlyIncludeStubAnnotations: Boolean = false,
onlyIncludeClassRetentionAnnotations: Boolean = false
) {
@@ -215,6 +216,7 @@
separateLines = false,
writer = writer,
onlyIncludeSignatureAnnotations = onlyIncludeSignatureAnnotations,
+ onlyIncludeStubAnnotations = onlyIncludeStubAnnotations,
onlyIncludeClassRetentionAnnotations = onlyIncludeClassRetentionAnnotations
)
}
@@ -389,6 +391,7 @@
filterDuplicates: Boolean = false,
writer: Writer,
onlyIncludeSignatureAnnotations: Boolean = true,
+ onlyIncludeStubAnnotations: Boolean = true,
onlyIncludeClassRetentionAnnotations: Boolean = false
) {
val annotations = list.annotations()
@@ -396,10 +399,13 @@
var index = -1
for (annotation in annotations) {
index++
- if (onlyIncludeSignatureAnnotations && !annotation.isSignificant()) {
+ if (onlyIncludeSignatureAnnotations && !annotation.isSignificantInSignatures()) {
+ continue
+ } else if (onlyIncludeStubAnnotations && !annotation.isSignificantInStubs()) {
continue
} else if (onlyIncludeClassRetentionAnnotations && !annotation.hasClassRetention() &&
- !options.includeSourceRetentionAnnotations) {
+ !options.includeSourceRetentionAnnotations
+ ) {
continue
} else if ((annotation.isNonNull() || annotation.isNullable())) {
if (skipNullnessAnnotations) {
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
index 75709ac..2f557be 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
@@ -263,7 +263,8 @@
ModifierList.write(
modifierString, method.modifiers, method, removeAbstract = false,
removeFinal = false, addPublic = true,
- onlyIncludeSignatureAnnotations = true,
+ onlyIncludeSignatureAnnotations = false,
+ onlyIncludeStubAnnotations = true,
onlyIncludeClassRetentionAnnotations = true
)
sb.append(modifierString.toString())
diff --git a/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt b/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
index f8ad6ec..0b5b239 100644
--- a/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
+++ b/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
@@ -102,7 +102,7 @@
* to be a String resource reference (e.g. {@code android.R.string.ok}).
*/
@SuppressWarnings({"unchecked", "deprecation", "all"})
- public @interface StringRes {
+ @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface StringRes {
}
"""
)
diff --git a/src/test/java/com/android/tools/metalava/StubsTest.kt b/src/test/java/com/android/tools/metalava/StubsTest.kt
index e1f47b4..19ef97d 100644
--- a/src/test/java/com/android/tools/metalava/StubsTest.kt
+++ b/src/test/java/com/android/tools/metalava/StubsTest.kt
@@ -37,6 +37,8 @@
extraArguments: Array<String> = emptyArray(),
docStubs: Boolean = false,
showAnnotations: Array<String> = emptyArray(),
+ includeSourceRetentionAnnotations: Boolean = true,
+ skipEmitPackages: List<String> = listOf("java.lang", "java.util", "java.io"),
vararg sourceFiles: TestFile
) {
check(
@@ -49,7 +51,9 @@
checkCompilation = true,
api = api,
extraArguments = extraArguments,
- docStubs = docStubs
+ docStubs = docStubs,
+ includeSourceRetentionAnnotations = includeSourceRetentionAnnotations,
+ skipEmitPackages = skipEmitPackages
)
}
@@ -305,7 +309,7 @@
source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
- public @interface Foo {
+ @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Foo {
public java.lang.String value();
}
"""
@@ -1811,28 +1815,28 @@
)
}
-@Test
-fun `Test inaccessible constructors`() {
- // If the constructors of a class are not visible, and the class has subclasses,
- // those subclass stubs will need to reference these inaccessible constructors.
- // This generally only happens when the constructors are package private (and
- // therefore hidden) but the subclass using it is also in the same package.
+ @Test
+ fun `Test inaccessible constructors`() {
+ // If the constructors of a class are not visible, and the class has subclasses,
+ // those subclass stubs will need to reference these inaccessible constructors.
+ // This generally only happens when the constructors are package private (and
+ // therefore hidden) but the subclass using it is also in the same package.
- check(
- checkDoclava1 = false,
- checkCompilation = true,
- sourceFiles =
- *arrayOf(
- java(
- """
+ check(
+ checkDoclava1 = false,
+ checkCompilation = true,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
public class MyClass1 {
MyClass1(int myVar) { }
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg;
import java.io.IOException;
@SuppressWarnings("RedundantThrows")
@@ -1840,27 +1844,27 @@
MySubClass1(int myVar) throws IOException { super(myVar); }
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg;
public class MyClass2 {
/** @hide */
public MyClass2(int myVar) { }
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg;
public class MySubClass2 extends MyClass2 {
public MySubClass2() { super(5); }
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class MyClass1 {
}
@@ -1873,22 +1877,22 @@
}
}
""",
- stubs = arrayOf(
- """
+ stubs = arrayOf(
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class MyClass1 {
MyClass1(int myVar) { throw new RuntimeException("Stub!"); }
}
""",
- """
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class MySubClass1 extends test.pkg.MyClass1 {
MySubClass1(int myVar) throws java.io.IOException { super(0); throw new RuntimeException("Stub!"); }
}
""",
- """
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class MyClass2 {
@@ -1896,32 +1900,32 @@
MyClass2(int myVar) { throw new RuntimeException("Stub!"); }
}
""",
- """
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class MySubClass2 extends test.pkg.MyClass2 {
public MySubClass2() { super(0); throw new RuntimeException("Stub!"); }
}
"""
+ )
)
- )
-}
+ }
-@Test
-fun `Generics Variable Rewriting`() {
- // When we move methods from hidden superclasses into the subclass since they
- // provide the implementation for a required method, it's possible that the
- // method we copied in is referencing generics with a different variable than
- // in the current class, so we need to handle this
+ @Test
+ fun `Generics Variable Rewriting`() {
+ // When we move methods from hidden superclasses into the subclass since they
+ // provide the implementation for a required method, it's possible that the
+ // method we copied in is referencing generics with a different variable than
+ // in the current class, so we need to handle this
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- // TODO: Try using prefixes like "A", and "AA" to make sure my generics
- // variable renaming doesn't do something really dumb
- java(
- """
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ // TODO: Try using prefixes like "A", and "AA" to make sure my generics
+ // variable renaming doesn't do something really dumb
+ java(
+ """
package test.pkg;
import java.util.List;
@@ -1951,10 +1955,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Generics {
@@ -1980,18 +1984,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Rewriting type parameters in interfaces from hidden super classes and in throws lists`() {
- checkStubs(
- extraArguments = arrayOf("--skip-inherited-methods=false"),
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Rewriting type parameters in interfaces from hidden super classes and in throws lists`() {
+ checkStubs(
+ extraArguments = arrayOf("--skip-inherited-methods=false"),
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
import java.io.IOException;
@@ -2026,10 +2030,10 @@
}
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class Generics {
ctor public Generics();
@@ -2048,8 +2052,8 @@
}
}
""",
- source = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
- """
+ source = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Generics {
@@ -2071,8 +2075,8 @@
}
}
"""
- } else {
- """
+ } else {
+ """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Generics {
@@ -2094,20 +2098,20 @@
}
}
"""
- }
- )
-}
+ }
+ )
+ }
-@Test
-fun `Picking super class throwables`() {
- // Like previous test, but without compatibility mode: ensures that we
- // use super classes of filtered throwables
- checkStubs(
- compatibilityMode = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Picking super class throwables`() {
+ // Like previous test, but without compatibility mode: ensures that we
+ // use super classes of filtered throwables
+ checkStubs(
+ compatibilityMode = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
import java.io.IOException;
@@ -2142,10 +2146,10 @@
}
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class Generics {
ctor public Generics();
@@ -2164,7 +2168,7 @@
}
}
""",
- source = """
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Generics {
@@ -2186,19 +2190,19 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Rewriting implements class references`() {
- // Checks some more subtle bugs around generics type variable renaming
- checkStubs(
- extraArguments = arrayOf("--skip-inherited-methods=false"),
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Rewriting implements class references`() {
+ // Checks some more subtle bugs around generics type variable renaming
+ checkStubs(
+ extraArguments = arrayOf("--skip-inherited-methods=false"),
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
import java.util.Collection;
@@ -2225,10 +2229,10 @@
}
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class ConcurrentHashMap<K, V> {
ctor public ConcurrentHashMap();
@@ -2241,7 +2245,7 @@
}
}
""",
- source = """
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class ConcurrentHashMap<K, V> {
@@ -2255,17 +2259,17 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Arrays in type arguments`() {
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Arrays in type arguments`() {
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
public class Generics2 {
@@ -2277,10 +2281,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Generics2 {
@@ -2294,20 +2298,20 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Interface extending multiple interfaces`() {
- // Ensure that we handle sorting correctly where we're mixing super classes and implementing
- // interfaces
- // Real-world example: XmlResourceParser
- check(
- checkDoclava1 = false,
- checkCompilation = true,
- sourceFiles = *arrayOf(
- java(
- """
+ @Test
+ fun `Interface extending multiple interfaces`() {
+ // Ensure that we handle sorting correctly where we're mixing super classes and implementing
+ // interfaces
+ // Real-world example: XmlResourceParser
+ check(
+ checkDoclava1 = false,
+ checkCompilation = true,
+ sourceFiles = *arrayOf(
+ java(
+ """
package android.content.res;
import android.util.AttributeSet;
import org.xmlpull.v1.XmlPullParser;
@@ -2317,52 +2321,52 @@
public void close();
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package android.util;
public interface AttributeSet {
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package java.lang;
public interface AutoCloseable {
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package org.xmlpull.v1;
public interface XmlPullParser {
}
"""
- )
- ),
- stubs = arrayOf(
- """
+ )
+ ),
+ stubs = arrayOf(
+ """
package android.content.res;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public interface XmlResourceParser extends org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, java.lang.AutoCloseable {
public void close();
}
"""
+ )
)
- )
-}
+ }
// TODO: Add a protected constructor too to make sure my code to make non-public constructors package private
// don't accidentally demote protected constructors to package private!
-@Test
-fun `Picking Super Constructors`() {
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Picking Super Constructors`() {
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
import java.io.IOException;
@@ -2434,10 +2438,10 @@
}
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class PickConstructors {
ctor public PickConstructors();
@@ -2478,7 +2482,7 @@
}
}
""",
- source = """
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class PickConstructors {
@@ -2530,17 +2534,17 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Picking Constructors`() {
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Picking Constructors`() {
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
@SuppressWarnings({"WeakerAccess", "unused"})
@@ -2617,10 +2621,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Constructors2 {
@@ -2664,18 +2668,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Another Constructor Test`() {
- // A specific scenario triggered in the API where the right super class detector was not chosen
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Another Constructor Test`() {
+ // A specific scenario triggered in the API where the right super class detector was not chosen
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
@SuppressWarnings({"RedundantThrows", "JavaDoc", "WeakerAccess"})
@@ -2701,10 +2705,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class PickConstructors2 {
@@ -2725,18 +2729,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Overriding protected methods`() {
- // Checks a scenario where the stubs were missing overrides
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Overriding protected methods`() {
+ // Checks a scenario where the stubs were missing overrides
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
@SuppressWarnings("all")
@@ -2759,10 +2763,10 @@
}
}
"""
- )
- ),
- warnings = "",
- api = """
+ )
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class Layouts {
ctor public Layouts();
@@ -2780,7 +2784,7 @@
}
}
""",
- source = """
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Layouts {
@@ -2802,18 +2806,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Missing overridden method`() {
- // Another special case where overridden methods were missing
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Missing overridden method`() {
+ // Another special case where overridden methods were missing
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
import java.util.Collection;
@@ -2840,10 +2844,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class SpanTest {
@@ -2865,18 +2869,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Skip type variables in casts`() {
- // When generating casts in super constructor calls, use raw types
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Skip type variables in casts`() {
+ // When generating casts in super constructor calls, use raw types
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg;
@SuppressWarnings("all")
@@ -2896,10 +2900,10 @@
}
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg;
@SuppressWarnings({"unchecked", "deprecation", "all"})
public class Properties {
@@ -2915,18 +2919,18 @@
}
}
"""
- )
-}
+ )
+ }
-@Test
-fun `Rewrite relative documentation links`() {
- // When generating casts in super constructor calls, use raw types
- checkStubs(
- checkDoclava1 = false,
- sourceFiles =
- *arrayOf(
- java(
- """
+ @Test
+ fun `Rewrite relative documentation links`() {
+ // When generating casts in super constructor calls, use raw types
+ checkStubs(
+ checkDoclava1 = false,
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
package test.pkg1;
import java.io.IOException;
import test.pkg2.OtherClass;
@@ -2958,9 +2962,9 @@
public boolean importance;
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg2;
@SuppressWarnings("all")
@@ -2971,19 +2975,19 @@
public void bar(int baz, boolean bar);
}
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg1;
@SuppressWarnings("all")
public class LocalClass {
}
"""
- )
- ),
- warnings = "",
- source = """
+ )
+ ),
+ warnings = "",
+ source = """
package test.pkg1;
import test.pkg2.OtherClass;
import java.io.IOException;
@@ -3015,12 +3019,11 @@
public boolean importance;
}
"""
- )
-}
+ )
+ }
@Test
fun `Annotation default values`() {
-
checkStubs(
compatibilityMode = false,
sourceFiles =
@@ -3083,7 +3086,6 @@
)
),
warnings = "",
- // TODO: Put default values into signature files if not compatibiility mode
api = """
package test.pkg {
public @interface ExportedProperty {
@@ -3123,7 +3125,7 @@
* by this annotation.
*/
@SuppressWarnings({"unchecked", "deprecation", "all"})
- public @interface ExportedProperty {
+ @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface ExportedProperty {
/**
* When resolveId is true, and if the annotated field/method return value
* is an int, the value is converted to an Android's resource name.
@@ -3155,51 +3157,82 @@
public static final int PX = 1; // 0x1
public static final int SP = 2; // 0x2
@SuppressWarnings({"unchecked", "deprecation", "all"})
- public static @interface InnerAnnotation {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface InnerAnnotation {
}
}
"""
)
}
-@Test
-fun `Check writing package info file`() {
- checkStubs(
- sourceFiles =
- *arrayOf(
- java(
+ @Test
+ fun `Annotation metadata in stubs`() {
+ checkStubs(
+ compatibilityMode = false,
+ includeSourceRetentionAnnotations = false,
+ skipEmitPackages = emptyList(),
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
+ package java.lang;
+
+ import java.lang.annotation.*;
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MyAnnotation {
+ }
+ """
+ )
+ ),
+ warnings = "",
+ source = """
+ package java.lang;
+ @SuppressWarnings({"unchecked", "deprecation", "all"})
+ @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface MyAnnotation {
+ }
"""
+ )
+ }
+
+ @Test
+ fun `Check writing package info file`() {
+ checkStubs(
+ sourceFiles =
+ *arrayOf(
+ java(
+ """
@androidx.annotation.Nullable
package test.pkg;
"""
- ),
- java(
- """
+ ),
+ java(
+ """
package test.pkg;
@SuppressWarnings("all")
public class Test {
}
"""
- ),
+ ),
- androidxNullableSource
- ),
- warnings = "",
- api = """
+ androidxNullableSource
+ ),
+ warnings = "",
+ api = """
package test.pkg {
public class Test {
ctor public Test();
}
}
""", // WRONG: I should include package annotations!
- source = """
+ source = """
@androidx.annotation.Nullable
package test.pkg;
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation")
- )
-}
+ extraArguments = arrayOf("--hide-package", "androidx.annotation")
+ )
+ }
// TODO: Add in some type variables in method signatures and constructors!
// TODO: Test what happens when a class extends a hidden extends a public in separate packages,