blob: a4c2d44b0435df27df938f5bc0b64d77023833d2 [file] [log] [blame]
/*
* 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 {
/** non-null; no-element instance */
public static final StdTypeList EMPTY = new StdTypeList(0);
/** non-null; the list <code>[int]</code> */
public static final StdTypeList INT = StdTypeList.make(Type.INT);
/** non-null; the list <code>[long]</code> */
public static final StdTypeList LONG = StdTypeList.make(Type.LONG);
/** non-null; the list <code>[float]</code> */
public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT);
/** non-null; the list <code>[double]</code> */
public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE);
/** non-null; the list <code>[Object]</code> */
public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT);
/** non-null; the list <code>[ReturnAddress]</code> */
public static final StdTypeList RETURN_ADDRESS
= StdTypeList.make(Type.RETURN_ADDRESS);
/** non-null; the list <code>[Throwable]</code> */
public static final StdTypeList THROWABLE =
StdTypeList.make(Type.THROWABLE);
/** non-null; the list <code>[int, int]</code> */
public static final StdTypeList INT_INT =
StdTypeList.make(Type.INT, Type.INT);
/** non-null; the list <code>[long, long]</code> */
public static final StdTypeList LONG_LONG =
StdTypeList.make(Type.LONG, Type.LONG);
/** non-null; the list <code>[float, float]</code> */
public static final StdTypeList FLOAT_FLOAT =
StdTypeList.make(Type.FLOAT, Type.FLOAT);
/** non-null; the list <code>[double, double]</code> */
public static final StdTypeList DOUBLE_DOUBLE =
StdTypeList.make(Type.DOUBLE, Type.DOUBLE);
/** non-null; the list <code>[Object, Object]</code> */
public static final StdTypeList OBJECT_OBJECT =
StdTypeList.make(Type.OBJECT, Type.OBJECT);
/** non-null; the list <code>[int, Object]</code> */
public static final StdTypeList INT_OBJECT =
StdTypeList.make(Type.INT, Type.OBJECT);
/** non-null; the list <code>[long, Object]</code> */
public static final StdTypeList LONG_OBJECT =
StdTypeList.make(Type.LONG, Type.OBJECT);
/** non-null; the list <code>[float, Object]</code> */
public static final StdTypeList FLOAT_OBJECT =
StdTypeList.make(Type.FLOAT, Type.OBJECT);
/** non-null; the list <code>[double, Object]</code> */
public static final StdTypeList DOUBLE_OBJECT =
StdTypeList.make(Type.DOUBLE, Type.OBJECT);
/** non-null; the list <code>[long, int]</code> */
public static final StdTypeList LONG_INT =
StdTypeList.make(Type.LONG, Type.INT);
/** non-null; the list <code>[int[], int]</code> */
public static final StdTypeList INTARR_INT =
StdTypeList.make(Type.INT_ARRAY, Type.INT);
/** non-null; the list <code>[long[], int]</code> */
public static final StdTypeList LONGARR_INT =
StdTypeList.make(Type.LONG_ARRAY, Type.INT);
/** non-null; the list <code>[float[], int]</code> */
public static final StdTypeList FLOATARR_INT =
StdTypeList.make(Type.FLOAT_ARRAY, Type.INT);
/** non-null; the list <code>[double[], int]</code> */
public static final StdTypeList DOUBLEARR_INT =
StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT);
/** non-null; the list <code>[Object[], int]</code> */
public static final StdTypeList OBJECTARR_INT =
StdTypeList.make(Type.OBJECT_ARRAY, Type.INT);
/** non-null; the list <code>[boolean[], int]</code> */
public static final StdTypeList BOOLEANARR_INT =
StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT);
/** non-null; the list <code>[byte[], int]</code> */
public static final StdTypeList BYTEARR_INT =
StdTypeList.make(Type.BYTE_ARRAY, Type.INT);
/** non-null; the list <code>[char[], int]</code> */
public static final StdTypeList CHARARR_INT =
StdTypeList.make(Type.CHAR_ARRAY, Type.INT);
/** non-null; the list <code>[short[], int]</code> */
public static final StdTypeList SHORTARR_INT =
StdTypeList.make(Type.SHORT_ARRAY, Type.INT);
/** non-null; the list <code>[int, int[], int]</code> */
public static final StdTypeList INT_INTARR_INT =
StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT);
/** non-null; the list <code>[long, long[], int]</code> */
public static final StdTypeList LONG_LONGARR_INT =
StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT);
/** non-null; the list <code>[float, float[], int]</code> */
public static final StdTypeList FLOAT_FLOATARR_INT =
StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT);
/** non-null; the list <code>[double, double[], int]</code> */
public static final StdTypeList DOUBLE_DOUBLEARR_INT =
StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT);
/** non-null; the list <code>[Object, Object[], int]</code> */
public static final StdTypeList OBJECT_OBJECTARR_INT =
StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT);
/** non-null; the list <code>[int, boolean[], int]</code> */
public static final StdTypeList INT_BOOLEANARR_INT =
StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT);
/** non-null; the list <code>[int, byte[], int]</code> */
public static final StdTypeList INT_BYTEARR_INT =
StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT);
/** non-null; the list <code>[int, char[], int]</code> */
public static final StdTypeList INT_CHARARR_INT =
StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT);
/** non-null; the list <code>[int, short[], int]</code> */
public static final StdTypeList INT_SHORTARR_INT =
StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT);
/**
* Makes a single-element instance.
*
* @param type non-null; the element
* @return 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 non-null; the first element
* @param type1 non-null; the second element
* @return 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 non-null; the first element
* @param type1 non-null; the second element
* @param type2 non-null; the third element
* @return 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 non-null; the first element
* @param type1 non-null; the second element
* @param type2 non-null; the third element
* @param type3 non-null; the fourth element
* @return 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 non-null; the list to convert
* @return 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 non-null; the list to inspect
* @return 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 non-null; one list to compare
* @param list2 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 non-null; one list to compare
* @param list2 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</code>.
*
* @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</code>.
*
* @param n &gt;= 0, &lt; size(); which element
* @return non-null; the indicated element
*/
public Type get(int n) {
return (Type) get0(n);
}
/**
* Sets the type at the given index.
*
* @param n &gt;= 0, &lt; size(); which element
* @param type 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 non-null; the new first element
* @return 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;
}
}