1 /* 2 * Copyright (C) 2007 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.dexgen.rop.cst; 18 19 import com.android.dexgen.rop.type.Prototype; 20 import com.android.dexgen.rop.type.Type; 21 import com.android.dexgen.rop.type.TypeBearer; 22 23 /** 24 * Base class for constants of "methodish" type. 25 * 26 * <p><b>Note:</b> As a {@link TypeBearer}, this class bears the return type 27 * of the method.</p> 28 */ 29 public abstract class CstBaseMethodRef 30 extends CstMemberRef { 31 /** {@code non-null;} the raw prototype for this method */ 32 private final Prototype prototype; 33 34 /** 35 * {@code null-ok;} the prototype for this method taken to be an instance 36 * method, or {@code null} if not yet calculated 37 */ 38 private Prototype instancePrototype; 39 40 /** 41 * Constructs an instance. 42 * 43 * @param definingClass {@code non-null;} the type of the defining class 44 * @param nat {@code non-null;} the name-and-type 45 */ CstBaseMethodRef(CstType definingClass, CstNat nat)46 /*package*/ CstBaseMethodRef(CstType definingClass, CstNat nat) { 47 super(definingClass, nat); 48 49 String descriptor = getNat().getDescriptor().getString(); 50 this.prototype = Prototype.intern(descriptor); 51 this.instancePrototype = null; 52 } 53 54 /** 55 * Gets the raw prototype of this method. This doesn't include a 56 * {@code this} argument. 57 * 58 * @return {@code non-null;} the method prototype 59 */ getPrototype()60 public final Prototype getPrototype() { 61 return prototype; 62 } 63 64 /** 65 * Gets the prototype of this method as either a 66 * {@code static} or instance method. In the case of a 67 * {@code static} method, this is the same as the raw 68 * prototype. In the case of an instance method, this has an 69 * appropriately-typed {@code this} argument as the first 70 * one. 71 * 72 * @param isStatic whether the method should be considered static 73 * @return {@code non-null;} the method prototype 74 */ getPrototype(boolean isStatic)75 public final Prototype getPrototype(boolean isStatic) { 76 if (isStatic) { 77 return prototype; 78 } else { 79 if (instancePrototype == null) { 80 Type thisType = getDefiningClass().getClassType(); 81 instancePrototype = prototype.withFirstParameter(thisType); 82 } 83 return instancePrototype; 84 } 85 } 86 87 /** {@inheritDoc} */ 88 @Override compareTo0(Constant other)89 protected final int compareTo0(Constant other) { 90 int cmp = super.compareTo0(other); 91 92 if (cmp != 0) { 93 return cmp; 94 } 95 96 CstBaseMethodRef otherMethod = (CstBaseMethodRef) other; 97 return prototype.compareTo(otherMethod.prototype); 98 } 99 100 /** 101 * {@inheritDoc} 102 * 103 * In this case, this method returns the <i>return type</i> of this method. 104 * 105 * @return {@code non-null;} the method's return type 106 */ getType()107 public final Type getType() { 108 return prototype.getReturnType(); 109 } 110 111 /** 112 * Gets the number of words of parameters required by this 113 * method's descriptor. Since instances of this class have no way 114 * to know if they will be used in a {@code static} or 115 * instance context, one has to indicate this explicitly as an 116 * argument. This method is just a convenient shorthand for 117 * {@code getPrototype().getParameterTypes().getWordCount()}, 118 * plus {@code 1} if the method is to be treated as an 119 * instance method. 120 * 121 * @param isStatic whether the method should be considered static 122 * @return {@code >= 0;} the argument word count 123 */ getParameterWordCount(boolean isStatic)124 public final int getParameterWordCount(boolean isStatic) { 125 return getPrototype(isStatic).getParameterTypes().getWordCount(); 126 } 127 128 /** 129 * Gets whether this is a reference to an instance initialization 130 * method. This is just a convenient shorthand for 131 * {@code getNat().isInstanceInit()}. 132 * 133 * @return {@code true} iff this is a reference to an 134 * instance initialization method 135 */ isInstanceInit()136 public final boolean isInstanceInit() { 137 return getNat().isInstanceInit(); 138 } 139 140 /** 141 * Gets whether this is a reference to a class initialization 142 * method. This is just a convenient shorthand for 143 * {@code getNat().isClassInit()}. 144 * 145 * @return {@code true} iff this is a reference to an 146 * instance initialization method 147 */ isClassInit()148 public final boolean isClassInit() { 149 return getNat().isClassInit(); 150 } 151 } 152