/* * 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.Type; /** * Constants of type {@code CONSTANT_NameAndType_info}. */ public final class CstNat extends Constant { /** * {@code non-null;} the instance for name {@code TYPE} and descriptor * {@code java.lang.Class}, which is useful when dealing with * wrapped primitives */ public static final CstNat PRIMITIVE_TYPE_NAT = new CstNat(new CstUtf8("TYPE"), new CstUtf8("Ljava/lang/Class;")); /** {@code non-null;} the name */ private final CstUtf8 name; /** {@code non-null;} the descriptor (type) */ private final CstUtf8 descriptor; /** * Constructs an instance. * * @param name {@code non-null;} the name * @param descriptor {@code non-null;} the descriptor */ public CstNat(CstUtf8 name, CstUtf8 descriptor) { if (name == null) { throw new NullPointerException("name == null"); } if (descriptor == null) { throw new NullPointerException("descriptor == null"); } this.name = name; this.descriptor = descriptor; } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (!(other instanceof CstNat)) { return false; } CstNat otherNat = (CstNat) other; return name.equals(otherNat.name) && descriptor.equals(otherNat.descriptor); } /** {@inheritDoc} */ @Override public int hashCode() { return (name.hashCode() * 31) ^ descriptor.hashCode(); } /** {@inheritDoc} */ @Override protected int compareTo0(Constant other) { CstNat otherNat = (CstNat) other; int cmp = name.compareTo(otherNat.name); if (cmp != 0) { return cmp; } return descriptor.compareTo(otherNat.descriptor); } /** {@inheritDoc} */ @Override public String toString() { return "nat{" + toHuman() + '}'; } /** {@inheritDoc} */ @Override public String typeName() { return "nat"; } /** {@inheritDoc} */ @Override public boolean isCategory2() { return false; } /** * Gets the name. * * @return {@code non-null;} the name */ public CstUtf8 getName() { return name; } /** * Gets the descriptor. * * @return {@code non-null;} the descriptor */ public CstUtf8 getDescriptor() { return descriptor; } /** * Returns an unadorned but human-readable version of the name-and-type * value. * * @return {@code non-null;} the human form */ public String toHuman() { return name.toHuman() + ':' + descriptor.toHuman(); } /** * Gets the field type corresponding to this instance's descriptor. * This method is only valid to call if the descriptor in fact describes * a field (and not a method). * * @return {@code non-null;} the field type */ public Type getFieldType() { return Type.intern(descriptor.getString()); } /** * Gets whether this instance has the name of a standard instance * initialization method. This is just a convenient shorthand for * {@code getName().getString().equals("<init>")}. * * @return {@code true} iff this is a reference to an * instance initialization method */ public final boolean isInstanceInit() { return name.getString().equals("<init>"); } /** * Gets whether this instance has the name of a standard class * initialization method. This is just a convenient shorthand for * {@code getName().getString().equals("<clinit>")}. * * @return {@code true} iff this is a reference to an * instance initialization method */ public final boolean isClassInit() { return name.getString().equals("<clinit>"); } }