KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
14 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
15 import org.eclipse.jdt.internal.compiler.ast.Annotation;
16 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
18 import org.eclipse.jdt.internal.compiler.impl.Constant;
19 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
20
21 public class LocalVariableBinding extends VariableBinding {
22
23     public int resolvedPosition; // for code generation (position in method context)
24

25     public static final int UNUSED = 0;
26     public static final int USED = 1;
27     public static final int FAKE_USED = 2;
28     public int useFlag; // for flow analysis (default is UNUSED)
29

30     public BlockScope declaringScope; // back-pointer to its declaring scope
31
public LocalDeclaration declaration; // for source-positions
32

33     public int[] initializationPCs;
34     public int initializationCount = 0;
35
36     // for synthetic local variables
37
// if declaration slot is not positionned, the variable will not be listed in attribute
38
// note that the name of a variable should be chosen so as not to conflict with user ones (usually starting with a space char is all needed)
39
public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) {
40         super(name, type, modifiers, isArgument ? Constant.NotAConstant : null);
41         if (isArgument) this.tagBits |= TagBits.IsArgument;
42     }
43     
44     // regular local variable or argument
45
public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) {
46
47         this(declaration.name, type, modifiers, isArgument);
48         this.declaration = declaration;
49     }
50
51     /* API
52     * Answer the receiver's binding type from Binding.BindingID.
53     */

54     public final int kind() {
55
56         return LOCAL;
57     }
58     
59     /*
60      * declaringUniqueKey # scopeIndex / varName
61      * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local
62      */

