blob: 6eaebcc446bfbc044533b7ca8ec8d9b69b4fd18f [file] [log] [blame]
Søren Gjesse591455a2025-02-06 16:46:39 +01001/*
2 * Copyright 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// ***********************************************************************************
18// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
19// ***********************************************************************************
20
Søren Gjesse495b0382025-02-19 16:59:13 +010021package androidx.annotation.keep
Søren Gjesse591455a2025-02-06 16:46:39 +010022
23/**
24 * Usage constraints for how a target is used and what must be kept.
25 *
26 * <p>Providing the constraints on how an item is being used allows shrinkers to optimize or remove
27 * aspects of the item that do not change that usage constraint.
28 *
29 * <p>For example, invoking a method reflectively does not use any annotations on that method, and
30 * it is safe to remove the annotations. However, it would not be safe to remove parameters from the
31 * method.
32 */
Søren Gjesse495b0382025-02-19 16:59:13 +010033enum class KeepConstraint {
Søren Gjesse591455a2025-02-06 16:46:39 +010034 /**
35 * Indicates that the target item is being looked up reflectively.
36 *
37 * <p>Looking up an item reflectively requires that it remains on its expected context, which for
38 * a method or field means it must remain on its defining class. In other words, the item cannot
39 * be removed or moved.
40 *
41 * <p>Note that looking up a member does not imply that the holder class of the member can be
42 * looked up. If both the class and the member need to be looked, make sure to have a target for
43 * both.
44 *
45 * <p>Note also that the item can be looked up within its context but no constraint is placed on
46 * its name, accessibility or any other properties of the item.
47 *
48 * <p>If assumptions are being made about other aspects, additional constraints and targets should
49 * be added to the keep annotation.
50 */
51 LOOKUP,
52
53 /**
54 * Indicates that the name of the target item is being used.
55 *
56 * <p>This usage constraint is needed if the target is being looked up reflectively by using its
57 * name. Setting it will prohibit renaming of the target item.
58 *
59 * <p>Note that preserving the name of a member does not imply that the holder class of the member
60 * will preserve its qualified or simple name. If both the class and the member need to preserve
61 * their names, make sure to have a target for both.
62 *
63 * <p>Note that preserving the name of a member does not preserve the types of its parameters or
64 * its return type for methods or the type for fields.
65 */
66 NAME,
67
68 /**
69 * Indicates that the visibility of the target must be at least as visible as declared.
70 *
71 * <p>Setting this constraint ensures that any (reflective) access to the target that is allowed
72 * remains valid. In other words, a public class, field or method must remain public. For a
73 * non-public target its visibility may be relaxed in the direction: {@code private ->
74 * package-private -> protected -> public}.
75 *
76 * <p>Note that this constraint does not place any restrictions on any other accesses flags than
77 * visibility. In particular, flags such a static, final and abstract may change.
78 *
79 * <p>Used together with {@link #VISIBILITY_RESTRICT} the visibility will remain invariant.
80 */
81 VISIBILITY_RELAX,
82
83 /**
84 * Indicates that the visibility of the target must be at most as visible as declared.
85 *
86 * <p>Setting this constraint ensures that any (reflective) access to the target that would fail
87 * will continue to fail. In other words, a private class, field or method must remain private.
88 * Concretely the visibility of the target item may be restricted in the direction: {@code public
89 * -> protected -> package-private -> private}.
90 *
91 * <p>Note that this constraint does not place any restrictions on any other accesses flags than
92 * visibility. In particular, flags such a static, final and abstract may change.
93 *
94 * <p>Used together with {@link #VISIBILITY_RELAX} the visibility will remain invariant.
95 */
96 VISIBILITY_RESTRICT,
97
98 /**
99 * Indicates that the visibility of the target must remain as declared.
100 *
101 * <p>Note that this constraint does not place any restrictions on any other accesses flags than
102 * visibility. In particular, flags such a static, final and abstract may change.
103 *
104 * <p>This is equivalent to using both {@link #VISIBILITY_RELAX} and {@link #VISIBILITY_RESTRICT}.
105 */
106 VISIBILITY_INVARIANT,
107
108 /**
109 * Indicates that the class target is being instantiated reflectively.
110 *
111 * <p>This usage constraint is only valid on class targets.
112 *
113 * <p>Being instantiated prohibits reasoning about the class instances at compile time. In other
114 * words, the compiler must assume the class to be possibly instantiated at all times.
115 *
116 * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain a
117 * class. This constraint only implies that if the class is referenced in the program it may be
118 * instantiated.
119 */
120 CLASS_INSTANTIATE,
121
122 /**
123 * Indicates that the method target is being invoked reflectively.
124 *
125 * <p>This usage constraint is only valid on method targets.
126 *
127 * <p>To be invoked reflectively the method must retain the structure of the method. Thus, unused
128 * arguments cannot be removed. However, it does not imply preserving the types of its parameters
129 * or its return type. If the parameter types are being obtained reflectively then those need a
130 * keep target independent of the method.
131 *
132 * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain a
133 * method reference. This constraint only implies that if the method is referenced in the program
134 * it may be reflectively invoked.
135 */
136 METHOD_INVOKE,
137
138 /**
139 * Indicates that the field target is reflectively read from.
140 *
141 * <p>This usage constraint is only valid on field targets.
142 *
143 * <p>A field that has its value read from, requires that the field value must remain. Thus, if
144 * field remains, its value cannot be replaced. It can still be removed in full, be inlined and
145 * its value reasoned about at compile time.
146 *
147 * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain
148 * access to the field. This constraint only implies that if a field is referenced then it may be
149 * reflectively read.
150 */
151 FIELD_GET,
152
153 /**
154 * Indicates that the field target is reflectively written to.
155 *
156 * <p>This usage constraint is only valid on field targets.
157 *
158 * <p>A field that has its value written to, requires that the field value must be treated as
159 * unknown.
160 *
161 * <p>Note that the constraint {@link KeepConstraint#LOOKUP} is needed to reflectively obtain
162 * access to the field. This constraint only implies that if a field is referenced then it may be
163 * reflectively written.
164 */
165 FIELD_SET,
166
167 /**
168 * Indicates that the target method can be replaced by an alternative definition at runtime.
169 *
170 * <p>This usage constraint is only valid on method targets.
171 *
172 * <p>Replacing a method implies that the concrete implementation of the target cannot be known at
173 * compile time. Thus, it cannot be moved or otherwise assumed to have particular properties.
174 * Being able to replace the method still allows the compiler to fully remove it if it is
175 * statically found to be unused.
176 *
177 * <p>Note also that no restriction is placed on the method name. To ensure the same name add
178 * {@link #NAME} to the constraint set.
179 */
180 METHOD_REPLACE,
181
182 /**
183 * Indicates that the target field can be replaced by an alternative definition at runtime.
184 *
185 * <p>This usage constraint is only valid on field targets.
186 *
187 * <p>Replacing a field implies that the concrete implementation of the target cannot be known at
188 * compile time. Thus, it cannot be moved or otherwise assumed to have particular properties.
189 * Being able to replace the method still allows the compiler to fully remove it if it is
190 * statically found to be unused.
191 *
192 * <p>Note also that no restriction is placed on the field name. To ensure the same name add
193 * {@link #NAME} to the constraint set.
194 */
195 FIELD_REPLACE,
196
197 /**
198 * Indicates that the target item must never be inlined or merged.
199 *
200 * <p>This ensures that if the item is actually used in the program it will remain in some form.
201 * For example, a method may still be renamed, but it will be present as a frame in stack traces
202 * produced by the runtime (before potentially being retraced). For classes, they too may be
203 * renamed, but will not have been merged with other classes or have their allocations fully
204 * eliminated (aka class inlining).
205 *
206 * <p>For members this also ensures that the field value or method body cannot be reasoned about
207 * outside the item itself. For example, a field value cannot be assumed to be a particular value,
208 * and a method cannot be assumed to have particular properties for callers, such as always
209 * throwing or a constant return value.
210 */
211 NEVER_INLINE,
212
213 /**
214 * Indicates that the class hierarchy below the target class may be extended at runtime.
215 *
216 * <p>This ensures that new subtypes of the target class can later be linked and/or class loaded
217 * at runtime.
218 *
219 * <p>This does not ensure that the class remains if it is otherwise dead code and can be fully
220 * removed.
221 *
222 * <p>Note that this constraint does not ensure that particular methods remain on the target
223 * class. If methods or fields of the target class are being targeted by a subclass that was
224 * classloaded or linked later, then keep annotations are needed for those targets too. Such
225 * non-visible uses requires the same annotations to preserve as for reflective uses.
226 */
227 CLASS_OPEN_HIERARCHY,
228
229 /**
230 * Indicates that the target item must retain its generic signature if present.
231 *
232 * <p>This ensures that the generic signature remains, but does not prohibit rewriting of the
233 * generic signature. For example, if a type present in the generic signature is renamed, the
234 * generic signature will also be updated to now refer to the type by its renamed name.
235 *
236 * <p>Note that this constraint does not otherwise restrict what can be done to the target, such
237 * as removing the target completely, inlining it, etc.
238 */
239 GENERIC_SIGNATURE,
240}