/* * 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 ""; } 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; } }