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 17package com.android.dexgen.rop.cst; 18 19import com.android.dexgen.rop.type.Type; 20 21/** 22 * Constants of type {@code CONSTANT_NameAndType_info}. 23 */ 24public final class CstNat extends Constant { 25 /** 26 * {@code non-null;} the instance for name {@code TYPE} and descriptor 27 * {@code java.lang.Class}, which is useful when dealing with 28 * wrapped primitives 29 */ 30 public static final CstNat PRIMITIVE_TYPE_NAT = 31 new CstNat(new CstUtf8("TYPE"), 32 new CstUtf8("Ljava/lang/Class;")); 33 34 /** {@code non-null;} the name */ 35 private final CstUtf8 name; 36 37 /** {@code non-null;} the descriptor (type) */ 38 private final CstUtf8 descriptor; 39 40 /** 41 * Constructs an instance. 42 * 43 * @param name {@code non-null;} the name 44 * @param descriptor {@code non-null;} the descriptor 45 */ 46 public CstNat(CstUtf8 name, CstUtf8 descriptor) { 47 if (name == null) { 48 throw new NullPointerException("name == null"); 49 } 50 51 if (descriptor == null) { 52 throw new NullPointerException("descriptor == null"); 53 } 54 55 this.name = name; 56 this.descriptor = descriptor; 57 } 58 59 /** {@inheritDoc} */ 60 @Override 61 public boolean equals(Object other) { 62 if (!(other instanceof CstNat)) { 63 return false; 64 } 65 66 CstNat otherNat = (CstNat) other; 67 return name.equals(otherNat.name) && 68 descriptor.equals(otherNat.descriptor); 69 } 70 71 /** {@inheritDoc} */ 72 @Override 73 public int hashCode() { 74 return (name.hashCode() * 31) ^ descriptor.hashCode(); 75 } 76 77 /** {@inheritDoc} */ 78 @Override 79 protected int compareTo0(Constant other) { 80 CstNat otherNat = (CstNat) other; 81 int cmp = name.compareTo(otherNat.name); 82 83 if (cmp != 0) { 84 return cmp; 85 } 86 87 return descriptor.compareTo(otherNat.descriptor); 88 } 89 90 /** {@inheritDoc} */ 91 @Override 92 public String toString() { 93 return "nat{" + toHuman() + '}'; 94 } 95 96 /** {@inheritDoc} */ 97 @Override 98 public String typeName() { 99 return "nat"; 100 } 101 102 /** {@inheritDoc} */ 103 @Override 104 public boolean isCategory2() { 105 return false; 106 } 107 108 /** 109 * Gets the name. 110 * 111 * @return {@code non-null;} the name 112 */ 113 public CstUtf8 getName() { 114 return name; 115 } 116 117 /** 118 * Gets the descriptor. 119 * 120 * @return {@code non-null;} the descriptor 121 */ 122 public CstUtf8 getDescriptor() { 123 return descriptor; 124 } 125 126 /** 127 * Returns an unadorned but human-readable version of the name-and-type 128 * value. 129 * 130 * @return {@code non-null;} the human form 131 */ 132 public String toHuman() { 133 return name.toHuman() + ':' + descriptor.toHuman(); 134 } 135 136 /** 137 * Gets the field type corresponding to this instance's descriptor. 138 * This method is only valid to call if the descriptor in fact describes 139 * a field (and not a method). 140 * 141 * @return {@code non-null;} the field type 142 */ 143 public Type getFieldType() { 144 return Type.intern(descriptor.getString()); 145 } 146 147 /** 148 * Gets whether this instance has the name of a standard instance 149 * initialization method. This is just a convenient shorthand for 150 * {@code getName().getString().equals("<init>")}. 151 * 152 * @return {@code true} iff this is a reference to an 153 * instance initialization method 154 */ 155 public final boolean isInstanceInit() { 156 return name.getString().equals("<init>"); 157 } 158 159 /** 160 * Gets whether this instance has the name of a standard class 161 * initialization method. This is just a convenient shorthand for 162 * {@code getName().getString().equals("<clinit>")}. 163 * 164 * @return {@code true} iff this is a reference to an 165 * instance initialization method 166 */ 167 public final boolean isClassInit() { 168 return name.getString().equals("<clinit>"); 169 } 170} 171