A variable description (like PHPFunctionDeclaration)
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / ArrayBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
12
13 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
14 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
15
16 public final class ArrayBinding extends TypeBinding {
17         // creation and initialization of the length field
18         // the declaringClass of this field is intentionally set to null so it can be distinguished.
19         public static final FieldBinding LengthField = new FieldBinding(LENGTH, IntBinding, AccPublic | AccFinal, null, Constant.NotAConstant);
20
21         public TypeBinding leafComponentType;
22         public int dimensions;
23
24         char[] constantPoolName;
25 public ArrayBinding(TypeBinding type, int dimensions) {
26         this.tagBits |= IsArrayType;
27         this.leafComponentType = type;
28         this.dimensions = dimensions;
29 }
30 /* Answer the receiver's constant pool name.
31 *
32 * NOTE: This method should only be used during/after code gen.
33 */
34
35 public char[] constantPoolName() /*     [Ljava/lang/Object; */ {
36         if (constantPoolName != null)
37                 return constantPoolName;
38
39         char[] brackets = new char[dimensions];
40         for (int i = dimensions - 1; i >= 0; i--)
41                 brackets[i] = '[';
42         return constantPoolName = CharOperation.concat(brackets, leafComponentType.signature());
43 }
44 String debugName() {
45         StringBuffer brackets = new StringBuffer(dimensions * 2);
46         for (int i = dimensions; --i >= 0;)
47                 brackets.append("[]"); //$NON-NLS-1$
48         return leafComponentType.debugName() + brackets.toString();
49 }
50 /* Answer an array whose dimension size is one less than the receiver.
51 *
52 * When the receiver's dimension size is one then answer the leaf component type.
53 */
54
55 public TypeBinding elementsType(Scope scope) {
56         if (dimensions == 1)
57                 return leafComponentType;
58         else
59                 return scope.createArray(leafComponentType, dimensions - 1);
60 }
61 public PackageBinding getPackage() {
62         return leafComponentType.getPackage();
63 }
64 /* Answer true if the receiver type can be assigned to the argument type (right)
65 */
66
67 boolean isCompatibleWith(TypeBinding right) {
68         if (this == right)
69                 return true;
70
71         char[][] rightName;
72         if (right.isArrayType()) {
73                 ArrayBinding rightArray = (ArrayBinding) right;
74                 if (rightArray.leafComponentType.isBaseType())
75                         return false; // relying on the fact that all equal arrays are identical
76                 if (dimensions == rightArray.dimensions)
77                         return leafComponentType.isCompatibleWith(rightArray.leafComponentType);
78                 if (dimensions < rightArray.dimensions)
79                         return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
80                 rightName = ((ReferenceBinding) rightArray.leafComponentType).compoundName;
81         } else {
82                 if (right.isBaseType())
83                         return false;
84                 rightName = ((ReferenceBinding) right).compoundName;
85         }
86         //Check dimensions - Java does not support explicitly sized dimensions for types.
87         //However, if it did, the type checking support would go here.
88
89         if (CharOperation.equals(rightName, JAVA_LANG_OBJECT))
90                 return true;
91         if (CharOperation.equals(rightName, JAVA_LANG_CLONEABLE))
92                 return true;
93         if (CharOperation.equals(rightName, JAVA_IO_SERIALIZABLE))
94                 return true;
95         return false;
96 }
97
98 public TypeBinding leafComponentType(){
99         return leafComponentType;
100 }
101
102 /* API
103 * Answer the problem id associated with the receiver.
104 * NoError if the receiver is a valid binding.
105 */
106
107 public int problemId() {
108         return leafComponentType.problemId();
109 }
110 /**
111 * Answer the source name for the type.
112 * In the case of member types, as the qualified name from its top level type.
113 * For example, for a member type N defined inside M & A: "A.M.N".
114 */
115
116 public char[] qualifiedSourceName() {
117         char[] brackets = new char[dimensions * 2];
118         for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
119                 brackets[i] = ']';
120                 brackets[i - 1] = '[';
121         }
122         return CharOperation.concat(leafComponentType.qualifiedSourceName(), brackets);
123 }
124 public char[] readableName() /* java.lang.Object[] */ {
125         char[] brackets = new char[dimensions * 2];
126         for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
127                 brackets[i] = ']';
128                 brackets[i - 1] = '[';
129         }
130         return CharOperation.concat(leafComponentType.readableName(), brackets);
131 }
132 public char[] sourceName() {
133         char[] brackets = new char[dimensions * 2];
134         for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
135                 brackets[i] = ']';
136                 brackets[i - 1] = '[';
137         }
138         return CharOperation.concat(leafComponentType.sourceName(), brackets);
139 }
140 public String toString() {
141         return leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
142 }
143 }