1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.javaeditor.selectionactions;
13 import org.eclipse.ui.PlatformUI;
15 import org.eclipse.jdt.core.ISourceRange;
16 import org.eclipse.jdt.core.ISourceReference;
17 import org.eclipse.jdt.core.JavaModelException;
18 import org.eclipse.jdt.core.dom.ASTNode;
20 import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
21 import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
23 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
24 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
26 public class StructureSelectPreviousAction extends StructureSelectionAction {
28 private static class PreviousNodeAnalyzer extends GenericVisitor {
29 private final int fOffset;
30 private ASTNode fPreviousNode;
31 private PreviousNodeAnalyzer(int offset) {
35 public static ASTNode perform(int offset, ASTNode lastCoveringNode) {
36 PreviousNodeAnalyzer analyzer= new PreviousNodeAnalyzer(offset);
37 lastCoveringNode.accept(analyzer);
38 return analyzer.fPreviousNode;
41 protected boolean visitNode(ASTNode node) {
42 int start= node.getStartPosition();
43 int end= start + node.getLength();
48 return (start < fOffset && fOffset < end);
53 public StructureSelectPreviousAction(JavaEditor editor, SelectionHistory history) {
54 super(SelectionActionMessages.StructureSelectPrevious_label, editor, history);
55 setToolTipText(SelectionActionMessages.StructureSelectPrevious_tooltip);
56 setDescription(SelectionActionMessages.StructureSelectPrevious_description);
57 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.STRUCTURED_SELECT_PREVIOUS_ACTION);
61 * This constructor is for testing purpose only.
63 public StructureSelectPreviousAction() {
67 * @see StructureSelectionAction#internalGetNewSelectionRange(ISourceRange, ICompilationUnit, SelectionAnalyzer)
70 ISourceRange internalGetNewSelectionRange(ISourceRange oldSourceRange, ISourceReference sr, SelectionAnalyzer selAnalyzer) throws JavaModelException{
71 if (oldSourceRange.getLength() == 0 && selAnalyzer.getLastCoveringNode() != null) {
72 ASTNode previousNode= PreviousNodeAnalyzer.perform(oldSourceRange.getOffset(), selAnalyzer.getLastCoveringNode());
73 if (previousNode != null)
74 return getSelectedNodeSourceRange(sr, previousNode);
76 ASTNode first= selAnalyzer.getFirstSelectedNode();
78 return getLastCoveringNodeRange(oldSourceRange, sr, selAnalyzer);
80 ASTNode parent= first.getParent();
82 return getLastCoveringNodeRange(oldSourceRange, sr, selAnalyzer);
84 ASTNode previousNode= getPreviousNode(parent, selAnalyzer.getSelectedNodes()[0]);
85 if (previousNode == parent)
86 return getSelectedNodeSourceRange(sr, parent);
88 int offset= previousNode.getStartPosition();
89 int end= oldSourceRange.getOffset() + oldSourceRange.getLength() - 1;
90 return StructureSelectionAction.createSourceRange(offset, end);
93 private static ASTNode getPreviousNode(ASTNode parent, ASTNode node){
94 ASTNode[] siblingNodes= StructureSelectionAction.getSiblingNodes(node);
95 if (siblingNodes == null || siblingNodes.length == 0)
97 if (node == siblingNodes[0]) {
100 int index= StructureSelectionAction.findIndex(siblingNodes, node);
103 return siblingNodes[index - 1];