1 package no.uio.ifi.refaktor.analyze.analyzers;
3 import java.util.Collections;
4 import java.util.Comparator;
5 import java.util.LinkedList;
7 import no.uio.ifi.refaktor.analyze.exceptions.SelectionInvalidException;
8 import no.uio.ifi.refaktor.textselection.CompilationUnitTextSelection;
10 import org.eclipse.jdt.core.dom.ASTNode;
11 import org.eclipse.jdt.core.dom.ASTVisitor;
12 import org.eclipse.jdt.core.dom.Block;
13 import org.eclipse.jdt.core.dom.MethodDeclaration;
14 import org.eclipse.jdt.core.dom.Statement;
16 public class SelectionValidator extends ASTVisitor {
18 private final CompilationUnitTextSelection selection;
19 private final LinkedList<ASTNode> selectedStatements;
21 public SelectionValidator(CompilationUnitTextSelection selection) {
23 this.selection = selection;
24 this.selectedStatements = new LinkedList<ASTNode>();
25 findSelectedStatements();
28 private void findSelectedStatements() {
29 getCoveringNode().accept(this);
32 private ASTNode getCoveringNode() {
33 return selection.getCoveringNode();
36 private ASTNode getCoveredNode() {
37 return selection.getCoveredNode();
41 public boolean preVisit2(ASTNode node) {
42 if (node instanceof Statement && selection.surroundsNode(node)) {
43 selectedStatements.add(node);
44 // Only visit top-level statements
48 if (node instanceof MethodDeclaration || node instanceof Block )
54 public static void checkIfSelectionIsValid(CompilationUnitTextSelection selection) {
55 if (!selectionIsValid(selection))
56 throw new SelectionInvalidException();
59 private static boolean selectionIsValid(CompilationUnitTextSelection selection) {
60 return new SelectionValidator(selection).selectionIsValid();
63 private boolean selectionIsValid() {
64 if (noStatementsSelected())
67 if (selectedNodeHasBlockStructure())
70 return selectionMatchesStatementsStartAndEnd();
73 private boolean noStatementsSelected() {
74 return selectedStatements.isEmpty();
77 private boolean selectedNodeHasBlockStructure() {
78 return isSingleNodeSelection() &&
79 (getSelectedNode() instanceof MethodDeclaration || getSelectedNode() instanceof Block);
82 private boolean selectionMatchesStatementsStartAndEnd() {
83 sortSelectedStatements();
84 return selectedStatements.getFirst().getStartPosition() == selection.getOffset()
85 && nodeEnd(selectedStatements.getLast()) == selection.getEnd();
88 private void sortSelectedStatements() {
89 Collections.sort(selectedStatements, new Comparator<ASTNode>(){
91 public int compare(ASTNode node1, ASTNode node2) {
92 if (node1.equals(node2))
94 else if (node1.getStartPosition() < node2.getStartPosition())
96 else if (node1.getStartPosition() > node2.getStartPosition())
103 private boolean isSingleNodeSelection() {
104 return getCoveringNode() == getCoveredNode();
107 private ASTNode getSelectedNode() {
108 if (!isSingleNodeSelection())
110 return getCoveredNode();
113 private int nodeEnd(ASTNode astNode) {
114 return astNode.getStartPosition() + astNode.getLength();