• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 package com.android.dx.dex.file;
18 
19 import com.android.dx.rop.annotation.Annotations;
20 import com.android.dx.rop.annotation.AnnotationsList;
21 import com.android.dx.rop.cst.CstMethodRef;
22 import com.android.dx.util.AnnotatedOutput;
23 import com.android.dx.util.Hex;
24 import com.android.dx.util.ToHuman;
25 import java.util.ArrayList;
26 
27 /**
28  * Association of a method and its parameter annotations.
29  */
30 public final class ParameterAnnotationStruct
31         implements ToHuman, Comparable<ParameterAnnotationStruct> {
32     /** {@code non-null;} the method in question */
33     private final CstMethodRef method;
34 
35     /** {@code non-null;} the associated annotations list */
36     private final AnnotationsList annotationsList;
37 
38     /** {@code non-null;} the associated annotations list, as an item */
39     private final UniformListItem<AnnotationSetRefItem> annotationsItem;
40 
41     /**
42      * Constructs an instance.
43      *
44      * @param method {@code non-null;} the method in question
45      * @param annotationsList {@code non-null;} the associated annotations list
46      * @param dexFile {@code non-null;} dex output
47      */
ParameterAnnotationStruct(CstMethodRef method, AnnotationsList annotationsList, DexFile dexFile)48     public ParameterAnnotationStruct(CstMethodRef method,
49             AnnotationsList annotationsList, DexFile dexFile) {
50         if (method == null) {
51             throw new NullPointerException("method == null");
52         }
53 
54         if (annotationsList == null) {
55             throw new NullPointerException("annotationsList == null");
56         }
57 
58         this.method = method;
59         this.annotationsList = annotationsList;
60 
61         /*
62          * Construct an item for the annotations list. TODO: This
63          * requires way too much copying; fix it.
64          */
65 
66         int size = annotationsList.size();
67         ArrayList<AnnotationSetRefItem> arrayList = new
68             ArrayList<AnnotationSetRefItem>(size);
69 
70         for (int i = 0; i < size; i++) {
71             Annotations annotations = annotationsList.get(i);
72             AnnotationSetItem item = new AnnotationSetItem(annotations, dexFile);
73             arrayList.add(new AnnotationSetRefItem(item));
74         }
75 
76         this.annotationsItem = new UniformListItem<AnnotationSetRefItem>(
77                 ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList);
78     }
79 
80     /** {@inheritDoc} */
81     @Override
hashCode()82     public int hashCode() {
83         return method.hashCode();
84     }
85 
86     /** {@inheritDoc} */
87     @Override
equals(Object other)88     public boolean equals(Object other) {
89         if (! (other instanceof ParameterAnnotationStruct)) {
90             return false;
91         }
92 
93         return method.equals(((ParameterAnnotationStruct) other).method);
94     }
95 
96     /** {@inheritDoc} */
97     @Override
compareTo(ParameterAnnotationStruct other)98     public int compareTo(ParameterAnnotationStruct other) {
99         return method.compareTo(other.method);
100     }
101 
102     /** {@inheritDoc} */
addContents(DexFile file)103     public void addContents(DexFile file) {
104         MethodIdsSection methodIds = file.getMethodIds();
105         MixedItemSection wordData = file.getWordData();
106 
107         methodIds.intern(method);
108         wordData.add(annotationsItem);
109     }
110 
111     /** {@inheritDoc} */
writeTo(DexFile file, AnnotatedOutput out)112     public void writeTo(DexFile file, AnnotatedOutput out) {
113         int methodIdx = file.getMethodIds().indexOf(method);
114         int annotationsOff = annotationsItem.getAbsoluteOffset();
115 
116         if (out.annotates()) {
117             out.annotate(0, "    " + method.toHuman());
118             out.annotate(4, "      method_idx:      " + Hex.u4(methodIdx));
119             out.annotate(4, "      annotations_off: " +
120                     Hex.u4(annotationsOff));
121         }
122 
123         out.writeInt(methodIdx);
124         out.writeInt(annotationsOff);
125     }
126 
127     /** {@inheritDoc} */
128     @Override
toHuman()129     public String toHuman() {
130         StringBuilder sb = new StringBuilder();
131 
132         sb.append(method.toHuman());
133         sb.append(": ");
134 
135         boolean first = true;
136         for (AnnotationSetRefItem item : annotationsItem.getItems()) {
137             if (first) {
138                 first = false;
139             } else {
140                 sb.append(", ");
141             }
142             sb.append(item.toHuman());
143         }
144 
145         return sb.toString();
146     }
147 
148     /**
149      * Gets the method this item is for.
150      *
151      * @return {@code non-null;} the method
152      */
getMethod()153     public CstMethodRef getMethod() {
154         return method;
155     }
156 
157     /**
158      * Gets the associated annotations list.
159      *
160      * @return {@code non-null;} the annotations list
161      */
getAnnotationsList()162     public AnnotationsList getAnnotationsList() {
163         return annotationsList;
164     }
165 }
166