1f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project/* 2f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 3f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 4f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * you may not use this file except in compliance with the License. 6f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * You may obtain a copy of the License at 7f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 8f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * 10f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * See the License for the specific language governing permissions and 14f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project * limitations under the License. 15f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project */ 16f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 17f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectpackage dex.reader; 18f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 19f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.lang.reflect.Modifier; 20f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.HashMap; 21f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.HashSet; 22f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.LinkedList; 23f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.List; 24f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.Map; 25f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport java.util.Set; 26f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 27f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexClassImpl.MethodAnnotation; 28f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexClassImpl.ParameterAnnotation; 29f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexFileReader.FieldIdItem; 30f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexFileReader.MethodsIdItem; 31f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.reader.DexFileReader.ProtIdItem; 32f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.structure.DexAnnotation; 33f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.structure.DexClass; 34f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.structure.DexMethod; 35f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Projectimport dex.structure.DexParameter; 36f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 37f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project/* package */final class DexMethodImpl implements DexMethod { 38f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 39f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private DexBuffer buffer; 40f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private MethodsIdItem methodsIdItem; 41f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private String[] stringPool; 42f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private int[] typeIds; 43f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private ProtIdItem protoIdItem; 44f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private List<DexParameter> parameters; 45f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final int accessFlags; 46f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final MethodAnnotation methodAnnotation; 47f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private Set<DexAnnotation> annotations; 48f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final TypeFormatter formatter = new TypeFormatter(); 49f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final DexClass declaringClass; 50f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final ParameterAnnotation parameterAnnotation; 51f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private Map<Integer, Integer> parameterIdToIndex; 52f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private final FieldIdItem[] fieldIdItems; 53f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 54f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public DexMethodImpl(DexBuffer buffer, DexClass declaringClass, 55f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project MethodsIdItem methodsIdItem, ProtIdItem protoIdItem, 56f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project int accessFlags, MethodAnnotation methodAnnotation, 57f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project ParameterAnnotation parameterAnnotation, String[] stringPool, 58f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project int[] typeIds, FieldIdItem[] fieldIdItems) { 59f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.buffer = buffer; 60f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.declaringClass = declaringClass; 61f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.methodsIdItem = methodsIdItem; 62f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.protoIdItem = protoIdItem; 63f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.accessFlags = accessFlags; 64f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.methodAnnotation = methodAnnotation; 65f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.parameterAnnotation = parameterAnnotation; 66f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.stringPool = stringPool; 67f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.typeIds = typeIds; 68f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project this.fieldIdItems = fieldIdItems; 69f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parseAnnotations(); 70f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parseParameterAnnotations(); 71f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 72f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 73f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private void parseParameterAnnotations() { 74f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parameterIdToIndex = new HashMap<Integer, Integer>(); 75f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if (parameterAnnotation != null) { 76f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project buffer.setPosition(parameterAnnotation.annotationsOff); 77f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project int numberOfParameters = buffer.readUInt(); 78f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (int i = 0; i < numberOfParameters; i++) { 79f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parameterIdToIndex.put(i, buffer.readUInt()); 80f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 81f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 82f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 83f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 84f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project private void parseAnnotations() { 85f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project annotations = new HashSet<DexAnnotation>(); 86f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if (methodAnnotation != null) { 87f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project buffer.setPosition(methodAnnotation.annotationsOff); 88f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project final int size = buffer.readUInt(); 89f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (int i = 0; i < size; i++) { 90f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project annotations.add(new DexAnnotationImpl(buffer.createCopy(), 91f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project buffer.readUInt(), typeIds, stringPool, fieldIdItems)); 92f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 93f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 94f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 95f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 96f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public String getName() { 97f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return stringPool[methodsIdItem.name_idx]; 98f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 99f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 100f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public String getReturnType() { 101f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return stringPool[typeIds[protoIdItem.return_type_idx]]; 102f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 103f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 104f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public synchronized List<DexParameter> getParameters() { 105f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if (parameters == null) { 106f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parameters = new LinkedList<DexParameter>(); 107f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project if (protoIdItem.parameter_off != 0) { 108f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 109f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project buffer.setPosition(protoIdItem.parameter_off); 110f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project int size = buffer.readUInt(); 111f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 112f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project int[] paramTypeIdx = new int[size]; 113f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (int i = 0; i < size; i++) { 114f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project paramTypeIdx[i] = buffer.readUShort(); 115f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 116f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (int i = 0; i < paramTypeIdx.length; i++) { 117f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parameters.add(new DexParameterImpl(buffer.createCopy(), 118f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project stringPool[typeIds[paramTypeIdx[i]]], 119f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project parameterIdToIndex.get(i), typeIds, stringPool, 120f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project fieldIdItems)); 121f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 122f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 123f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 124f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return parameters; 125f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 126f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 127f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public int getModifiers() { 128f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return accessFlags; 129f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 130f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 131f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public Set<DexAnnotation> getAnnotations() { 132f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return annotations; 133f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 134f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 135f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public DexClass getDeclaringClass() { 136f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return declaringClass; 137f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 138f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project 139f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project @Override 140f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project public String toString() { 141f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project StringBuilder builder = new StringBuilder(); 142f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(formatter.formatAnnotations(getAnnotations())); 143f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(Modifier.toString(getModifiers())); 144f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(" "); 145f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(formatter.format(getReturnType())); 146f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(" "); 147f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(getName()); 148f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append("("); 149f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project List<DexParameter> parameters = getParameters(); 150f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project for (DexParameter dexParameter : parameters) { 151f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(formatter.formatAnnotations(dexParameter 152f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project .getAnnotations())); 153f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(formatter.format(dexParameter.getTypeName())); 154f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 155f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project builder.append(")"); 156f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project return builder.toString(); 157f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project } 158f8057104af9cae031b544e971a52adafa7c0d9eThe Android Open Source Project} 159