1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2008 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.file; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.annotation.Annotations; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.annotation.AnnotationsList; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstFieldRef; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstMethodRef; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.AnnotatedOutput; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Hex; 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.PrintWriter; 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.ArrayList; 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.Collections; 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Per-class directory of annotations. 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class AnnotationsDirectoryItem extends OffsettedItem { 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** the required alignment for instances of this class */ 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int ALIGNMENT = 4; 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** write size of this class's header, in bytes */ 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int HEADER_SIZE = 16; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** write size of a list element, in bytes */ 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int ELEMENT_SIZE = 8; 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code null-ok;} the class-level annotations, if any */ 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private AnnotationSetItem classAnnotations; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code null-ok;} the annotated fields, if any */ 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<FieldAnnotationStruct> fieldAnnotations; 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code null-ok;} the annotated methods, if any */ 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<MethodAnnotationStruct> methodAnnotations; 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code null-ok;} the annotated parameters, if any */ 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<ParameterAnnotationStruct> parameterAnnotations; 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an empty instance. 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public AnnotationsDirectoryItem() { 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(ALIGNMENT, -1); 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson classAnnotations = null; 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fieldAnnotations = null; 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson methodAnnotations = null; 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson parameterAnnotations = null; 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ItemType itemType() { 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM; 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether this item is empty (has no contents). 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} if this item is empty, or {@code false} 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * if not 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isEmpty() { 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (classAnnotations == null) && 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (fieldAnnotations == null) && 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (methodAnnotations == null) && 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (parameterAnnotations == null); 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether this item is a candidate for interning. The only 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * interning candidates are ones that <i>only</i> have a non-null 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * set of class annotations, with no other lists. 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} if this is an interning candidate, or 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code false} if not 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isInternable() { 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (classAnnotations != null) && 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (fieldAnnotations == null) && 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (methodAnnotations == null) && 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (parameterAnnotations == null); 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int hashCode() { 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (classAnnotations == null) { 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 0; 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return classAnnotations.hashCode(); 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@inheritDoc} 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * <p><b>Note:</b>: This throws an exception if this item is not 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * internable.</p> 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #isInternable 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int compareTo0(OffsettedItem other) { 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (! isInternable()) { 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException("uninternable instance"); 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson AnnotationsDirectoryItem otherDirectory = 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (AnnotationsDirectoryItem) other; 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return classAnnotations.compareTo(otherDirectory.classAnnotations); 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the direct annotations on this instance. These are annotations 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * made on the class, per se, as opposed to on one of its members. 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * It is only valid to call this method at most once per instance. 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param annotations {@code non-null;} annotations to set for this class 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void setClassAnnotations(Annotations annotations) { 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (annotations == null) { 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("annotations == null"); 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (classAnnotations != null) { 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException( 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "class annotations already set"); 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson classAnnotations = new AnnotationSetItem(annotations); 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds a field annotations item to this instance. 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param field {@code non-null;} field in question 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param annotations {@code non-null;} associated annotations to add 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addFieldAnnotations(CstFieldRef field, 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Annotations annotations) { 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fieldAnnotations == null) { 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fieldAnnotations = new ArrayList<FieldAnnotationStruct>(); 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fieldAnnotations.add(new FieldAnnotationStruct(field, 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson new AnnotationSetItem(annotations))); 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds a method annotations item to this instance. 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param method {@code non-null;} method in question 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param annotations {@code non-null;} associated annotations to add 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addMethodAnnotations(CstMethodRef method, 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Annotations annotations) { 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (methodAnnotations == null) { 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson methodAnnotations = new ArrayList<MethodAnnotationStruct>(); 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson methodAnnotations.add(new MethodAnnotationStruct(method, 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson new AnnotationSetItem(annotations))); 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds a parameter annotations item to this instance. 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param method {@code non-null;} method in question 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param list {@code non-null;} associated list of annotation sets to add 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addParameterAnnotations(CstMethodRef method, 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson AnnotationsList list) { 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (parameterAnnotations == null) { 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson parameterAnnotations = new ArrayList<ParameterAnnotationStruct>(); 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson parameterAnnotations.add(new ParameterAnnotationStruct(method, list)); 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the method annotations for a given method, if any. This is 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * meant for use by debugging / dumping code. 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param method {@code non-null;} the method 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code null-ok;} the method annotations, if any 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Annotations getMethodAnnotations(CstMethodRef method) { 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (methodAnnotations == null) { 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (MethodAnnotationStruct item : methodAnnotations) { 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (item.getMethod().equals(method)) { 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return item.getAnnotations(); 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the parameter annotations for a given method, if any. This is 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * meant for use by debugging / dumping code. 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param method {@code non-null;} the method 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code null-ok;} the parameter annotations, if any 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public AnnotationsList getParameterAnnotations(CstMethodRef method) { 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (parameterAnnotations == null) { 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (ParameterAnnotationStruct item : parameterAnnotations) { 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (item.getMethod().equals(method)) { 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return item.getAnnotationsList(); 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addContents(DexFile file) { 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson MixedItemSection wordData = file.getWordData(); 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (classAnnotations != null) { 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson classAnnotations = wordData.intern(classAnnotations); 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fieldAnnotations != null) { 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (FieldAnnotationStruct item : fieldAnnotations) { 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.addContents(file); 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (methodAnnotations != null) { 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (MethodAnnotationStruct item : methodAnnotations) { 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.addContents(file); 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (parameterAnnotations != null) { 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (ParameterAnnotationStruct item : parameterAnnotations) { 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.addContents(file); 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toHuman() { 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("unsupported"); 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected void place0(Section addedTo, int offset) { 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // We just need to set the write size here. 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int elementCount = listSize(fieldAnnotations) 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson + listSize(methodAnnotations) + listSize(parameterAnnotations); 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson setWriteSize(HEADER_SIZE + (elementCount * ELEMENT_SIZE)); 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected void writeTo0(DexFile file, AnnotatedOutput out) { 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean annotates = out.annotates(); 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations); 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int fieldsSize = listSize(fieldAnnotations); 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int methodsSize = listSize(methodAnnotations); 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int parametersSize = listSize(parameterAnnotations); 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (annotates) { 292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, offsetString() + " annotations directory"); 293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " class_annotations_off: " + Hex.u4(classOff)); 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " fields_size: " + 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Hex.u4(fieldsSize)); 296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " methods_size: " + 297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Hex.u4(methodsSize)); 298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " parameters_size: " + 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Hex.u4(parametersSize)); 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(classOff); 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(fieldsSize); 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(methodsSize); 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(parametersSize); 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fieldsSize != 0) { 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Collections.sort(fieldAnnotations); 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (annotates) { 310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, " fields:"); 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (FieldAnnotationStruct item : fieldAnnotations) { 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.writeTo(file, out); 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (methodsSize != 0) { 318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Collections.sort(methodAnnotations); 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (annotates) { 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, " methods:"); 321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (MethodAnnotationStruct item : methodAnnotations) { 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.writeTo(file, out); 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (parametersSize != 0) { 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Collections.sort(parameterAnnotations); 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (annotates) { 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, " parameters:"); 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (ParameterAnnotationStruct item : parameterAnnotations) { 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson item.writeTo(file, out); 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the list size of the given list, or {@code 0} if given 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null}. 341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param list {@code null-ok;} the list in question 343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} its size 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static int listSize(ArrayList<?> list) { 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (list == null) { 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 0; 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return list.size(); 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Prints out the contents of this instance, in a debugging-friendly 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * way. This is meant to be called from {@link ClassDefItem#debugPrint}. 356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to output to 358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /*package*/ void debugPrint(PrintWriter out) { 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (classAnnotations != null) { 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" class annotations: " + classAnnotations); 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fieldAnnotations != null) { 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" field annotations:"); 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (FieldAnnotationStruct item : fieldAnnotations) { 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" " + item.toHuman()); 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (methodAnnotations != null) { 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" method annotations:"); 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (MethodAnnotationStruct item : methodAnnotations) { 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" " + item.toHuman()); 375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (parameterAnnotations != null) { 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" parameter annotations:"); 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (ParameterAnnotationStruct item : parameterAnnotations) { 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(" " + item.toHuman()); 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 386