| 1 21 package proguard.shrink; 22 23 import proguard.classfile.util.SimplifiedVisitor; 24 import proguard.classfile.attribute.visitor.*; 25 import proguard.classfile.attribute.*; 26 import proguard.classfile.attribute.annotation.visitor.*; 27 import proguard.classfile.attribute.annotation.*; 28 import proguard.classfile.constant.visitor.ConstantVisitor; 29 import proguard.classfile.constant.*; 30 import proguard.classfile.visitor.*; 31 import proguard.classfile.*; 32 33 41 public class AnnotationUsageMarker 42 extends SimplifiedVisitor 43 implements AttributeVisitor, 44 AnnotationVisitor, 45 ElementValueVisitor, 46 ConstantVisitor, 47 ClassVisitor, 48 MemberVisitor 49 { 50 private UsageMarker usageMarker; 51 52 private boolean attributeUsed; 54 private boolean annotationUsed; 55 private boolean elementValueUsed; 56 private boolean classUsed; 57 private boolean methodUsed; 58 59 60 65 public AnnotationUsageMarker(UsageMarker usageMarker) 66 { 67 this.usageMarker = usageMarker; 68 } 69 70 71 73 public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} 74 75 76 public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) 77 { 78 attributeUsed = false; 80 annotationsAttribute.annotationsAccept(clazz, this); 81 82 if (attributeUsed) 83 { 84 usageMarker.markAsUsed(annotationsAttribute); 87 88 markConstant(clazz, annotationsAttribute.u2attributeNameIndex); 89 } 90 } 91 92 93 public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) 94 { 95 attributeUsed = false; 97 parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); 98 99 if (attributeUsed) 100 { 101 usageMarker.markAsUsed(parameterAnnotationsAttribute); 104 105 markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex); 106 } 107 } 108 109 110 public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) 111 { 112 attributeUsed = false; 114 annotationDefaultAttribute.defaultValueAccept(clazz, this); 115 116 if (attributeUsed) 117 { 118 usageMarker.markAsUsed(annotationDefaultAttribute); 121 122 markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex); 123 } 124 } 125 126 127 129 public void visitAnnotation(Clazz clazz, Annotation annotation) 130 { 131 if (isReferencedClassUsed(annotation)) 132 { 133 usageMarker.markAsUsed(annotation); 135 136 markConstant(clazz, annotation.u2typeIndex); 137 138 annotation.elementValuesAccept(clazz, this); 140 141 annotationUsed = true; 143 attributeUsed = true; 144 } 145 } 146 147 148 150 public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) 151 { 152 if (isReferencedMethodUsed(constantElementValue)) 153 { 154 usageMarker.markAsUsed(constantElementValue); 156 157 markConstant(clazz, constantElementValue.u2elementNameIndex); 158 markConstant(clazz, constantElementValue.u2constantValueIndex); 159 160 elementValueUsed = true; 162 } 163 } 164 165 166 public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) 167 { 168 if (isReferencedMethodUsed(enumConstantElementValue)) 169 { 170 classUsed = true; 172 enumConstantElementValue.referencedClassesAccept(usageMarker); 173 174 if (classUsed) 175 { 176 usageMarker.markAsUsed(enumConstantElementValue); 178 179 markConstant(clazz, enumConstantElementValue.u2elementNameIndex); 180 markConstant(clazz, enumConstantElementValue.u2typeNameIndex); 181 markConstant(clazz, enumConstantElementValue.u2constantNameIndex); 182 183 elementValueUsed = true; 185 } 186 } 187 } 188 189 190 public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) 191 { 192 if (isReferencedMethodUsed(classElementValue)) 193 { 194 classUsed = true; 196 classElementValue.referencedClassesAccept(usageMarker); 197 198 if (classUsed) 199 { 200 usageMarker.markAsUsed(classElementValue); 202 203 markConstant(clazz, classElementValue.u2elementNameIndex); 204 markConstant(clazz, classElementValue.u2classInfoIndex); 205 206 elementValueUsed = true; 208 } 209 } 210 } 211 212 213 public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) 214 { 215 if (isReferencedMethodUsed(annotationElementValue)) 216 { 217 boolean oldAnnotationUsed = annotationUsed; 218 219 annotationUsed = false; 221 annotationElementValue.annotationAccept(clazz, this); 222 223 if (annotationUsed) 224 { 225 usageMarker.markAsUsed(annotationElementValue); 227 228 markConstant(clazz, annotationElementValue.u2elementNameIndex); 229 230 elementValueUsed = true; 232 } 233 234 annotationUsed = oldAnnotationUsed; 235 } 236 } 237 238 239 public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) 240 { 241 if (isReferencedMethodUsed(arrayElementValue)) 242 { 243 boolean oldelementValueUsed = elementValueUsed; 244 245 elementValueUsed = false; 247 arrayElementValue.elementValuesAccept(clazz, annotation, this); 248 249 if (elementValueUsed) 250 { 251 usageMarker.markAsUsed(arrayElementValue); 253 254 markConstant(clazz, arrayElementValue.u2elementNameIndex); 255 256 } 259 else 260 { 261 elementValueUsed = oldelementValueUsed; 262 } 263 } 264 } 265 266 267 269 public void visitAnyConstant(Clazz clazz, Constant constant) 270 { 271 usageMarker.markAsUsed(constant); 272 } 273 274 275 public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 276 { 277 classUsed = usageMarker.isUsed(classConstant); 278 279 if (!classUsed) 281 { 282 classUsed = true; 284 classConstant.referencedClassAccept(this); 285 286 if (classUsed) 288 { 289 usageMarker.markAsUsed(classConstant); 291 292 markConstant(clazz, classConstant.u2nameIndex); 293 } 294 } 295 } 296 297 298 300 public void visitProgramClass(ProgramClass programClass) 301 { 302 classUsed = usageMarker.isUsed(programClass); 303 } 304 305 306 public void visitLibraryClass(LibraryClass libraryClass) 307 { 308 classUsed = true; 309 } 310 311 312 314 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 315 { 316 methodUsed = usageMarker.isUsed(programMethod); 317 } 318 319 320 public void visitLibraryMethod(LibraryClass LibraryClass, LibraryMethod libraryMethod) 321 { 322 classUsed = true; 323 } 324 325 326 328 331 private boolean isReferencedClassUsed(Annotation annotation) 332 { 333 classUsed = true; 335 annotation.referencedClassAccept(this); 336 337 return classUsed; 338 } 339 340 341 344 private boolean isReferencedMethodUsed(ElementValue elementValue) 345 { 346 methodUsed = true; 348 elementValue.referencedMethodAccept(this); 349 350 return methodUsed; 351 } 352 353 354 357 private void markConstant(Clazz clazz, int index) 358 { 359 if (index > 0) 360 { 361 clazz.constantPoolEntryAccept(index, this); 362 } 363 } 364 } 365 | Popular Tags |