/******************************************************************************* * Copyright (c) 2000, 2011 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.jdt.internal.ui.search; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.BreakStatement; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.ContinueStatement; import org.eclipse.jdt.core.dom.DoStatement; import org.eclipse.jdt.core.dom.EnhancedForStatement; import org.eclipse.jdt.core.dom.ForStatement; import org.eclipse.jdt.core.dom.Initializer; import org.eclipse.jdt.core.dom.LabeledStatement; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.TokenScanner; import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; /** * Class used to find the target for a break or continue statement according * to the language specification. *
* The target statement is a while, do, switch, for or a labeled statement. * Break is described in section 14.15 of the JLS3 and continue in section 14.16.
* * @since 3.2 */ public class BreakContinueTargetFinder extends ASTVisitor implements IOccurrencesFinder { public static final String ID= "BreakContinueTargetFinder"; //$NON-NLS-1$ private ASTNode fSelected; private boolean fIsBreak; private SimpleName fLabel; private String fDescription; private CompilationUnit fASTRoot; private static final Class>[] STOPPERS= {MethodDeclaration.class, Initializer.class}; private static final Class>[] BREAKTARGETS= {ForStatement.class, EnhancedForStatement.class, WhileStatement.class, DoStatement.class, SwitchStatement.class}; private static final Class>[] CONTINUETARGETS= {ForStatement.class, EnhancedForStatement.class, WhileStatement.class, DoStatement.class}; private static final int BRACE_LENGTH= 1; /* * Initializes the finder. Returns error message ornull
if everything is OK.
*/
public String initialize(CompilationUnit root, int offset, int length) {
return initialize(root, NodeFinder.perform(root, offset, length));
}
/*
* Initializes the finder. Returns error message or null
if everything is OK.
*/
public String initialize(CompilationUnit root, ASTNode node) {
ASTNode controlNode= getBreakOrContinueNode(node);
if (controlNode != null) {
fASTRoot= root;
try {
if (root.getTypeRoot() == null || root.getTypeRoot().getBuffer() == null)
return SearchMessages.BreakContinueTargetFinder_cannot_highlight;
} catch (JavaModelException e) {
return SearchMessages.BreakContinueTargetFinder_cannot_highlight;
}
fSelected= controlNode;
fIsBreak= fSelected instanceof BreakStatement;
fLabel= getLabel();
fDescription= Messages.format(SearchMessages.BreakContinueTargetFinder_occurrence_description, BasicElementLabels.getJavaElementName(ASTNodes.asString(fSelected)));
return null;
} else {
return SearchMessages.BreakContinueTargetFinder_no_break_or_continue_selected;
}
}
//extract the control node: handle labels
private ASTNode getBreakOrContinueNode(ASTNode selectedNode) {
if (selectedNode instanceof BreakStatement)
return selectedNode;
if (selectedNode instanceof ContinueStatement)
return selectedNode;
if (selectedNode instanceof SimpleName && selectedNode.getParent() instanceof BreakStatement)
return selectedNode.getParent();
if (selectedNode instanceof SimpleName && selectedNode.getParent() instanceof ContinueStatement)
return selectedNode.getParent();
return null;
}
private SimpleName getLabel() {
if (fIsBreak){
BreakStatement bs= (BreakStatement) fSelected;
return bs.getLabel();
} else {
ContinueStatement cs= (ContinueStatement) fSelected;
return cs.getLabel();
}
}
/**
* Returns the locations of all occurrences or null
if no matches are found
*
* @return the locations of all occurrences or null
if no matches are found
*/
public OccurrenceLocation[] getOccurrences() {
ASTNode targetNode= findTargetNode(fSelected);
if (!isEnclosingStatement(targetNode))
return null;
List