1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2008 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.file; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.annotation.Annotations; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.annotation.AnnotationsList; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstMethodRef; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.AnnotatedOutput; 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.Hex; 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.ToHuman; 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.ArrayList; 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Association of a method and its parameter annotations. 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class ParameterAnnotationStruct 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul implements ToHuman, Comparable<ParameterAnnotationStruct> { 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} the method in question */ 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CstMethodRef method; 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} the associated annotations list */ 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final AnnotationsList annotationsList; 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} the associated annotations list, as an item */ 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final UniformListItem<AnnotationSetRefItem> annotationsItem; 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param method {@code non-null;} the method in question 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param annotationsList {@code non-null;} the associated annotations list 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public ParameterAnnotationStruct(CstMethodRef method, 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul AnnotationsList annotationsList) { 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (method == null) { 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("method == null"); 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (annotationsList == null) { 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("annotationsList == null"); 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.method = method; 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.annotationsList = annotationsList; 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Construct an item for the annotations list. TODO: This 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * requires way too much copying; fix it. 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int size = annotationsList.size(); 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ArrayList<AnnotationSetRefItem> arrayList = new 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ArrayList<AnnotationSetRefItem>(size); 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < size; i++) { 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotations annotations = annotationsList.get(i); 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul AnnotationSetItem item = new AnnotationSetItem(annotations); 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul arrayList.add(new AnnotationSetRefItem(item)); 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.annotationsItem = new UniformListItem<AnnotationSetRefItem>( 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList); 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int hashCode() { 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return method.hashCode(); 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean equals(Object other) { 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (! (other instanceof ParameterAnnotationStruct)) { 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return method.equals(((ParameterAnnotationStruct) other).method); 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int compareTo(ParameterAnnotationStruct other) { 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return method.compareTo(other.method); 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void addContents(DexFile file) { 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul MethodIdsSection methodIds = file.getMethodIds(); 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul MixedItemSection wordData = file.getWordData(); 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul methodIds.intern(method); 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul wordData.add(annotationsItem); 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void writeTo(DexFile file, AnnotatedOutput out) { 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int methodIdx = file.getMethodIds().indexOf(method); 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int annotationsOff = annotationsItem.getAbsoluteOffset(); 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (out.annotates()) { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.annotate(0, " " + method.toHuman()); 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.annotate(4, " method_idx: " + Hex.u4(methodIdx)); 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.annotate(4, " annotations_off: " + 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Hex.u4(annotationsOff)); 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.writeInt(methodIdx); 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.writeInt(annotationsOff); 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String toHuman() { 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringBuilder sb = new StringBuilder(); 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(method.toHuman()); 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(": "); 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul boolean first = true; 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (AnnotationSetRefItem item : annotationsItem.getItems()) { 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (first) { 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul first = false; 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else { 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(", "); 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(item.toHuman()); 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return sb.toString(); 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the method this item is for. 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the method 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CstMethodRef getMethod() { 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return method; 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the associated annotations list. 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the annotations list 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public AnnotationsList getAnnotationsList() { 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return annotationsList; 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 162