| /* |
| * 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.type; |
| |
| import com.android.dx.util.FixedSizeList; |
| |
| /** |
| * Standard implementation of {@link TypeList}. |
| */ |
| public final class StdTypeList |
| extends FixedSizeList implements TypeList { |
| /** {@code non-null;} no-element instance */ |
| public static final StdTypeList EMPTY = new StdTypeList(0); |
| |
| /** {@code non-null;} the list {@code [int]} */ |
| public static final StdTypeList INT = StdTypeList.make(Type.INT); |
| |
| /** {@code non-null;} the list {@code [long]} */ |
| public static final StdTypeList LONG = StdTypeList.make(Type.LONG); |
| |
| /** {@code non-null;} the list {@code [float]} */ |
| public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT); |
| |
| /** {@code non-null;} the list {@code [double]} */ |
| public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE); |
| |
| /** {@code non-null;} the list {@code [Object]} */ |
| public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [ReturnAddress]} */ |
| public static final StdTypeList RETURN_ADDRESS |
| = StdTypeList.make(Type.RETURN_ADDRESS); |
| |
| /** {@code non-null;} the list {@code [Throwable]} */ |
| public static final StdTypeList THROWABLE = |
| StdTypeList.make(Type.THROWABLE); |
| |
| /** {@code non-null;} the list {@code [int, int]} */ |
| public static final StdTypeList INT_INT = |
| StdTypeList.make(Type.INT, Type.INT); |
| |
| /** {@code non-null;} the list {@code [long, long]} */ |
| public static final StdTypeList LONG_LONG = |
| StdTypeList.make(Type.LONG, Type.LONG); |
| |
| /** {@code non-null;} the list {@code [float, float]} */ |
| public static final StdTypeList FLOAT_FLOAT = |
| StdTypeList.make(Type.FLOAT, Type.FLOAT); |
| |
| /** {@code non-null;} the list {@code [double, double]} */ |
| public static final StdTypeList DOUBLE_DOUBLE = |
| StdTypeList.make(Type.DOUBLE, Type.DOUBLE); |
| |
| /** {@code non-null;} the list {@code [Object, Object]} */ |
| public static final StdTypeList OBJECT_OBJECT = |
| StdTypeList.make(Type.OBJECT, Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [int, Object]} */ |
| public static final StdTypeList INT_OBJECT = |
| StdTypeList.make(Type.INT, Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [long, Object]} */ |
| public static final StdTypeList LONG_OBJECT = |
| StdTypeList.make(Type.LONG, Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [float, Object]} */ |
| public static final StdTypeList FLOAT_OBJECT = |
| StdTypeList.make(Type.FLOAT, Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [double, Object]} */ |
| public static final StdTypeList DOUBLE_OBJECT = |
| StdTypeList.make(Type.DOUBLE, Type.OBJECT); |
| |
| /** {@code non-null;} the list {@code [long, int]} */ |
| public static final StdTypeList LONG_INT = |
| StdTypeList.make(Type.LONG, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int[], int]} */ |
| public static final StdTypeList INTARR_INT = |
| StdTypeList.make(Type.INT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [long[], int]} */ |
| public static final StdTypeList LONGARR_INT = |
| StdTypeList.make(Type.LONG_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [float[], int]} */ |
| public static final StdTypeList FLOATARR_INT = |
| StdTypeList.make(Type.FLOAT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [double[], int]} */ |
| public static final StdTypeList DOUBLEARR_INT = |
| StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [Object[], int]} */ |
| public static final StdTypeList OBJECTARR_INT = |
| StdTypeList.make(Type.OBJECT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [boolean[], int]} */ |
| public static final StdTypeList BOOLEANARR_INT = |
| StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [byte[], int]} */ |
| public static final StdTypeList BYTEARR_INT = |
| StdTypeList.make(Type.BYTE_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [char[], int]} */ |
| public static final StdTypeList CHARARR_INT = |
| StdTypeList.make(Type.CHAR_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [short[], int]} */ |
| public static final StdTypeList SHORTARR_INT = |
| StdTypeList.make(Type.SHORT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int, int[], int]} */ |
| public static final StdTypeList INT_INTARR_INT = |
| StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [long, long[], int]} */ |
| public static final StdTypeList LONG_LONGARR_INT = |
| StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [float, float[], int]} */ |
| public static final StdTypeList FLOAT_FLOATARR_INT = |
| StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [double, double[], int]} */ |
| public static final StdTypeList DOUBLE_DOUBLEARR_INT = |
| StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [Object, Object[], int]} */ |
| public static final StdTypeList OBJECT_OBJECTARR_INT = |
| StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int, boolean[], int]} */ |
| public static final StdTypeList INT_BOOLEANARR_INT = |
| StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int, byte[], int]} */ |
| public static final StdTypeList INT_BYTEARR_INT = |
| StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int, char[], int]} */ |
| public static final StdTypeList INT_CHARARR_INT = |
| StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT); |
| |
| /** {@code non-null;} the list {@code [int, short[], int]} */ |
| public static final StdTypeList INT_SHORTARR_INT = |
| StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT); |
| |
| /** |
| * Makes a single-element instance. |
| * |
| * @param type {@code non-null;} the element |
| * @return {@code non-null;} an appropriately-constructed instance |
| */ |
| public static StdTypeList make(Type type) { |
| StdTypeList result = new StdTypeList(1); |
| result.set(0, type); |
| return result; |
| } |
| |
| /** |
| * Makes a two-element instance. |
| * |
| * @param type0 {@code non-null;} the first element |
| * @param type1 {@code non-null;} the second element |
| * @return {@code non-null;} an appropriately-constructed instance |
| */ |
| public static StdTypeList make(Type type0, Type type1) { |
| StdTypeList result = new StdTypeList(2); |
| result.set(0, type0); |
| result.set(1, type1); |
| return result; |
| } |
| |
| /** |
| * Makes a three-element instance. |
| * |
| * @param type0 {@code non-null;} the first element |
| * @param type1 {@code non-null;} the second element |
| * @param type2 {@code non-null;} the third element |
| * @return {@code non-null;} an appropriately-constructed instance |
| */ |
| public static StdTypeList make(Type type0, Type type1, Type type2) { |
| StdTypeList result = new StdTypeList(3); |
| result.set(0, type0); |
| result.set(1, type1); |
| result.set(2, type2); |
| return result; |
| } |
| |
| /** |
| * Makes a four-element instance. |
| * |
| * @param type0 {@code non-null;} the first element |
| * @param type1 {@code non-null;} the second element |
| * @param type2 {@code non-null;} the third element |
| * @param type3 {@code non-null;} the fourth element |
| * @return {@code non-null;} an appropriately-constructed instance |
| */ |
| public static StdTypeList make(Type type0, Type type1, Type type2, |
| Type type3) { |
| StdTypeList result = new StdTypeList(4); |
| result.set(0, type0); |
| result.set(1, type1); |
| result.set(2, type2); |
| result.set(3, type3); |
| return result; |
| } |
| |
| /** |
| * Returns the given list as a comma-separated list of human forms. This |
| * is a static method so as to work on arbitrary {@link TypeList} |
| * instances. |
| * |
| * @param list {@code non-null;} the list to convert |
| * @return {@code non-null;} the human form |
| */ |
| public static String toHuman(TypeList list) { |
| int size = list.size(); |
| |
| if (size == 0) { |
| return "<empty>"; |
| } |
| |
| StringBuffer sb = new StringBuffer(100); |
| |
| for (int i = 0; i < size; i++) { |
| if (i != 0) { |
| sb.append(", "); |
| } |
| sb.append(list.getType(i).toHuman()); |
| } |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * Returns a hashcode of the contents of the given list. This |
| * is a static method so as to work on arbitrary {@link TypeList} |
| * instances. |
| * |
| * @param list {@code non-null;} the list to inspect |
| * @return {@code non-null;} the hash code |
| */ |
| public static int hashContents(TypeList list) { |
| int size = list.size(); |
| int hash = 0; |
| |
| for (int i = 0; i < size; i++) { |
| hash = (hash * 31) + list.getType(i).hashCode(); |
| } |
| |
| return hash; |
| } |
| |
| /** |
| * Compares the contents of the given two instances for equality. This |
| * is a static method so as to work on arbitrary {@link TypeList} |
| * instances. |
| * |
| * @param list1 {@code non-null;} one list to compare |
| * @param list2 {@code non-null;} another list to compare |
| * @return whether the two lists contain corresponding equal elements |
| */ |
| public static boolean equalContents(TypeList list1, TypeList list2) { |
| int size = list1.size(); |
| |
| if (list2.size() != size) { |
| return false; |
| } |
| |
| for (int i = 0; i < size; i++) { |
| if (! list1.getType(i).equals(list2.getType(i))) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Compares the contents of the given two instances for ordering. This |
| * is a static method so as to work on arbitrary {@link TypeList} |
| * instances. |
| * |
| * @param list1 {@code non-null;} one list to compare |
| * @param list2 {@code non-null;} another list to compare |
| * @return the order of the two lists |
| */ |
| public static int compareContents(TypeList list1, TypeList list2) { |
| int size1 = list1.size(); |
| int size2 = list2.size(); |
| int size = Math.min(size1, size2); |
| |
| for (int i = 0; i < size; i++) { |
| int comparison = list1.getType(i).compareTo(list2.getType(i)); |
| if (comparison != 0) { |
| return comparison; |
| } |
| } |
| |
| if (size1 == size2) { |
| return 0; |
| } else if (size1 < size2) { |
| return -1; |
| } else { |
| return 1; |
| } |
| } |
| |
| /** |
| * Constructs an instance. All indices initially contain {@code null}. |
| * |
| * @param size the size of the list |
| */ |
| public StdTypeList(int size) { |
| super(size); |
| } |
| |
| /** {@inheritDoc} */ |
| public Type getType(int n) { |
| return get(n); |
| } |
| |
| /** {@inheritDoc} */ |
| public int getWordCount() { |
| int sz = size(); |
| int result = 0; |
| |
| for (int i = 0; i < sz; i++) { |
| result += get(i).getCategory(); |
| } |
| |
| return result; |
| } |
| |
| /** {@inheritDoc} */ |
| public TypeList withAddedType(Type type) { |
| int sz = size(); |
| StdTypeList result = new StdTypeList(sz + 1); |
| |
| for (int i = 0; i < sz; i++) { |
| result.set0(i, get0(i)); |
| } |
| |
| result.set(sz, type); |
| result.setImmutable(); |
| return result; |
| } |
| |
| /** |
| * Gets the indicated element. It is an error to call this with the |
| * index for an element which was never set; if you do that, this |
| * will throw {@code NullPointerException}. |
| * |
| * @param n {@code >= 0, < size();} which element |
| * @return {@code non-null;} the indicated element |
| */ |
| public Type get(int n) { |
| return (Type) get0(n); |
| } |
| |
| /** |
| * Sets the type at the given index. |
| * |
| * @param n {@code >= 0, < size();} which element |
| * @param type {@code non-null;} the type to store |
| */ |
| public void set(int n, Type type) { |
| set0(n, type); |
| } |
| |
| /** |
| * Returns a new instance, which is the same as this instance, |
| * except that it has an additional type prepended to the |
| * original. |
| * |
| * @param type {@code non-null;} the new first element |
| * @return {@code non-null;} an appropriately-constructed instance |
| */ |
| public StdTypeList withFirst(Type type) { |
| int sz = size(); |
| StdTypeList result = new StdTypeList(sz + 1); |
| |
| result.set0(0, type); |
| for (int i = 0; i < sz; i++) { |
| result.set0(i + 1, getOrNull0(i)); |
| } |
| |
| return result; |
| } |
| } |