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