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.type; 18 19 import com.android.dx.util.FixedSizeList; 20 21 /** 22 * Standard implementation of {@link TypeList}. 23 */ 24 public final class StdTypeList 25 extends FixedSizeList implements TypeList { 26 /** {@code non-null;} no-element instance */ 27 public static final StdTypeList EMPTY = new StdTypeList(0); 28 29 /** {@code non-null;} the list {@code [int]} */ 30 public static final StdTypeList INT = StdTypeList.make(Type.INT); 31 32 /** {@code non-null;} the list {@code [long]} */ 33 public static final StdTypeList LONG = StdTypeList.make(Type.LONG); 34 35 /** {@code non-null;} the list {@code [float]} */ 36 public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT); 37 38 /** {@code non-null;} the list {@code [double]} */ 39 public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE); 40 41 /** {@code non-null;} the list {@code [Object]} */ 42 public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT); 43 44 /** {@code non-null;} the list {@code [ReturnAddress]} */ 45 public static final StdTypeList RETURN_ADDRESS 46 = StdTypeList.make(Type.RETURN_ADDRESS); 47 48 /** {@code non-null;} the list {@code [Throwable]} */ 49 public static final StdTypeList THROWABLE = 50 StdTypeList.make(Type.THROWABLE); 51 52 /** {@code non-null;} the list {@code [int, int]} */ 53 public static final StdTypeList INT_INT = 54 StdTypeList.make(Type.INT, Type.INT); 55 56 /** {@code non-null;} the list {@code [long, long]} */ 57 public static final StdTypeList LONG_LONG = 58 StdTypeList.make(Type.LONG, Type.LONG); 59 60 /** {@code non-null;} the list {@code [float, float]} */ 61 public static final StdTypeList FLOAT_FLOAT = 62 StdTypeList.make(Type.FLOAT, Type.FLOAT); 63 64 /** {@code non-null;} the list {@code [double, double]} */ 65 public static final StdTypeList DOUBLE_DOUBLE = 66 StdTypeList.make(Type.DOUBLE, Type.DOUBLE); 67 68 /** {@code non-null;} the list {@code [Object, Object]} */ 69 public static final StdTypeList OBJECT_OBJECT = 70 StdTypeList.make(Type.OBJECT, Type.OBJECT); 71 72 /** {@code non-null;} the list {@code [int, Object]} */ 73 public static final StdTypeList INT_OBJECT = 74 StdTypeList.make(Type.INT, Type.OBJECT); 75 76 /** {@code non-null;} the list {@code [long, Object]} */ 77 public static final StdTypeList LONG_OBJECT = 78 StdTypeList.make(Type.LONG, Type.OBJECT); 79 80 /** {@code non-null;} the list {@code [float, Object]} */ 81 public static final StdTypeList FLOAT_OBJECT = 82 StdTypeList.make(Type.FLOAT, Type.OBJECT); 83 84 /** {@code non-null;} the list {@code [double, Object]} */ 85 public static final StdTypeList DOUBLE_OBJECT = 86 StdTypeList.make(Type.DOUBLE, Type.OBJECT); 87 88 /** {@code non-null;} the list {@code [long, int]} */ 89 public static final StdTypeList LONG_INT = 90 StdTypeList.make(Type.LONG, Type.INT); 91 92 /** {@code non-null;} the list {@code [int[], int]} */ 93 public static final StdTypeList INTARR_INT = 94 StdTypeList.make(Type.INT_ARRAY, Type.INT); 95 96 /** {@code non-null;} the list {@code [long[], int]} */ 97 public static final StdTypeList LONGARR_INT = 98 StdTypeList.make(Type.LONG_ARRAY, Type.INT); 99 100 /** {@code non-null;} the list {@code [float[], int]} */ 101 public static final StdTypeList FLOATARR_INT = 102 StdTypeList.make(Type.FLOAT_ARRAY, Type.INT); 103 104 /** {@code non-null;} the list {@code [double[], int]} */ 105 public static final StdTypeList DOUBLEARR_INT = 106 StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT); 107 108 /** {@code non-null;} the list {@code [Object[], int]} */ 109 public static final StdTypeList OBJECTARR_INT = 110 StdTypeList.make(Type.OBJECT_ARRAY, Type.INT); 111 112 /** {@code non-null;} the list {@code [boolean[], int]} */ 113 public static final StdTypeList BOOLEANARR_INT = 114 StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT); 115 116 /** {@code non-null;} the list {@code [byte[], int]} */ 117 public static final StdTypeList BYTEARR_INT = 118 StdTypeList.make(Type.BYTE_ARRAY, Type.INT); 119 120 /** {@code non-null;} the list {@code [char[], int]} */ 121 public static final StdTypeList CHARARR_INT = 122 StdTypeList.make(Type.CHAR_ARRAY, Type.INT); 123 124 /** {@code non-null;} the list {@code [short[], int]} */ 125 public static final StdTypeList SHORTARR_INT = 126 StdTypeList.make(Type.SHORT_ARRAY, Type.INT); 127 128 /** {@code non-null;} the list {@code [int, int[], int]} */ 129 public static final StdTypeList INT_INTARR_INT = 130 StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT); 131 132 /** {@code non-null;} the list {@code [long, long[], int]} */ 133 public static final StdTypeList LONG_LONGARR_INT = 134 StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT); 135 136 /** {@code non-null;} the list {@code [float, float[], int]} */ 137 public static final StdTypeList FLOAT_FLOATARR_INT = 138 StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT); 139 140 /** {@code non-null;} the list {@code [double, double[], int]} */ 141 public static final StdTypeList DOUBLE_DOUBLEARR_INT = 142 StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT); 143 144 /** {@code non-null;} the list {@code [Object, Object[], int]} */ 145 public static final StdTypeList OBJECT_OBJECTARR_INT = 146 StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT); 147 148 /** {@code non-null;} the list {@code [int, boolean[], int]} */ 149 public static final StdTypeList INT_BOOLEANARR_INT = 150 StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT); 151 152 /** {@code non-null;} the list {@code [int, byte[], int]} */ 153 public static final StdTypeList INT_BYTEARR_INT = 154 StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT); 155 156 /** {@code non-null;} the list {@code [int, char[], int]} */ 157 public static final StdTypeList INT_CHARARR_INT = 158 StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT); 159 160 /** {@code non-null;} the list {@code [int, short[], int]} */ 161 public static final StdTypeList INT_SHORTARR_INT = 162 StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT); 163 164 /** 165 * Makes a single-element instance. 166 * 167 * @param type {@code non-null;} the element 168 * @return {@code non-null;} an appropriately-constructed instance 169 */ make(Type type)170 public static StdTypeList make(Type type) { 171 StdTypeList result = new StdTypeList(1); 172 result.set(0, type); 173 return result; 174 } 175 176 /** 177 * Makes a two-element instance. 178 * 179 * @param type0 {@code non-null;} the first element 180 * @param type1 {@code non-null;} the second element 181 * @return {@code non-null;} an appropriately-constructed instance 182 */ make(Type type0, Type type1)183 public static StdTypeList make(Type type0, Type type1) { 184 StdTypeList result = new StdTypeList(2); 185 result.set(0, type0); 186 result.set(1, type1); 187 return result; 188 } 189 190 /** 191 * Makes a three-element instance. 192 * 193 * @param type0 {@code non-null;} the first element 194 * @param type1 {@code non-null;} the second element 195 * @param type2 {@code non-null;} the third element 196 * @return {@code non-null;} an appropriately-constructed instance 197 */ make(Type type0, Type type1, Type type2)198 public static StdTypeList make(Type type0, Type type1, Type type2) { 199 StdTypeList result = new StdTypeList(3); 200 result.set(0, type0); 201 result.set(1, type1); 202 result.set(2, type2); 203 return result; 204 } 205 206 /** 207 * Makes a four-element instance. 208 * 209 * @param type0 {@code non-null;} the first element 210 * @param type1 {@code non-null;} the second element 211 * @param type2 {@code non-null;} the third element 212 * @param type3 {@code non-null;} the fourth element 213 * @return {@code non-null;} an appropriately-constructed instance 214 */ make(Type type0, Type type1, Type type2, Type type3)215 public static StdTypeList make(Type type0, Type type1, Type type2, 216 Type type3) { 217 StdTypeList result = new StdTypeList(4); 218 result.set(0, type0); 219 result.set(1, type1); 220 result.set(2, type2); 221 result.set(3, type3); 222 return result; 223 } 224 225 /** 226 * Returns the given list as a comma-separated list of human forms. This 227 * is a static method so as to work on arbitrary {@link TypeList} 228 * instances. 229 * 230 * @param list {@code non-null;} the list to convert 231 * @return {@code non-null;} the human form 232 */ toHuman(TypeList list)233 public static String toHuman(TypeList list) { 234 int size = list.size(); 235 236 if (size == 0) { 237 return "<empty>"; 238 } 239 240 StringBuffer sb = new StringBuffer(100); 241 242 for (int i = 0; i < size; i++) { 243 if (i != 0) { 244 sb.append(", "); 245 } 246 sb.append(list.getType(i).toHuman()); 247 } 248 249 return sb.toString(); 250 } 251 252 /** 253 * Returns a hashcode of the contents of the given list. This 254 * is a static method so as to work on arbitrary {@link TypeList} 255 * instances. 256 * 257 * @param list {@code non-null;} the list to inspect 258 * @return {@code non-null;} the hash code 259 */ hashContents(TypeList list)260 public static int hashContents(TypeList list) { 261 int size = list.size(); 262 int hash = 0; 263 264 for (int i = 0; i < size; i++) { 265 hash = (hash * 31) + list.getType(i).hashCode(); 266 } 267 268 return hash; 269 } 270 271 /** 272 * Compares the contents of the given two instances for equality. This 273 * is a static method so as to work on arbitrary {@link TypeList} 274 * instances. 275 * 276 * @param list1 {@code non-null;} one list to compare 277 * @param list2 {@code non-null;} another list to compare 278 * @return whether the two lists contain corresponding equal elements 279 */ equalContents(TypeList list1, TypeList list2)280 public static boolean equalContents(TypeList list1, TypeList list2) { 281 int size = list1.size(); 282 283 if (list2.size() != size) { 284 return false; 285 } 286 287 for (int i = 0; i < size; i++) { 288 if (! list1.getType(i).equals(list2.getType(i))) { 289 return false; 290 } 291 } 292 293 return true; 294 } 295 296 /** 297 * Compares the contents of the given two instances for ordering. This 298 * is a static method so as to work on arbitrary {@link TypeList} 299 * instances. 300 * 301 * @param list1 {@code non-null;} one list to compare 302 * @param list2 {@code non-null;} another list to compare 303 * @return the order of the two lists 304 */ compareContents(TypeList list1, TypeList list2)305 public static int compareContents(TypeList list1, TypeList list2) { 306 int size1 = list1.size(); 307 int size2 = list2.size(); 308 int size = Math.min(size1, size2); 309 310 for (int i = 0; i < size; i++) { 311 int comparison = list1.getType(i).compareTo(list2.getType(i)); 312 if (comparison != 0) { 313 return comparison; 314 } 315 } 316 317 if (size1 == size2) { 318 return 0; 319 } else if (size1 < size2) { 320 return -1; 321 } else { 322 return 1; 323 } 324 } 325 326 /** 327 * Constructs an instance. All indices initially contain {@code null}. 328 * 329 * @param size the size of the list 330 */ StdTypeList(int size)331 public StdTypeList(int size) { 332 super(size); 333 } 334 335 /** {@inheritDoc} */ getType(int n)336 public Type getType(int n) { 337 return get(n); 338 } 339 340 /** {@inheritDoc} */ getWordCount()341 public int getWordCount() { 342 int sz = size(); 343 int result = 0; 344 345 for (int i = 0; i < sz; i++) { 346 result += get(i).getCategory(); 347 } 348 349 return result; 350 } 351 352 /** {@inheritDoc} */ withAddedType(Type type)353 public TypeList withAddedType(Type type) { 354 int sz = size(); 355 StdTypeList result = new StdTypeList(sz + 1); 356 357 for (int i = 0; i < sz; i++) { 358 result.set0(i, get0(i)); 359 } 360 361 result.set(sz, type); 362 result.setImmutable(); 363 return result; 364 } 365 366 /** 367 * Gets the indicated element. It is an error to call this with the 368 * index for an element which was never set; if you do that, this 369 * will throw {@code NullPointerException}. 370 * 371 * @param n {@code >= 0, < size();} which element 372 * @return {@code non-null;} the indicated element 373 */ get(int n)374 public Type get(int n) { 375 return (Type) get0(n); 376 } 377 378 /** 379 * Sets the type at the given index. 380 * 381 * @param n {@code >= 0, < size();} which element 382 * @param type {@code non-null;} the type to store 383 */ set(int n, Type type)384 public void set(int n, Type type) { 385 set0(n, type); 386 } 387 388 /** 389 * Returns a new instance, which is the same as this instance, 390 * except that it has an additional type prepended to the 391 * original. 392 * 393 * @param type {@code non-null;} the new first element 394 * @return {@code non-null;} an appropriately-constructed instance 395 */ withFirst(Type type)396 public StdTypeList withFirst(Type type) { 397 int sz = size(); 398 StdTypeList result = new StdTypeList(sz + 1); 399 400 result.set0(0, type); 401 for (int i = 0; i < sz; i++) { 402 result.set0(i + 1, getOrNull0(i)); 403 } 404 405 return result; 406 } 407 } 408