KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > lookup > NestedTypeBinding


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 public class NestedTypeBinding extends SourceTypeBinding {
14
15     public SourceTypeBinding enclosingType;
16
17     public SyntheticArgumentBinding[] enclosingInstances;
18     public SyntheticArgumentBinding[] outerLocalVariables;
19     public int enclosingInstancesSlotSize; // amount of slots used by synthetic enclosing instances
20
public int outerLocalVariablesSlotSize; // amount of slots used by synthetic outer local variables
21

22     public NestedTypeBinding(char[][] typeName, ClassScope scope, SourceTypeBinding enclosingType) {
23         super(typeName, enclosingType.fPackage, scope);
24         this.tagBits |= TagBits.IsNestedType;
25         this.enclosingType = enclosingType;
26     }
27     
28     /* Add a new synthetic argument for <actualOuterLocalVariable>.
29     * Answer the new argument or the existing argument if one already existed.
30     */

31     public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
32         SyntheticArgumentBinding synthLocal = null;
33     
34         if (outerLocalVariables == null) {
35             synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
36             outerLocalVariables = new SyntheticArgumentBinding[] {synthLocal};
37         } else {
38             int size = outerLocalVariables.length;
39             int newArgIndex = size;
40             for (int i = size; --i >= 0;) { // must search backwards
41
if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
42                     return outerLocalVariables[i]; // already exists
43
if (outerLocalVariables[i].id > actualOuterLocalVariable.id)
44                     newArgIndex = i;
45             }
46             SyntheticArgumentBinding[] synthLocals = new SyntheticArgumentBinding[size + 1];
47             System.arraycopy(outerLocalVariables, 0, synthLocals, 0, newArgIndex);
48             synthLocals[newArgIndex] = synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
49             System.arraycopy(outerLocalVariables, newArgIndex, synthLocals, newArgIndex + 1, size - newArgIndex);
50             outerLocalVariables = synthLocals;
51         }
52         //System.out.println("Adding synth arg for local var: " + new String(actualOuterLocalVariable.name) + " to: " + new String(this.readableName()));
53
if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
54             this.updateInnerEmulationDependents();
55         return synthLocal;
56     }
57
58     /* Add a new synthetic argument for <enclosingType>.
59     * Answer the new argument or the existing argument if one already existed.
60     */

61     public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding targetEnclosingType) {
62         SyntheticArgumentBinding synthLocal = null;
63         if (enclosingInstances == null) {
64             synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
65             enclosingInstances = new SyntheticArgumentBinding[] {synthLocal};
66         } else {
67             int size = enclosingInstances.length;
68             int newArgIndex = size;
69             for (int i = size; --i >= 0;) {
70                 if (enclosingInstances[i].type == targetEnclosingType)
71                     return enclosingInstances[i]; // already exists
72
if (this.enclosingType() == targetEnclosingType)
73                     newArgIndex = 0;
74             }
75             SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1];
76             System.arraycopy(enclosingInstances, 0, newInstances, newArgIndex == 0 ? 1 : 0, size);
77             newInstances[newArgIndex] = synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
78             enclosingInstances = newInstances;
79         }
80         //System.out.println("Adding synth arg for enclosing type: " + new String(enclosingType.readableName()) + " to: " + new String(this.readableName()));
81
if (scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
82             this.updateInnerEmulationDependents();
83         return synthLocal;
84     }
85
86     /* Add a new synthetic argument and field for <actualOuterLocalVariable>.
87     * Answer the new argument or the existing argument if one already existed.
88     */

89     public SyntheticArgumentBinding addSyntheticArgumentAndField(LocalVariableBinding actualOuterLocalVariable) {
90         SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable);
91         if (synthLocal == null) return null;
92     
93         if (synthLocal.matchingField == null)
94             synthLocal.matchingField = addSyntheticFieldForInnerclass(actualOuterLocalVariable);
95         return synthLocal;
96     }
97
98     /* Add a new synthetic argument and field for <enclosingType>.
99     * Answer the new argument or the existing argument if one already existed.
100     */

101     public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding targetEnclosingType) {
102         SyntheticArgumentBinding synthLocal = addSyntheticArgument(targetEnclosingType);
103         if (synthLocal == null) return null;
104     
105         if (synthLocal.matchingField == null)
106             synthLocal.matchingField = addSyntheticFieldForInnerclass(targetEnclosingType);
107         return synthLocal;
108     }
109
110     /**
111      * Compute the resolved positions for all the synthetic arguments
112      */

