1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2011 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.google.dexmaker; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstMethodRef; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstNat; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstString; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.Prototype; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.List; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 2623abc2fe89ec3713645d64bdb74415a9090084f4Jesse Wilson * Identifies a method or constructor. 273e7a2230ec75b59ae9b4aad292f51df2542ced7dJesse Wilson * 283e7a2230ec75b59ae9b4aad292f51df2542ced7dJesse Wilson * @param <D> the type declaring this field 293e7a2230ec75b59ae9b4aad292f51df2542ced7dJesse Wilson * @param <R> the return type of this method 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class MethodId<D, R> { 320e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson final TypeId<D> declaringType; 330e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson final TypeId<R> returnType; 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson final String name; 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson final TypeList parameters; 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** cached converted state */ 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson final CstNat nat; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson final CstMethodRef constant; 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 410e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson MethodId(TypeId<D> declaringType, TypeId<R> returnType, String name, TypeList parameters) { 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (declaringType == null || returnType == null || name == null || parameters == null) { 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException(); 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.declaringType = declaringType; 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.returnType = returnType; 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.name = name; 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.parameters = parameters; 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.nat = new CstNat(new CstString(name), new CstString(descriptor(false))); 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.constant = new CstMethodRef(declaringType.constant, nat); 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 530e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson public TypeId<D> getDeclaringType() { 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return declaringType; 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 570e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson public TypeId<R> getReturnType() { 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return returnType; 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 6123abc2fe89ec3713645d64bdb74415a9090084f4Jesse Wilson /** 62c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson * Returns true if this method is a constructor for its declaring class. 63c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson */ 64c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson public boolean isConstructor() { 65c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson return name.equals("<init>"); 66c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson } 67c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson 68c0271e9981ddd85a13ed88defd0b5b1a5ccc6f46Jesse Wilson /** 6923abc2fe89ec3713645d64bdb74415a9090084f4Jesse Wilson * Returns the method's name. This is "<init>" if this is a constructor. 7023abc2fe89ec3713645d64bdb74415a9090084f4Jesse Wilson */ 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getName() { 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return name; 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 750e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson public List<TypeId<?>> getParameters() { 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return parameters.asList(); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a descriptor like "(Ljava/lang/Class;[I)Ljava/lang/Object;". 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String descriptor(boolean includeThis) { 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson StringBuilder result = new StringBuilder(); 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.append("("); 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (includeThis) { 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.append(declaringType.name); 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 880e49fb9243b7463835ab80ef7cc62435f55846ceJesse Wilson for (TypeId t : parameters.types) { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.append(t.name); 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.append(")"); 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.append(returnType.name); 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result.toString(); 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Prototype prototype(boolean includeThis) { 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return Prototype.intern(descriptor(includeThis)); 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override public boolean equals(Object o) { 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return o instanceof MethodId 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson && ((MethodId<?, ?>) o).declaringType.equals(declaringType) 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson && ((MethodId<?, ?>) o).name.equals(name) 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson && ((MethodId<?, ?>) o).parameters.equals(parameters) 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson && ((MethodId<?, ?>) o).returnType.equals(returnType); 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override public int hashCode() { 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int result = 17; 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = 31 * result + declaringType.hashCode(); 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = 31 * result + name.hashCode(); 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = 31 * result + parameters.hashCode(); 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = 31 * result + returnType.hashCode(); 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override public String toString() { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return declaringType + "." + name + "(" + parameters + ")"; 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 121