/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.lookup; import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration; import net.sourceforge.phpdt.internal.compiler.impl.Constant; public class LocalVariableBinding extends VariableBinding { public boolean isArgument; public int resolvedPosition; // for code generation (position in method // context) public static final int UNUSED = 0; public static final int USED = 1; public static final int FAKE_USED = 2; public int useFlag; // for flow analysis (default is UNUSED) public BlockScope declaringScope; // back-pointer to its declaring scope public LocalDeclaration declaration; // for source-positions public int[] initializationPCs; public int initializationCount = 0; // for synthetic local variables public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) { this.name = name; this.type = type; this.modifiers = modifiers; if (this.isArgument = isArgument) this.constant = Constant.NotAConstant; } // regular local variable or argument public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) { this(declaration.name, type, modifiers, isArgument); this.declaration = declaration; } /* * API Answer the receiver's binding type from Binding.BindingID. */ public final int bindingType() { return LOCAL; } // Answer whether the variable binding is a secret variable added for code // gen purposes public boolean isSecret() { return declaration == null && !isArgument; } public void recordInitializationEndPC(int pc) { if (initializationPCs[((initializationCount - 1) << 1) + 1] == -1) initializationPCs[((initializationCount - 1) << 1) + 1] = pc; } public void recordInitializationStartPC(int pc) { if (initializationPCs == null) return; // optimize cases where reopening a contiguous interval if ((initializationCount > 0) && (initializationPCs[((initializationCount - 1) << 1) + 1] == pc)) { initializationPCs[((initializationCount - 1) << 1) + 1] = -1; // reuse // previous // interval // (its // range // will // be // augmented) } else { int index = initializationCount << 1; if (index == initializationPCs.length) { System .arraycopy( initializationPCs, 0, (initializationPCs = new int[initializationCount << 2]), 0, index); } initializationPCs[index] = pc; initializationPCs[index + 1] = -1; initializationCount++; } } public String toString() { String s = super.toString(); switch (useFlag) { case USED: s += "[pos: " + String.valueOf(resolvedPosition) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ break; case UNUSED: s += "[pos: unused]"; //$NON-NLS-1$ break; case FAKE_USED: s += "[pos: fake_used]"; //$NON-NLS-1$ break; } s += "[id:" + String.valueOf(id) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ if (initializationCount > 0) { s += "[pc: "; //$NON-NLS-1$ for (int i = 0; i < initializationCount; i++) { if (i > 0) s += ", "; //$NON-NLS-1$ s += String.valueOf(initializationPCs[i << 1]) + "-" + ((initializationPCs[(i << 1) + 1] == -1) ? "?" : String.valueOf(initializationPCs[(i << 1) + 1])); //$NON-NLS-2$ //$NON-NLS-1$ } s += "]"; //$NON-NLS-1$ } return s; } }