Home | History | Annotate | Download | only in generic
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  */
     18 package org.apache.bcel.generic;
     19 
     20 import org.apache.bcel.Const;
     21 
     22 /**
     23  * Denotes array type, such as int[][]
     24  *
     25  * @version $Id$
     26  */
     27 public final class ArrayType extends ReferenceType {
     28 
     29     private int dimensions;
     30     private Type basic_type;
     31 
     32 
     33     /**
     34      * Convenience constructor for array type, e.g. int[]
     35      *
     36      * @param type array type, e.g. T_INT
     37      */
     38     public ArrayType(final byte type, final int dimensions) {
     39         this(BasicType.getType(type), dimensions);
     40     }
     41 
     42 
     43     /**
     44      * Convenience constructor for reference array type, e.g. Object[]
     45      *
     46      * @param class_name complete name of class (java.lang.String, e.g.)
     47      */
     48     public ArrayType(final String class_name, final int dimensions) {
     49         this(ObjectType.getInstance(class_name), dimensions);
     50     }
     51 
     52 
     53     /**
     54      * Constructor for array of given type
     55      *
     56      * @param type type of array (may be an array itself)
     57      */
     58     public ArrayType(final Type type, final int dimensions) {
     59         super(Const.T_ARRAY, "<dummy>");
     60         if ((dimensions < 1) || (dimensions > Const.MAX_BYTE)) {
     61             throw new ClassGenException("Invalid number of dimensions: " + dimensions);
     62         }
     63         switch (type.getType()) {
     64             case Const.T_ARRAY:
     65                 final ArrayType array = (ArrayType) type;
     66                 this.dimensions = dimensions + array.dimensions;
     67                 basic_type = array.basic_type;
     68                 break;
     69             case Const.T_VOID:
     70                 throw new ClassGenException("Invalid type: void[]");
     71             default: // Basic type or reference
     72                 this.dimensions = dimensions;
     73                 basic_type = type;
     74                 break;
     75         }
     76         final StringBuilder buf = new StringBuilder();
     77         for (int i = 0; i < this.dimensions; i++) {
     78             buf.append('[');
     79         }
     80         buf.append(basic_type.getSignature());
     81         super.setSignature(buf.toString());
     82     }
     83 
     84 
     85     /**
     86      * @return basic type of array, i.e., for int[][][] the basic type is int
     87      */
     88     public Type getBasicType() {
     89         return basic_type;
     90     }
     91 
     92 
     93     /**
     94      * @return element type of array, i.e., for int[][][] the element type is int[][]
     95      */
     96     public Type getElementType() {
     97         if (dimensions == 1) {
     98             return basic_type;
     99         }
    100         return new ArrayType(basic_type, dimensions - 1);
    101     }
    102 
    103 
    104     /** @return number of dimensions of array
    105      */
    106     public int getDimensions() {
    107         return dimensions;
    108     }
    109 
    110 
    111     /** @return a hash code value for the object.
    112      */
    113     @Override
    114     public int hashCode() {
    115         return basic_type.hashCode() ^ dimensions;
    116     }
    117 
    118 
    119     /** @return true if both type objects refer to the same array type.
    120      */
    121     @Override
    122     public boolean equals( final Object _type ) {
    123         if (_type instanceof ArrayType) {
    124             final ArrayType array = (ArrayType) _type;
    125             return (array.dimensions == dimensions) && array.basic_type.equals(basic_type);
    126         }
    127         return false;
    128     }
    129 }
    130