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.dx.rop.cst; 18 19 import com.android.dx.rop.type.Type; 20 21 /** 22 * Constants of type {@code CONSTANT_NameAndType_info}. 23 */ 24 public 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 CstString("TYPE"), 32 new CstString("Ljava/lang/Class;")); 33 34 /** {@code non-null;} the name */ 35 private final CstString name; 36 37 /** {@code non-null;} the descriptor (type) */ 38 private final CstString 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(CstString name, CstString 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 CstString getName() { 114 return name; 115 } 116 117 /** 118 * Gets the descriptor. 119 * 120 * @return {@code non-null;} the descriptor 121 */ 122 public CstString 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 @Override 133 public String toHuman() { 134 return name.toHuman() + ':' + descriptor.toHuman(); 135 } 136 137 /** 138 * Gets the field type corresponding to this instance's descriptor. 139 * This method is only valid to call if the descriptor in fact describes 140 * a field (and not a method). 141 * 142 * @return {@code non-null;} the field type 143 */ 144 public Type getFieldType() { 145 return Type.intern(descriptor.getString()); 146 } 147 148 /** 149 * Gets whether this instance has the name of a standard instance 150 * initialization method. This is just a convenient shorthand for 151 * {@code getName().getString().equals("<init>")}. 152 * 153 * @return {@code true} iff this is a reference to an 154 * instance initialization method 155 */ 156 public final boolean isInstanceInit() { 157 return name.getString().equals("<init>"); 158 } 159 160 /** 161 * Gets whether this instance has the name of a standard class 162 * initialization method. This is just a convenient shorthand for 163 * {@code getName().getString().equals("<clinit>")}. 164 * 165 * @return {@code true} iff this is a reference to an 166 * instance initialization method 167 */ 168 public final boolean isClassInit() { 169 return name.getString().equals("<clinit>"); 170 } 171 } 172