/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.corext.dom; import org.eclipse.core.runtime.Assert; import org.eclipse.wst.jsdt.core.dom.ASTNode; import org.eclipse.wst.jsdt.core.dom.ASTVisitor; import org.eclipse.wst.jsdt.core.dom.BodyDeclaration; import org.eclipse.wst.jsdt.core.dom.IVariableBinding; import org.eclipse.wst.jsdt.core.dom.Initializer; import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration; import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration; import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment; /** * * Provisional API: This class/interface is part of an interim API that is still under development and expected to * change significantly before reaching stability. It is being made available at this early stage to solicit feedback * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken * (repeatedly) as the API evolves. */ public class LocalVariableIndex extends ASTVisitor { private int fTopIndex; /** * Computes the maximum number of local variable declarations in the * given body declaration. * * @param declaration the body declaration. Must either be a method * declaration or an initializer. * @return the maximum number of local variables */ public static int perform(BodyDeclaration declaration) { Assert.isTrue(declaration != null); switch (declaration.getNodeType()) { case ASTNode.FUNCTION_DECLARATION: return internalPerform((FunctionDeclaration)declaration); case ASTNode.INITIALIZER: return internalPerform((Initializer)declaration); default: Assert.isTrue(false); } return -1; } private static int internalPerform(FunctionDeclaration method) { // we have to find the outermost method declaration since a local or anonymous // type can reference final variables from the outer scope. FunctionDeclaration target= method; while (ASTNodes.getParent(target, ASTNode.FUNCTION_DECLARATION) != null) { target= (FunctionDeclaration)ASTNodes.getParent(target, ASTNode.FUNCTION_DECLARATION); } return doPerform(target); } private static int internalPerform(Initializer initializer) { return doPerform(initializer); } private static int doPerform(BodyDeclaration node) { LocalVariableIndex counter= new LocalVariableIndex(); node.accept(counter); return counter.fTopIndex; } public boolean visit(SingleVariableDeclaration node) { handleVariableBinding(node.resolveBinding()); return true; } public boolean visit(VariableDeclarationFragment node) { handleVariableBinding(node.resolveBinding()); return true; } private void handleVariableBinding(IVariableBinding binding) { if (binding == null) return; fTopIndex= Math.max(fTopIndex, binding.getVariableId()); } }