| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.dx.dex.file; |
| |
| import com.android.dx.rop.annotation.Annotations; |
| import com.android.dx.rop.annotation.AnnotationsList; |
| import com.android.dx.rop.cst.CstMethodRef; |
| import com.android.dx.util.AnnotatedOutput; |
| import com.android.dx.util.Hex; |
| import com.android.dx.util.ToHuman; |
| |
| import java.util.ArrayList; |
| |
| /** |
| * Association of a method and its parameter annotations. |
| */ |
| public final class ParameterAnnotationStruct |
| implements ToHuman, Comparable<ParameterAnnotationStruct> { |
| /** {@code non-null;} the method in question */ |
| private final CstMethodRef method; |
| |
| /** {@code non-null;} the associated annotations list */ |
| private final AnnotationsList annotationsList; |
| |
| /** {@code non-null;} the associated annotations list, as an item */ |
| private final UniformListItem<AnnotationSetRefItem> annotationsItem; |
| |
| /** |
| * Constructs an instance. |
| * |
| * @param method {@code non-null;} the method in question |
| * @param annotationsList {@code non-null;} the associated annotations list |
| */ |
| public ParameterAnnotationStruct(CstMethodRef method, |
| AnnotationsList annotationsList) { |
| if (method == null) { |
| throw new NullPointerException("method == null"); |
| } |
| |
| if (annotationsList == null) { |
| throw new NullPointerException("annotationsList == null"); |
| } |
| |
| this.method = method; |
| this.annotationsList = annotationsList; |
| |
| /* |
| * Construct an item for the annotations list. TODO: This |
| * requires way too much copying; fix it. |
| */ |
| |
| int size = annotationsList.size(); |
| ArrayList<AnnotationSetRefItem> arrayList = new |
| ArrayList<AnnotationSetRefItem>(size); |
| |
| for (int i = 0; i < size; i++) { |
| Annotations annotations = annotationsList.get(i); |
| AnnotationSetItem item = new AnnotationSetItem(annotations); |
| arrayList.add(new AnnotationSetRefItem(item)); |
| } |
| |
| this.annotationsItem = new UniformListItem<AnnotationSetRefItem>( |
| ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList); |
| } |
| |
| /** {@inheritDoc} */ |
| public int hashCode() { |
| return method.hashCode(); |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean equals(Object other) { |
| if (! (other instanceof ParameterAnnotationStruct)) { |
| return false; |
| } |
| |
| return method.equals(((ParameterAnnotationStruct) other).method); |
| } |
| |
| /** {@inheritDoc} */ |
| public int compareTo(ParameterAnnotationStruct other) { |
| return method.compareTo(other.method); |
| } |
| |
| /** {@inheritDoc} */ |
| public void addContents(DexFile file) { |
| MethodIdsSection methodIds = file.getMethodIds(); |
| MixedItemSection wordData = file.getWordData(); |
| |
| methodIds.intern(method); |
| wordData.add(annotationsItem); |
| } |
| |
| /** {@inheritDoc} */ |
| public void writeTo(DexFile file, AnnotatedOutput out) { |
| int methodIdx = file.getMethodIds().indexOf(method); |
| int annotationsOff = annotationsItem.getAbsoluteOffset(); |
| |
| if (out.annotates()) { |
| out.annotate(0, " " + method.toHuman()); |
| out.annotate(4, " method_idx: " + Hex.u4(methodIdx)); |
| out.annotate(4, " annotations_off: " + |
| Hex.u4(annotationsOff)); |
| } |
| |
| out.writeInt(methodIdx); |
| out.writeInt(annotationsOff); |
| } |
| |
| /** {@inheritDoc} */ |
| public String toHuman() { |
| StringBuilder sb = new StringBuilder(); |
| |
| sb.append(method.toHuman()); |
| sb.append(": "); |
| |
| boolean first = true; |
| for (AnnotationSetRefItem item : annotationsItem.getItems()) { |
| if (first) { |
| first = false; |
| } else { |
| sb.append(", "); |
| } |
| sb.append(item.toHuman()); |
| } |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * Gets the method this item is for. |
| * |
| * @return {@code non-null;} the method |
| */ |
| public CstMethodRef getMethod() { |
| return method; |
| } |
| |
| /** |
| * Gets the associated annotations list. |
| * |
| * @return {@code non-null;} the annotations list |
| */ |
| public AnnotationsList getAnnotationsList() { |
| return annotationsList; |
| } |
| } |