63     public char[] computeUniqueKey(boolean isLeaf) {
64         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
65         
66         // declaring method or type
67
BlockScope scope = this.declaringScope;
68         if (scope != null) {
69             // the scope can be null. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=185129
70
MethodScope methodScope = scope instanceof MethodScope ? (MethodScope) scope : scope.enclosingMethodScope();
71             ReferenceContext referenceContext = methodScope.referenceContext;
72             if (referenceContext instanceof AbstractMethodDeclaration) {
73                 MethodBinding methodBinding = ((AbstractMethodDeclaration) referenceContext).binding;
74                 if (methodBinding != null) {
75                     buffer.append(methodBinding.computeUniqueKey(false/*not a leaf*/));
76                 }
77             } else if (referenceContext instanceof TypeDeclaration) {
78                 TypeBinding typeBinding = ((TypeDeclaration) referenceContext).binding;
79                 if (typeBinding != null) {
80                     buffer.append(typeBinding.computeUniqueKey(false/*not a leaf*/));
81                 }
82             }
83     
84             // scope index
85
getScopeKey(scope, buffer);
86         }
87         // variable name
88
buffer.append('#');
89         buffer.append(this.name);
90         
91         int length = buffer.length();
92         char[] uniqueKey = new char[length];
93         buffer.getChars(0, length, uniqueKey, 0);
94         return uniqueKey;
95     }
96
97     public AnnotationBinding[] getAnnotations() {
98         if (this.declaringScope == null) {
99             if ((this.tagBits & TagBits.AnnotationResolved) != 0) {
100                 // annotation are already resolved
101
if (this.declaration == null) {
102                     return Binding.NO_ANNOTATIONS;
103                 }
104                 Annotation[] annotations = this.declaration.annotations;
105                 if (annotations != null) {
106                     int length = annotations.length;
107                     AnnotationBinding[] annotationBindings = new AnnotationBinding[length];
108                     for (int i = 0; i < length; i++) {
109                         AnnotationBinding compilerAnnotation = annotations[i].getCompilerAnnotation();
110                         if (compilerAnnotation == null) {
111                             return Binding.NO_ANNOTATIONS;
112                         }
113                         annotationBindings[i] = compilerAnnotation;
114                     }
115                     return annotationBindings;
116                 }
117             }
118             return Binding.NO_ANNOTATIONS;
119         }
120         SourceTypeBinding sourceType = this.declaringScope.enclosingSourceType();
121         if (sourceType == null)
122             return Binding.NO_ANNOTATIONS;
123
124         AnnotationBinding[] annotations = sourceType.retrieveAnnotations(this);
125         if ((this.tagBits & TagBits.AnnotationResolved) == 0) {
126             if (((this.tagBits & TagBits.IsArgument) != 0) && this.declaration != null) {
127                 Annotation[] annotationNodes = declaration.annotations;
128                 if (annotationNodes != null) {
129                     int length = annotationNodes.length;
130                     ASTNode.resolveAnnotations(this.declaringScope, annotationNodes, this);
131                     annotations = new AnnotationBinding[length];
132                     for (int i = 0; i < length; i++)
133                         annotations[i] = new AnnotationBinding(annotationNodes[i]);
134                     setAnnotations(annotations);
135                 }
136             }
137         }
138         return annotations;
139     }
140
141     private void getScopeKey(BlockScope scope, StringBuffer JavaDoc buffer) {
142         int scopeIndex = scope.scopeIndex();
143         if (scopeIndex != -1) {
144             getScopeKey((BlockScope)scope.parent, buffer);
145             buffer.append('#');
146             buffer.append(scopeIndex);
147         }
148     }
149     
150     // Answer whether the variable binding is a secret variable added for code gen purposes
151
public boolean isSecret() {
152
153         return declaration == null && (this.tagBits & TagBits.IsArgument) == 0;
154     }
155
156     public void recordInitializationEndPC(int pc) {
157
158         if (initializationPCs[((initializationCount - 1) << 1) + 1] == -1)
159             initializationPCs[((initializationCount - 1) << 1) + 1] = pc;
160     }
161
162     public void recordInitializationStartPC(int pc) {
163
164         if (initializationPCs == null) return;
165         if (initializationCount > 0) {
166             int previousEndPC = initializationPCs[ ((initializationCount - 1) << 1) + 1];
167              // interval still open, keep using it (108180)
168
if (previousEndPC == -1) {
169                 return;
170             }
171             // optimize cases where reopening a contiguous interval
172
if (previousEndPC == pc) {
173                 initializationPCs[ ((initializationCount - 1) << 1) + 1] = -1; // reuse previous interval (its range will be augmented)
174
return;
175             }
176         }
177         int index = initializationCount << 1;
178         if (index == initializationPCs.length) {
179             System.arraycopy(initializationPCs, 0, (initializationPCs = new int[initializationCount << 2]), 0, index);
180         }
181         initializationPCs[index] = pc;
182         initializationPCs[index + 1] = -1;
183         initializationCount++;
184     }
185
186     public void setAnnotations(AnnotationBinding[] annotations) {
187         if (this.declaringScope == null) return;
188
189         SourceTypeBinding sourceType = this.declaringScope.enclosingSourceType();
190         if (sourceType != null)
191             sourceType.storeAnnotations(this, annotations);
192     }
193
194     public String JavaDoc toString() {
195
196         String JavaDoc s = super.toString();
197         switch (useFlag){
198             case USED:
199                 s += "[pos: " + String.valueOf(resolvedPosition) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
200
break;
201             case UNUSED:
202                 s += "[pos: unused]"; //$NON-NLS-1$
203
break;
204             case FAKE_USED:
205                 s += "[pos: fake_used]"; //$NON-NLS-1$
206
break;
207         }
208         s += "[id:" + String.valueOf(id) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
209
if (initializationCount > 0) {
210             s += "[pc: "; //$NON-NLS-1$
211
for (int i = 0; i < initializationCount; i++) {
212                 if (i > 0)
213                     s += ", "; //$NON-NLS-1$
214
s += String.valueOf(initializationPCs[i << 1]) + "-" + ((initializationPCs[(i << 1) + 1] == -1) ? "?" : String.valueOf(initializationPCs[(i<< 1) + 1])); //$NON-NLS-2$ //$NON-NLS-1$
215
}
216             s += "]"; //$NON-NLS-1$
217
}
218         return s;
219     }
220 }
221
Popular Tags