Reapply "Add support for tests using androidx keep annotations"
This reverts commit 809cceb4534e1a1f1ca446a32bfa9fef13656cd2.
Reapply "Change the keep annotations in the androidx namespace to Kotlin source"
This reverts commit 8c2c3b1010ec081f0af519b8f8903d90229acde0.
With additional fix for SanityCheck.
Bug: b/392865072
Change-Id: I0d5dc671c4a7ea08960d92c28b5edf30e0e89627
diff --git a/src/keepanno/java/androidx/annotation/keep/KeepConstraint.kt b/src/keepanno/java/androidx/annotation/keep/KeepConstraint.kt
new file mode 100644
index 0000000..6eaebcc
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/KeepConstraint.kt
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+/**
+ * Usage constraints for how a target is used and what must be kept.
+ *
+ * <p>Providing the constraints on how an item is being used allows shrinkers to optimize or remove
+ * aspects of the item that do not change that usage constraint.
+ *
+ * <p>For example, invoking a method reflectively does not use any annotations on that method, and
+ * it is safe to remove the annotations. However, it would not be safe to remove parameters from the
+ * method.
+ */
+enum class KeepConstraint {
+ /**
+ * Indicates that the target item is being looked up reflectively.
+ *
+ * <p>Looking up an item reflectively requires that it remains on its expected context, which for
+ * a method or field means it must remain on its defining class. In other words, the item cannot
+ * be removed or moved.
+ *
+ * <p>Note that looking up a member does not imply that the holder class of the member can be
+ * looked up. If both the class and the member need to be looked, make sure to have a target for
+ * both.
+ *
+ * <p>Note also that the item can be looked up within its context but no constraint is placed on
+ * its name, accessibility or any other properties of the item.
+ *
+ * <p>If assumptions are being made about other aspects, additional constraints and targets should
+ * be added to the keep annotation.
+ */
+ LOOKUP,
+
+ /**
+ * Indicates that the name of the target item is being used.
+ *
+ * <p>This usage constraint is needed if the target is being looked up reflectively by using its
+ * name. Setting it will prohibit renaming of the target item.
+ *
+ * <p>Note that preserving the name of a member does not imply that the holder class of the member
+ * will preserve its qualified or simple name. If both the class and the member need to preserve
+ * their names, make sure to have a target for both.
+ *
+ * <p>Note that preserving the name of a member does not preserve the types of its parameters or
+ * its return type for methods or the type for fields.
+ */
+ NAME,
+
+ /**
+ * Indicates that the visibility of the target must be at least as visible as declared.
+ *
+ * <p>Setting this constraint ensures that any (reflective) access to the target that is allowed
+ * remains valid. In other words, a public class, field or method must remain public. For a
+ * non-public target its visibility may be relaxed in the direction: {@code private ->
+ * package-private -> protected -> public}.
+ *
+ * <p>Note that this constraint does not place any restrictions on any other accesses flags than
+ * visibility. In particular, flags such a static, final and abstract may change.
+ *
+ * <p>Used together with {@link #VISIBILITY_RESTRICT} the visibility will remain invariant.
+ */
+ VISIBILITY_RELAX,
+
+ /**
+ * Indicates that the visibility of the target must be at most as visible as declared.
+ *
+ * <p>Setting this constraint ensures that any (reflective) access to the target that would fail
+ * will continue to fail. In other words, a private class, field or method must remain private.
+ * Concretely the visibility of the target item may be restricted in the direction: {@code public
+ * -> protected -> package-private -> private}.
+ *
+ * <p>Note that this constraint does not place any restrictions on any other accesses flags than
+ * visibility. In particular, flags such a static, final and abstract may change.
+ *
+ * <p>Used together with {@link #VISIBILITY_RELAX} the visibility will remain invariant.
+ */
+ VISIBILITY_RESTRICT,
+
+ /**
+ * Indicates that the visibility of the target must remain as declared.
+ *
+ * <p>Note that this constraint does not place any restrictions on any other accesses flags than
+ * visibility. In particular, flags such a static, final and abstract may change.
+ *
+ * <p>This is equivalent to using both {@link #VISIBILITY_RELAX} and {@link #VISIBILITY_RESTRICT}.
+ */
+ VISIBILITY_INVARIANT,
+
+ /**
+ * Indicates that the class target is being instantiated reflectively.
+ *
+ * <p>This usage constraint is only valid on class targets.
+ *
+ * <p>Being instantiated prohibits reasoning about the class instances at compile time. In other
+ * words, the compiler must assume the class to be possibly instantiated at all times.
+ *
+ * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain a
+ * class. This constraint only implies that if the class is referenced in the program it may be
+ * instantiated.
+ */
+ CLASS_INSTANTIATE,
+
+ /**
+ * Indicates that the method target is being invoked reflectively.
+ *
+ * <p>This usage constraint is only valid on method targets.
+ *
+ * <p>To be invoked reflectively the method must retain the structure of the method. Thus, unused
+ * arguments cannot be removed. However, it does not imply preserving the types of its parameters
+ * or its return type. If the parameter types are being obtained reflectively then those need a
+ * keep target independent of the method.
+ *
+ * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain a
+ * method reference. This constraint only implies that if the method is referenced in the program
+ * it may be reflectively invoked.
+ */
+ METHOD_INVOKE,
+
+ /**
+ * Indicates that the field target is reflectively read from.
+ *
+ * <p>This usage constraint is only valid on field targets.
+ *
+ * <p>A field that has its value read from, requires that the field value must remain. Thus, if
+ * field remains, its value cannot be replaced. It can still be removed in full, be inlined and
+ * its value reasoned about at compile time.
+ *
+ * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain
+ * access to the field. This constraint only implies that if a field is referenced then it may be
+ * reflectively read.
+ */
+ FIELD_GET,
+
+ /**
+ * Indicates that the field target is reflectively written to.
+ *
+ * <p>This usage constraint is only valid on field targets.
+ *
+ * <p>A field that has its value written to, requires that the field value must be treated as
+ * unknown.
+ *
+ * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain
+ * access to the field. This constraint only implies that if a field is referenced then it may be
+ * reflectively written.
+ */
+ FIELD_SET,
+
+ /**
+ * Indicates that the target method can be replaced by an alternative definition at runtime.
+ *
+ * <p>This usage constraint is only valid on method targets.
+ *
+ * <p>Replacing a method implies that the concrete implementation of the target cannot be known at
+ * compile time. Thus, it cannot be moved or otherwise assumed to have particular properties.
+ * Being able to replace the method still allows the compiler to fully remove it if it is
+ * statically found to be unused.
+ *
+ * <p>Note also that no restriction is placed on the method name. To ensure the same name add
+ * {@link #NAME} to the constraint set.
+ */
+ METHOD_REPLACE,
+
+ /**
+ * Indicates that the target field can be replaced by an alternative definition at runtime.
+ *
+ * <p>This usage constraint is only valid on field targets.
+ *
+ * <p>Replacing a field implies that the concrete implementation of the target cannot be known at
+ * compile time. Thus, it cannot be moved or otherwise assumed to have particular properties.
+ * Being able to replace the method still allows the compiler to fully remove it if it is
+ * statically found to be unused.
+ *
+ * <p>Note also that no restriction is placed on the field name. To ensure the same name add
+ * {@link #NAME} to the constraint set.
+ */
+ FIELD_REPLACE,
+
+ /**
+ * Indicates that the target item must never be inlined or merged.
+ *
+ * <p>This ensures that if the item is actually used in the program it will remain in some form.
+ * For example, a method may still be renamed, but it will be present as a frame in stack traces
+ * produced by the runtime (before potentially being retraced). For classes, they too may be
+ * renamed, but will not have been merged with other classes or have their allocations fully
+ * eliminated (aka class inlining).
+ *
+ * <p>For members this also ensures that the field value or method body cannot be reasoned about
+ * outside the item itself. For example, a field value cannot be assumed to be a particular value,
+ * and a method cannot be assumed to have particular properties for callers, such as always
+ * throwing or a constant return value.
+ */
+ NEVER_INLINE,
+
+ /**
+ * Indicates that the class hierarchy below the target class may be extended at runtime.
+ *
+ * <p>This ensures that new subtypes of the target class can later be linked and/or class loaded
+ * at runtime.
+ *
+ * <p>This does not ensure that the class remains if it is otherwise dead code and can be fully
+ * removed.
+ *
+ * <p>Note that this constraint does not ensure that particular methods remain on the target
+ * class. If methods or fields of the target class are being targeted by a subclass that was
+ * classloaded or linked later, then keep annotations are needed for those targets too. Such
+ * non-visible uses requires the same annotations to preserve as for reflective uses.
+ */
+ CLASS_OPEN_HIERARCHY,
+
+ /**
+ * Indicates that the target item must retain its generic signature if present.
+ *
+ * <p>This ensures that the generic signature remains, but does not prohibit rewriting of the
+ * generic signature. For example, if a type present in the generic signature is renamed, the
+ * generic signature will also be updated to now refer to the type by its renamed name.
+ *
+ * <p>Note that this constraint does not otherwise restrict what can be done to the target, such
+ * as removing the target completely, inlining it, etc.
+ */
+ GENERIC_SIGNATURE,
+}