1/* 2 * Copyright (C) 2011 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 17package com.google.dexmaker; 18 19import com.android.dx.rop.cst.CstMethodRef; 20import com.android.dx.rop.cst.CstNat; 21import com.android.dx.rop.cst.CstString; 22import com.android.dx.rop.type.Prototype; 23import java.util.List; 24 25/** 26 * Identifies a method or constructor. 27 * 28 * @param <D> the type declaring this field 29 * @param <R> the return type of this method 30 */ 31public final class MethodId<D, R> { 32 final TypeId<D> declaringType; 33 final TypeId<R> returnType; 34 final String name; 35 final TypeList parameters; 36 37 /** cached converted state */ 38 final CstNat nat; 39 final CstMethodRef constant; 40 41 MethodId(TypeId<D> declaringType, TypeId<R> returnType, String name, TypeList parameters) { 42 if (declaringType == null || returnType == null || name == null || parameters == null) { 43 throw new NullPointerException(); 44 } 45 this.declaringType = declaringType; 46 this.returnType = returnType; 47 this.name = name; 48 this.parameters = parameters; 49 this.nat = new CstNat(new CstString(name), new CstString(descriptor(false))); 50 this.constant = new CstMethodRef(declaringType.constant, nat); 51 } 52 53 public TypeId<D> getDeclaringType() { 54 return declaringType; 55 } 56 57 public TypeId<R> getReturnType() { 58 return returnType; 59 } 60 61 /** 62 * Returns true if this method is a constructor for its declaring class. 63 */ 64 public boolean isConstructor() { 65 return name.equals("<init>"); 66 } 67 68 /** 69 * Returns the method's name. This is "<init>" if this is a constructor. 70 */ 71 public String getName() { 72 return name; 73 } 74 75 public List<TypeId<?>> getParameters() { 76 return parameters.asList(); 77 } 78 79 /** 80 * Returns a descriptor like "(Ljava/lang/Class;[I)Ljava/lang/Object;". 81 */ 82 String descriptor(boolean includeThis) { 83 StringBuilder result = new StringBuilder(); 84 result.append("("); 85 if (includeThis) { 86 result.append(declaringType.name); 87 } 88 for (TypeId t : parameters.types) { 89 result.append(t.name); 90 } 91 result.append(")"); 92 result.append(returnType.name); 93 return result.toString(); 94 } 95 96 Prototype prototype(boolean includeThis) { 97 return Prototype.intern(descriptor(includeThis)); 98 } 99 100 @Override public boolean equals(Object o) { 101 return o instanceof MethodId 102 && ((MethodId<?, ?>) o).declaringType.equals(declaringType) 103 && ((MethodId<?, ?>) o).name.equals(name) 104 && ((MethodId<?, ?>) o).parameters.equals(parameters) 105 && ((MethodId<?, ?>) o).returnType.equals(returnType); 106 } 107 108 @Override public int hashCode() { 109 int result = 17; 110 result = 31 * result + declaringType.hashCode(); 111 result = 31 * result + name.hashCode(); 112 result = 31 * result + parameters.hashCode(); 113 result = 31 * result + returnType.hashCode(); 114 return result; 115 } 116 117 @Override public String toString() { 118 return declaringType + "." + name + "(" + parameters + ")"; 119 } 120} 121