16 * distributed under the License is distributed on an "AS IS" BASIS, |
16 * distributed under the License is distributed on an "AS IS" BASIS, |
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
18 * See the License for the specific language governing permissions and |
18 * See the License for the specific language governing permissions and |
19 * limitations under the License. |
19 * limitations under the License. |
20 */ |
20 */ |
21 |
|
22 package com.sun.org.apache.bcel.internal.generic; |
21 package com.sun.org.apache.bcel.internal.generic; |
23 |
22 |
24 import com.sun.org.apache.bcel.internal.Constants; |
23 import com.sun.org.apache.bcel.internal.Const; |
25 |
24 |
26 /** |
25 /** |
27 * Denotes array type, such as int[][] |
26 * Denotes array type, such as int[][] |
28 * |
27 * |
29 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> |
28 * @version $Id: ArrayType.java 1749603 2016-06-21 20:50:19Z ggregory $ |
30 */ |
29 */ |
31 public final class ArrayType extends ReferenceType { |
30 public final class ArrayType extends ReferenceType { |
32 private int dimensions; |
|
33 private Type basic_type; |
|
34 |
31 |
35 /** |
32 private int dimensions; |
36 * Convenience constructor for array type, e.g. int[] |
33 private Type basic_type; |
37 * |
|
38 * @param type array type, e.g. T_INT |
|
39 */ |
|
40 public ArrayType(byte type, int dimensions) { |
|
41 this(BasicType.getType(type), dimensions); |
|
42 } |
|
43 |
34 |
44 /** |
35 /** |
45 * Convenience constructor for reference array type, e.g. Object[] |
36 * Convenience constructor for array type, e.g. int[] |
46 * |
37 * |
47 * @param class_name complete name of class (java.lang.String, e.g.) |
38 * @param type array type, e.g. T_INT |
48 */ |
39 */ |
49 public ArrayType(String class_name, int dimensions) { |
40 public ArrayType(final byte type, final int dimensions) { |
50 this(new ObjectType(class_name), dimensions); |
41 this(BasicType.getType(type), dimensions); |
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(Type type, int dimensions) { |
|
59 super(Constants.T_ARRAY, "<dummy>"); |
|
60 |
|
61 if((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) |
|
62 throw new ClassGenException("Invalid number of dimensions: " + dimensions); |
|
63 |
|
64 switch(type.getType()) { |
|
65 case Constants.T_ARRAY: |
|
66 ArrayType array = (ArrayType)type; |
|
67 this.dimensions = dimensions + array.dimensions; |
|
68 basic_type = array.basic_type; |
|
69 break; |
|
70 |
|
71 case Constants.T_VOID: |
|
72 throw new ClassGenException("Invalid type: void[]"); |
|
73 |
|
74 default: // Basic type or reference |
|
75 this.dimensions = dimensions; |
|
76 basic_type = type; |
|
77 break; |
|
78 } |
42 } |
79 |
43 |
80 StringBuffer buf = new StringBuffer(); |
44 /** |
81 for(int i=0; i < this.dimensions; i++) |
45 * Convenience constructor for reference array type, e.g. Object[] |
82 buf.append('['); |
46 * |
|
47 * @param class_name complete name of class (java.lang.String, e.g.) |
|
48 */ |
|
49 public ArrayType(final String class_name, final int dimensions) { |
|
50 this(ObjectType.getInstance(class_name), dimensions); |
|
51 } |
83 |
52 |
84 buf.append(basic_type.getSignature()); |
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 } |
85 |
83 |
86 signature = buf.toString(); |
84 /** |
87 } |
85 * @return basic type of array, i.e., for int[][][] the basic type is int |
|
86 */ |
|
87 public Type getBasicType() { |
|
88 return basic_type; |
|
89 } |
88 |
90 |
89 /** |
91 /** |
90 * @return basic type of array, i.e., for int[][][] the basic type is int |
92 * @return element type of array, i.e., for int[][][] the element type is |
91 */ |
93 * int[][] |
92 public Type getBasicType() { |
94 */ |
93 return basic_type; |
95 public Type getElementType() { |
94 } |
96 if (dimensions == 1) { |
|
97 return basic_type; |
|
98 } |
|
99 return new ArrayType(basic_type, dimensions - 1); |
|
100 } |
95 |
101 |
96 /** |
102 /** |
97 * @return element type of array, i.e., for int[][][] the element type is int[][] |
103 * @return number of dimensions of array |
98 */ |
104 */ |
99 public Type getElementType() { |
105 public int getDimensions() { |
100 if(dimensions == 1) |
106 return dimensions; |
101 return basic_type; |
107 } |
102 else |
|
103 return new ArrayType(basic_type, dimensions - 1); |
|
104 } |
|
105 |
108 |
106 /** @return number of dimensions of array |
109 /** |
107 */ |
110 * @return a hash code value for the object. |
108 public int getDimensions() { return dimensions; } |
111 */ |
|
112 @Override |
|
113 public int hashCode() { |
|
114 return basic_type.hashCode() ^ dimensions; |
|
115 } |
109 |
116 |
110 /** @return a hash code value for the object. |
117 /** |
111 */ |
118 * @return true if both type objects refer to the same array type. |
112 public int hashCode() { return basic_type.hashCode() ^ dimensions; } |
119 */ |
113 |
120 @Override |
114 /** @return true if both type objects refer to the same array type. |
121 public boolean equals(final Object _type) { |
115 */ |
122 if (_type instanceof ArrayType) { |
116 public boolean equals(Object type) { |
123 final ArrayType array = (ArrayType) _type; |
117 if(type instanceof ArrayType) { |
124 return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); |
118 ArrayType array = (ArrayType)type; |
125 } |
119 return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); |
126 return false; |
120 } else |
127 } |
121 return false; |
|
122 } |
|
123 } |
128 } |