1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.Annotations; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.AnnotationsList; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstFieldRef; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Per-class directory of annotations. 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class AnnotationsDirectoryItem extends OffsettedItem { 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the required alignment for instances of this class */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int ALIGNMENT = 4; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** write size of this class's header, in bytes */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int HEADER_SIZE = 16; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** write size of a list element, in bytes */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int ELEMENT_SIZE = 8; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} the class-level annotations, if any */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private AnnotationSetItem classAnnotations; 45de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} the annotated fields, if any */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<FieldAnnotationStruct> fieldAnnotations; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} the annotated methods, if any */ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<MethodAnnotationStruct> methodAnnotations; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} the annotated parameters, if any */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<ParameterAnnotationStruct> parameterAnnotations; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an empty instance. 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public AnnotationsDirectoryItem() { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(ALIGNMENT, -1); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classAnnotations = null; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldAnnotations = null; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodAnnotations = null; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parameterAnnotations = null; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 66de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ItemType itemType() { 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether this item is empty (has no contents). 75de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} if this item is empty, or {@code false} 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if not 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isEmpty() { 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (classAnnotations == null) && 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (fieldAnnotations == null) && 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (methodAnnotations == null) && 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (parameterAnnotations == null); 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether this item is a candidate for interning. The only 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interning candidates are ones that <i>only</i> have a non-null 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set of class annotations, with no other lists. 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} if this is an interning candidate, or 9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false} if not 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isInternable() { 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (classAnnotations != null) && 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (fieldAnnotations == null) && 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (methodAnnotations == null) && 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (parameterAnnotations == null); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (classAnnotations == null) { 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 107de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return classAnnotations.hashCode(); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 113de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p><b>Note:</b>: This throws an exception if this item is not 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * internable.</p> 116de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #isInternable 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int compareTo0(OffsettedItem other) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! isInternable()) { 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnsupportedOperationException("uninternable instance"); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationsDirectoryItem otherDirectory = 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (AnnotationsDirectoryItem) other; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return classAnnotations.compareTo(otherDirectory.classAnnotations); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the direct annotations on this instance. These are annotations 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * made on the class, per se, as opposed to on one of its members. 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It is only valid to call this method at most once per instance. 134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param annotations {@code non-null;} annotations to set for this class 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setClassAnnotations(Annotations annotations) { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotations == null) { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("annotations == null"); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (classAnnotations != null) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnsupportedOperationException( 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "class annotations already set"); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classAnnotations = new AnnotationSetItem(annotations); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds a field annotations item to this instance. 152de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param field {@code non-null;} field in question 15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param annotations {@code non-null;} associated annotations to add 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addFieldAnnotations(CstFieldRef field, 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Annotations annotations) { 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldAnnotations == null) { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldAnnotations = new ArrayList<FieldAnnotationStruct>(); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 161de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fieldAnnotations.add(new FieldAnnotationStruct(field, 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationSetItem(annotations))); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds a method annotations item to this instance. 168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} method in question 17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param annotations {@code non-null;} associated annotations to add 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addMethodAnnotations(CstMethodRef method, 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Annotations annotations) { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodAnnotations == null) { 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodAnnotations = new ArrayList<MethodAnnotationStruct>(); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodAnnotations.add(new MethodAnnotationStruct(method, 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationSetItem(annotations))); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds a parameter annotations item to this instance. 184de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} method in question 18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param list {@code non-null;} associated list of annotation sets to add 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addParameterAnnotations(CstMethodRef method, 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationsList list) { 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parameterAnnotations == null) { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parameterAnnotations = new ArrayList<ParameterAnnotationStruct>(); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parameterAnnotations.add(new ParameterAnnotationStruct(method, list)); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the method annotations for a given method, if any. This is 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * meant for use by debugging / dumping code. 200de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} the method 20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the method annotations, if any 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Annotations getMethodAnnotations(CstMethodRef method) { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodAnnotations == null) { 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (MethodAnnotationStruct item : methodAnnotations) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (item.getMethod().equals(method)) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return item.getAnnotations(); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the parameter annotations for a given method, if any. This is 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * meant for use by debugging / dumping code. 221de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 22299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} the method 22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the parameter annotations, if any 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public AnnotationsList getParameterAnnotations(CstMethodRef method) { 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parameterAnnotations == null) { 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ParameterAnnotationStruct item : parameterAnnotations) { 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (item.getMethod().equals(method)) { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return item.getAnnotationsList(); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addContents(DexFile file) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MixedItemSection wordData = file.getWordData(); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (classAnnotations != null) { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project classAnnotations = wordData.intern(classAnnotations); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldAnnotations != null) { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (FieldAnnotationStruct item : fieldAnnotations) { 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.addContents(file); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodAnnotations != null) { 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (MethodAnnotationStruct item : methodAnnotations) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.addContents(file); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parameterAnnotations != null) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ParameterAnnotationStruct item : parameterAnnotations) { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.addContents(file); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("unsupported"); 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void place0(Section addedTo, int offset) { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We just need to set the write size here. 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int elementCount = listSize(fieldAnnotations) 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + listSize(methodAnnotations) + listSize(parameterAnnotations); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setWriteSize(HEADER_SIZE + (elementCount * ELEMENT_SIZE)); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void writeTo0(DexFile file, AnnotatedOutput out) { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean annotates = out.annotates(); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fieldsSize = listSize(fieldAnnotations); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int methodsSize = listSize(methodAnnotations); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parametersSize = listSize(parameterAnnotations); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, offsetString() + " annotations directory"); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " class_annotations_off: " + Hex.u4(classOff)); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " fields_size: " + 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u4(fieldsSize)); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " methods_size: " + 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u4(methodsSize)); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(4, " parameters_size: " + 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u4(parametersSize)); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(classOff); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(fieldsSize); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(methodsSize); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeInt(parametersSize); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldsSize != 0) { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(fieldAnnotations); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " fields:"); 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (FieldAnnotationStruct item : fieldAnnotations) { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.writeTo(file, out); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodsSize != 0) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(methodAnnotations); 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " methods:"); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (MethodAnnotationStruct item : methodAnnotations) { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.writeTo(file, out); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parametersSize != 0) { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collections.sort(parameterAnnotations); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annotates) { 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, " parameters:"); 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ParameterAnnotationStruct item : parameterAnnotations) { 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project item.writeTo(file, out); 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 33999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the list size of the given list, or {@code 0} if given 34099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null}. 341de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 34299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param list {@code null-ok;} the list in question 34399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} its size 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static int listSize(ArrayList<?> list) { 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (list == null) { 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return list.size(); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prints out the contents of this instance, in a debugging-friendly 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * way. This is meant to be called from {@link ClassDefItem#debugPrint}. 356de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 35799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to output to 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /*package*/ void debugPrint(PrintWriter out) { 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (classAnnotations != null) { 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" class annotations: " + classAnnotations); 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fieldAnnotations != null) { 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" field annotations:"); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (FieldAnnotationStruct item : fieldAnnotations) { 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" " + item.toHuman()); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodAnnotations != null) { 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" method annotations:"); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (MethodAnnotationStruct item : methodAnnotations) { 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" " + item.toHuman()); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 377de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parameterAnnotations != null) { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" parameter annotations:"); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ParameterAnnotationStruct item : parameterAnnotations) { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(" " + item.toHuman()); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 386