Home | History | Annotate | Download | only in type
      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      */
    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      */
    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      */
    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      */
    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      */
    233     public static String toHuman(TypeList list) {
    234         int size = list.size();
    235 
    236         if (size == 0) {
    237             return "<empty>";
    238         }
    239 
    240         StringBuilder sb = new StringBuilder(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      */
    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      */
    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      */
    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      */
    331     public StdTypeList(int size) {
    332         super(size);
    333     }
    334 
    335     /** {@inheritDoc} */
    336     @Override
    337     public Type getType(int n) {
    338         return get(n);
    339     }
    340 
    341     /** {@inheritDoc} */
    342     @Override
    343     public int getWordCount() {
    344         int sz = size();
    345         int result = 0;
    346 
    347         for (int i = 0; i < sz; i++) {
    348             result += get(i).getCategory();
    349         }
    350 
    351         return result;
    352     }
    353 
    354     /** {@inheritDoc} */
    355     @Override
    356     public TypeList withAddedType(Type type) {
    357         int sz = size();
    358         StdTypeList result = new StdTypeList(sz + 1);
    359 
    360         for (int i = 0; i < sz; i++) {
    361             result.set0(i, get0(i));
    362         }
    363 
    364         result.set(sz, type);
    365         result.setImmutable();
    366         return result;
    367     }
    368 
    369     /**
    370      * Gets the indicated element. It is an error to call this with the
    371      * index for an element which was never set; if you do that, this
    372      * will throw {@code NullPointerException}.
    373      *
    374      * @param n {@code >= 0, < size();} which element
    375      * @return {@code non-null;} the indicated element
    376      */
    377     public Type get(int n) {
    378         return (Type) get0(n);
    379     }
    380 
    381     /**
    382      * Sets the type at the given index.
    383      *
    384      * @param n {@code >= 0, < size();} which element
    385      * @param type {@code non-null;} the type to store
    386      */
    387     public void set(int n, Type type) {
    388         set0(n, type);
    389     }
    390 
    391     /**
    392      * Returns a new instance, which is the same as this instance,
    393      * except that it has an additional type prepended to the
    394      * original.
    395      *
    396      * @param type {@code non-null;} the new first element
    397      * @return {@code non-null;} an appropriately-constructed instance
    398      */
    399     public StdTypeList withFirst(Type type) {
    400         int sz = size();
    401         StdTypeList result = new StdTypeList(sz + 1);
    402 
    403         result.set0(0, type);
    404         for (int i = 0; i < sz; i++) {
    405             result.set0(i + 1, getOrNull0(i));
    406         }
    407 
    408         return result;
    409     }
    410 }
    411