1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.lookup;
13 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
14 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
15 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
16 import org.eclipse.jdt.internal.compiler.impl.Constant;
17 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
19 public class LocalVariableBinding extends VariableBinding {
21 public boolean isArgument;
22 public int resolvedPosition; // for code generation (position in method context)
24 public static final int UNUSED = 0;
25 public static final int USED = 1;
26 public static final int FAKE_USED = 2;
27 public int useFlag; // for flow analysis (default is UNUSED)
29 public BlockScope declaringScope; // back-pointer to its declaring scope
30 public LocalDeclaration declaration; // for source-positions
32 public int[] initializationPCs;
33 public int initializationCount = 0;
35 // for synthetic local variables
36 // if declaration slot is not positionned, the variable will not be listed in attribute
37 // 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)
38 public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) {
39 super(name, type, modifiers, isArgument ? Constant.NotAConstant : null);
40 this.isArgument = isArgument;
43 // regular local variable or argument
44 public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) {
46 this(declaration.name, type, modifiers, isArgument);
47 this.declaration = declaration;
51 * Answer the receiver's binding type from Binding.BindingID.
53 public final int kind() {
59 * declaringUniqueKey # scopeIndex / varName
60 * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local
62 public char[] computeUniqueKey() {
63 StringBuffer buffer = new StringBuffer();
65 // declaring method or type
66 BlockScope scope = this.declaringScope;
67 MethodScope methodScope = scope instanceof MethodScope ? (MethodScope) scope : scope.enclosingMethodScope();
68 ReferenceContext referenceContext = methodScope.referenceContext;
69 if (referenceContext instanceof AbstractMethodDeclaration) {
70 MethodBinding methodBinding = ((AbstractMethodDeclaration) referenceContext).binding;
71 if (methodBinding != null) {
72 buffer.append(methodBinding.computeUniqueKey());
74 } else if (referenceContext instanceof TypeDeclaration) {
75 TypeBinding typeBinding = ((TypeDeclaration) referenceContext).binding;
76 if (typeBinding != null) {
77 buffer.append(typeBinding.computeUniqueKey());
82 getScopeKey(scope, buffer);
86 buffer.append(this.name);
88 int length = buffer.length();
89 char[] uniqueKey = new char[length];
90 buffer.getChars(0, length, uniqueKey, 0);
94 private void getScopeKey(BlockScope scope, StringBuffer buffer) {
95 int scopeIndex = scope.scopeIndex();
96 if (scopeIndex != -1) {
97 getScopeKey((BlockScope)scope.parent, buffer);
99 buffer.append(scopeIndex);
103 // Answer whether the variable binding is a secret variable added for code gen purposes
104 public boolean isSecret() {
106 return declaration == null && !isArgument;
109 public void recordInitializationEndPC(int pc) {
111 if (initializationPCs[((initializationCount - 1) << 1) + 1] == -1)
112 initializationPCs[((initializationCount - 1) << 1) + 1] = pc;
115 public void recordInitializationStartPC(int pc) {
117 if (initializationPCs == null) return;
118 // optimize cases where reopening a contiguous interval
119 if ((initializationCount > 0) && (initializationPCs[ ((initializationCount - 1) << 1) + 1] == pc)) {
120 initializationPCs[ ((initializationCount - 1) << 1) + 1] = -1; // reuse previous interval (its range will be augmented)
122 int index = initializationCount << 1;
123 if (index == initializationPCs.length) {
124 System.arraycopy(initializationPCs, 0, (initializationPCs = new int[initializationCount << 2]), 0, index);
126 initializationPCs[index] = pc;
127 initializationPCs[index + 1] = -1;
128 initializationCount++;
132 public String toString() {
134 String s = super.toString();
137 s += "[pos: " + String.valueOf(resolvedPosition) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
140 s += "[pos: unused]"; //$NON-NLS-1$
143 s += "[pos: fake_used]"; //$NON-NLS-1$
146 s += "[id:" + String.valueOf(id) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
147 if (initializationCount > 0) {
148 s += "[pc: "; //$NON-NLS-1$
149 for (int i = 0; i < initializationCount; i++) {
151 s += ", "; //$NON-NLS-1$
152 s += String.valueOf(initializationPCs[i << 1]) + "-" + ((initializationPCs[(i << 1) + 1] == -1) ? "?" : String.valueOf(initializationPCs[(i<< 1) + 1])); //$NON-NLS-2$ //$NON-NLS-1$
154 s += "]"; //$NON-NLS-1$