| /* |
| * Copyright (C) 2007 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.rop.cst; |
| |
| import com.android.dx.rop.type.Prototype; |
| import com.android.dx.rop.type.Type; |
| import com.android.dx.rop.type.TypeBearer; |
| |
| /** |
| * Base class for constants of "methodish" type. |
| * |
| * <p><b>Note:</b> As a {@link TypeBearer}, this class bears the return type |
| * of the method.</p> |
| */ |
| public abstract class CstBaseMethodRef |
| extends CstMemberRef { |
| /** {@code non-null;} the raw prototype for this method */ |
| private final Prototype prototype; |
| |
| /** |
| * {@code null-ok;} the prototype for this method taken to be an instance |
| * method, or {@code null} if not yet calculated |
| */ |
| private Prototype instancePrototype; |
| |
| /** |
| * Constructs an instance. |
| * |
| * @param definingClass {@code non-null;} the type of the defining class |
| * @param nat {@code non-null;} the name-and-type |
| */ |
| /*package*/ CstBaseMethodRef(CstType definingClass, CstNat nat) { |
| super(definingClass, nat); |
| |
| String descriptor = getNat().getDescriptor().getString(); |
| this.prototype = Prototype.intern(descriptor); |
| this.instancePrototype = null; |
| } |
| |
| /** |
| * Gets the raw prototype of this method. This doesn't include a |
| * {@code this} argument. |
| * |
| * @return {@code non-null;} the method prototype |
| */ |
| public final Prototype getPrototype() { |
| return prototype; |
| } |
| |
| /** |
| * Gets the prototype of this method as either a |
| * {@code static} or instance method. In the case of a |
| * {@code static} method, this is the same as the raw |
| * prototype. In the case of an instance method, this has an |
| * appropriately-typed {@code this} argument as the first |
| * one. |
| * |
| * @param isStatic whether the method should be considered static |
| * @return {@code non-null;} the method prototype |
| */ |
| public final Prototype getPrototype(boolean isStatic) { |
| if (isStatic) { |
| return prototype; |
| } else { |
| if (instancePrototype == null) { |
| Type thisType = getDefiningClass().getClassType(); |
| instancePrototype = prototype.withFirstParameter(thisType); |
| } |
| return instancePrototype; |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| protected final int compareTo0(Constant other) { |
| int cmp = super.compareTo0(other); |
| |
| if (cmp != 0) { |
| return cmp; |
| } |
| |
| CstBaseMethodRef otherMethod = (CstBaseMethodRef) other; |
| return prototype.compareTo(otherMethod.prototype); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * In this case, this method returns the <i>return type</i> of this method. |
| * |
| * @return {@code non-null;} the method's return type |
| */ |
| public final Type getType() { |
| return prototype.getReturnType(); |
| } |
| |
| /** |
| * Gets the number of words of parameters required by this |
| * method's descriptor. Since instances of this class have no way |
| * to know if they will be used in a {@code static} or |
| * instance context, one has to indicate this explicitly as an |
| * argument. This method is just a convenient shorthand for |
| * {@code getPrototype().getParameterTypes().getWordCount()}, |
| * plus {@code 1} if the method is to be treated as an |
| * instance method. |
| * |
| * @param isStatic whether the method should be considered static |
| * @return {@code >= 0;} the argument word count |
| */ |
| public final int getParameterWordCount(boolean isStatic) { |
| return getPrototype(isStatic).getParameterTypes().getWordCount(); |
| } |
| |
| /** |
| * Gets whether this is a reference to an instance initialization |
| * method. This is just a convenient shorthand for |
| * {@code getNat().isInstanceInit()}. |
| * |
| * @return {@code true} iff this is a reference to an |
| * instance initialization method |
| */ |
| public final boolean isInstanceInit() { |
| return getNat().isInstanceInit(); |
| } |
| |
| /** |
| * Gets whether this is a reference to a class initialization |
| * method. This is just a convenient shorthand for |
| * {@code getNat().isClassInit()}. |
| * |
| * @return {@code true} iff this is a reference to an |
| * instance initialization method |
| */ |
| public final boolean isClassInit() { |
| return getNat().isClassInit(); |
| } |
| } |