A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / NestedTypeBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
12
13 public class NestedTypeBinding extends SourceTypeBinding {
14
15         public SourceTypeBinding enclosingType;
16
17         public SyntheticArgumentBinding[] enclosingInstances;
18
19         public SyntheticArgumentBinding[] outerLocalVariables;
20
21         public int enclosingInstancesSlotSize; // amount of slots used by synthetic
22                                                                                         // enclosing instances
23
24         public int outerLocalVariablesSlotSize; // amount of slots used by synthetic
25                                                                                         // outer local variables
26
27         public NestedTypeBinding(char[][] typeName, ClassScope scope,
28                         SourceTypeBinding enclosingType) {
29                 super(typeName, enclosingType.fPackage, scope);
30                 this.tagBits |= IsNestedType;
31                 this.enclosingType = enclosingType;
32         }
33
34         /*
35          * Add a new synthetic argument for <actualOuterLocalVariable>. Answer the
36          * new argument or the existing argument if one already existed.
37          */
38         public SyntheticArgumentBinding addSyntheticArgument(
39                         LocalVariableBinding actualOuterLocalVariable) {
40                 SyntheticArgumentBinding synthLocal = null;
41
42                 if (outerLocalVariables == null) {
43                         synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
44                         outerLocalVariables = new SyntheticArgumentBinding[] { synthLocal };
45                 } else {
46                         int size = outerLocalVariables.length;
47                         int newArgIndex = size;
48                         for (int i = size; --i >= 0;) { // must search backwards
49                                 if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
50                                         return outerLocalVariables[i]; // already exists
51                                 if (outerLocalVariables[i].id > actualOuterLocalVariable.id)
52                                         newArgIndex = i;
53                         }
54                         SyntheticArgumentBinding[] synthLocals = new SyntheticArgumentBinding[size + 1];
55                         System.arraycopy(outerLocalVariables, 0, synthLocals, 0,
56                                         newArgIndex);
57                         synthLocals[newArgIndex] = synthLocal = new SyntheticArgumentBinding(
58                                         actualOuterLocalVariable);
59                         System.arraycopy(outerLocalVariables, newArgIndex, synthLocals,
60                                         newArgIndex + 1, size - newArgIndex);
61                         outerLocalVariables = synthLocals;
62                 }
63                 // System.out.println("Adding synth arg for local var: " + new
64                 // String(actualOuterLocalVariable.name) + " to: " + new
65                 // String(this.readableName()));
66                 if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
67                         this.updateInnerEmulationDependents();
68                 return synthLocal;
69         }
70
71         /*
72          * Add a new synthetic argument for <enclosingType>. Answer the new argument
73          * or the existing argument if one already existed.
74          */
75         public SyntheticArgumentBinding addSyntheticArgument(
76                         ReferenceBinding enclosingType) {
77                 SyntheticArgumentBinding synthLocal = null;
78                 if (enclosingInstances == null) {
79                         synthLocal = new SyntheticArgumentBinding(enclosingType);
80                         enclosingInstances = new SyntheticArgumentBinding[] { synthLocal };
81                 } else {
82                         int size = enclosingInstances.length;
83                         int newArgIndex = size;
84                         for (int i = size; --i >= 0;) {
85                                 if (enclosingInstances[i].type == enclosingType)
86                                         return enclosingInstances[i]; // already exists
87                                 if (this.enclosingType() == enclosingType)
88                                         newArgIndex = 0;
89                         }
90                         SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1];
91                         System.arraycopy(enclosingInstances, 0, newInstances,
92                                         newArgIndex == 0 ? 1 : 0, size);
93                         newInstances[newArgIndex] = synthLocal = new SyntheticArgumentBinding(
94                                         enclosingType);
95                         enclosingInstances = newInstances;
96                 }
97                 // System.out.println("Adding synth arg for enclosing type: " + new
98                 // String(enclosingType.readableName()) + " to: " + new
99                 // String(this.readableName()));
100                 if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
101                         this.updateInnerEmulationDependents();
102                 return synthLocal;
103         }
104
105         /*
106          * Add a new synthetic argument and field for <actualOuterLocalVariable>.
107          * Answer the new argument or the existing argument if one already existed.
108          */
109         public SyntheticArgumentBinding addSyntheticArgumentAndField(
110                         LocalVariableBinding actualOuterLocalVariable) {
111                 SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable);
112                 if (synthLocal == null)
113                         return null;
114
115                 if (synthLocal.matchingField == null)
116                         synthLocal.matchingField = addSyntheticField(actualOuterLocalVariable);
117                 return synthLocal;
118         }
119
120         /*
121          * Add a new synthetic argument and field for <enclosingType>. Answer the
122          * new argument or the existing argument if one already existed.
123          */
124         public SyntheticArgumentBinding addSyntheticArgumentAndField(
125                         ReferenceBinding enclosingType) {
126                 SyntheticArgumentBinding synthLocal = addSyntheticArgument(enclosingType);
127                 if (synthLocal == null)
128                         return null;
129
130                 if (synthLocal.matchingField == null)
131                         synthLocal.matchingField = addSyntheticField(enclosingType);
132                 return synthLocal;
133         }
134
135         /**
136          * Compute the resolved positions for all the synthetic arguments
137          */
138         final public void computeSyntheticArgumentSlotSizes() {
139
140                 int slotSize = 0;
141                 // insert enclosing instances first, followed by the outerLocals
142                 SyntheticArgumentBinding[] enclosingInstances = this
143                                 .syntheticEnclosingInstances();
144                 int enclosingInstancesCount = enclosingInstances == null ? 0
145                                 : enclosingInstances.length;
146                 for (int i = 0; i < enclosingInstancesCount; i++) {
147                         SyntheticArgumentBinding argument = enclosingInstances[i];
148                         // position the enclosing instance synthetic arg
149                         argument.resolvedPosition = slotSize + 1; // shift by 1 to leave
150                                                                                                                 // room for aload0==this
151                         if (slotSize + 1 > 0xFF) { // no more than 255 words of arguments
152                                 this.scope.problemReporter().noMoreAvailableSpaceForArgument(
153                                                 argument, this.scope.referenceType());
154                         }
155                         if ((argument.type == LongBinding)
156                                         || (argument.type == DoubleBinding)) {
157                                 slotSize += 2;
158                         } else {
159                                 slotSize++;
160                         }
161                 }
162                 this.enclosingInstancesSlotSize = slotSize;
163
164                 slotSize = 0; // reset, outer local are not positionned yet, since
165                                                 // will be appended to user arguments
166                 SyntheticArgumentBinding[] outerLocals = this
167                                 .syntheticOuterLocalVariables();
168                 int outerLocalsCount = outerLocals == null ? 0 : outerLocals.length;
169                 for (int i = 0; i < outerLocalsCount; i++) {
170                         SyntheticArgumentBinding argument = outerLocals[i];
171                         // do NOT position the outerlocal synthetic arg yet, since will be
172                         // appended to user arguments
173                         if ((argument.type == LongBinding)
174                                         || (argument.type == DoubleBinding)) {
175                                 slotSize += 2;
176                         } else {
177                                 slotSize++;
178                         }
179                 }
180                 this.outerLocalVariablesSlotSize = slotSize;
181         }
182
183         /*
184          * Answer the receiver's enclosing type... null if the receiver is a top
185          * level type.
186          */
187         public ReferenceBinding enclosingType() {
188
189                 return enclosingType;
190         }
191
192         /*
193          * Answer the synthetic argument for <actualOuterLocalVariable> or null if
194          * one does not exist.
195          */
196         public SyntheticArgumentBinding getSyntheticArgument(
197                         LocalVariableBinding actualOuterLocalVariable) {
198
199                 if (outerLocalVariables == null)
200                         return null; // is null if no outer local variables are known
201
202                 for (int i = outerLocalVariables.length; --i >= 0;)
203                         if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
204                                 return outerLocalVariables[i];
205                 return null;
206         }
207
208         public SyntheticArgumentBinding[] syntheticEnclosingInstances() {
209                 return enclosingInstances; // is null if no enclosing instances are
210                                                                         // required
211         }
212
213         public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
214                 if (enclosingInstances == null)
215                         return null;
216
217                 int length = enclosingInstances.length;
218                 ReferenceBinding types[] = new ReferenceBinding[length];
219                 for (int i = 0; i < length; i++)
220                         types[i] = (ReferenceBinding) enclosingInstances[i].type;
221                 return types;
222         }
223
224         public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
225
226                 return outerLocalVariables; // is null if no outer locals are required
227         }
228
229         /*
230          * Trigger the dependency mechanism forcing the innerclass emulation to be
231          * propagated to all dependent source types.
232          */
233         public void updateInnerEmulationDependents() {
234                 // nothing to do in general, only local types are doing anything
235         }
236
237         /*
238          * Answer the synthetic argument for <targetEnclosingType> or null if one
239          * does not exist.
240          */
241         public SyntheticArgumentBinding getSyntheticArgument(
242                         ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
243
244                 if (enclosingInstances == null)
245                         return null; // is null if no enclosing instances are known
246
247                 // exact match
248                 for (int i = enclosingInstances.length; --i >= 0;)
249                         if (enclosingInstances[i].type == targetEnclosingType)
250                                 if (enclosingInstances[i].actualOuterLocalVariable == null)
251                                         return enclosingInstances[i];
252
253                 // type compatibility : to handle cases such as
254                 // class T { class M{}}
255                 // class S extends T { class N extends M {}} --> need to use S as a
256                 // default enclosing instance for the super constructor call in N().
257                 if (!onlyExactMatch) {
258                         for (int i = enclosingInstances.length; --i >= 0;)
259                                 if (enclosingInstances[i].actualOuterLocalVariable == null)
260                                         if (targetEnclosingType
261                                                         .isSuperclassOf((ReferenceBinding) enclosingInstances[i].type))
262                                                 return enclosingInstances[i];
263                 }
264                 return null;
265         }
266 }