113     final public void computeSyntheticArgumentSlotSizes() {
114     
115         int slotSize = 0;
116         // insert enclosing instances first, followed by the outerLocals
117
int enclosingInstancesCount = this.enclosingInstances == null ? 0 : this.enclosingInstances.length;
118         for (int i = 0; i < enclosingInstancesCount; i++){
119             SyntheticArgumentBinding argument = this.enclosingInstances[i];
120             // position the enclosing instance synthetic arg
121
argument.resolvedPosition = slotSize + 1; // shift by 1 to leave room for aload0==this
122
if (slotSize + 1 > 0xFF) { // no more than 255 words of arguments
123
this.scope.problemReporter().noMoreAvailableSpaceForArgument(argument, this.scope.referenceType());
124             }
125             if ((argument.type == TypeBinding.LONG) || (argument.type == TypeBinding.DOUBLE)){
126                 slotSize += 2;
127             } else {
128                 slotSize ++;
129             }
130         }
131         this.enclosingInstancesSlotSize = slotSize;
132         
133         slotSize = 0; // reset, outer local are not positionned yet, since will be appended to user arguments
134
int outerLocalsCount = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length;
135             for (int i = 0; i < outerLocalsCount; i++){
136             SyntheticArgumentBinding argument = this.outerLocalVariables[i];
137             // do NOT position the outerlocal synthetic arg yet, since will be appended to user arguments
138
if ((argument.type == TypeBinding.LONG) || (argument.type == TypeBinding.DOUBLE)){
139                 slotSize += 2;
140             } else {
141                 slotSize ++;
142             }
143         }
144         this.outerLocalVariablesSlotSize = slotSize;
145     }
146     
147     /* Answer the receiver's enclosing type... null if the receiver is a top level type.
148     */

149     public ReferenceBinding enclosingType() {
150
151         return enclosingType;
152     }
153
154     /* Answer the synthetic argument for <actualOuterLocalVariable> or null if one does not exist.
155     */

156     public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
157
158         if (outerLocalVariables == null) return null; // is null if no outer local variables are known
159

160         for (int i = outerLocalVariables.length; --i >= 0;)
161             if (outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
162                 return outerLocalVariables[i];
163         return null;
164     }
165
166     public SyntheticArgumentBinding[] syntheticEnclosingInstances() {
167         return enclosingInstances; // is null if no enclosing instances are required
168
}
169
170     public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
171         if (enclosingInstances == null)
172             return null;
173     
174         int length = enclosingInstances.length;
175         ReferenceBinding types[] = new ReferenceBinding[length];
176         for (int i = 0; i < length; i++)
177             types[i] = (ReferenceBinding) enclosingInstances[i].type;
178         return types;
179     }
180
181     public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
182
183         return outerLocalVariables; // is null if no outer locals are required
184
}
185
186     /*
187      * Trigger the dependency mechanism forcing the innerclass emulation
188      * to be propagated to all dependent source types.
189      */

190     public void updateInnerEmulationDependents() {
191         // nothing to do in general, only local types are doing anything
192
}
193     
194     /* Answer the synthetic argument for <targetEnclosingType> or null if one does not exist.
195     */

196     public SyntheticArgumentBinding getSyntheticArgument(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
197
198         if (enclosingInstances == null) return null; // is null if no enclosing instances are known
199

200         // exact match
201
for (int i = enclosingInstances.length; --i >= 0;)
202             if (enclosingInstances[i].type == targetEnclosingType)
203                 if (enclosingInstances[i].actualOuterLocalVariable == null)
204                     return enclosingInstances[i];
205     
206         // type compatibility : to handle cases such as
207
// class T { class M{}}
208
// class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
209
if (!onlyExactMatch){
210             for (int i = enclosingInstances.length; --i >= 0;)
211                 if (enclosingInstances[i].actualOuterLocalVariable == null)
212                     if (enclosingInstances[i].type.findSuperTypeWithSameErasure(targetEnclosingType) != null)
213                         return enclosingInstances[i];
214         }
215         return null;
216     }
217 }
218
Popular Tags