package no.uio.ifi.refaktor.analyze.checkers; import no.uio.ifi.refaktor.analyze.CollectorManager; import no.uio.ifi.refaktor.analyze.collectors.PropertyCollector; import no.uio.ifi.refaktor.analyze.exceptions.IllegalExpressionFoundException; import no.uio.ifi.refaktor.analyze.exceptions.IllegalStatementFoundException; import no.uio.ifi.refaktor.analyze.matchers.InstanceOfMatcher; import no.uio.ifi.refaktor.analyze.matchers.LoopStatementMatcher; import no.uio.ifi.refaktor.analyze.matchers.OrInstanceOfMatcher; import no.uio.ifi.refaktor.analyze.matchers.SwitchStatementMatcher; import no.uio.ifi.refaktor.textselection.CompilationUnitTextSelection; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ArrayAccess; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.BreakStatement; import org.eclipse.jdt.core.dom.ContinueStatement; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.LabeledStatement; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; public class IllegalStatementsChecker extends PropertyCollector implements Checker { public IllegalStatementsChecker(CompilationUnitTextSelection selection) { super(selection); } @Override public void check() throws IllegalStatementFoundException, IllegalExpressionFoundException { CollectorManager.collectProperties(selection, this); } @Override public void clearData() { } @Override public boolean visit(SuperConstructorInvocation node) { if (!nodeInSelection(node)) return false; throw new IllegalStatementFoundException(node); } @Override public boolean visit(SuperMethodInvocation node) { if (!nodeInSelection(node)) return false; throw new IllegalExpressionFoundException(node); } @Override public boolean visit(SuperFieldAccess node) { if (!nodeInSelection(node)) return false; throw new IllegalExpressionFoundException(node); } @Override public boolean visit(BreakStatement node) { if (!nodeInSelection(node)) return false; if (node.getLabel() != null) { checkThatCorrespondingLabelStatementIsInSelection(node, node.getLabel()); } else { checkThatInnermostMatchingStatementIsInSelection(node, new OrInstanceOfMatcher(new LoopStatementMatcher(), new SwitchStatementMatcher())); } return true; } @Override public boolean visit(ContinueStatement node) { if (!nodeInSelection(node)) return false; if (node.getLabel() != null) { checkThatCorrespondingLabelStatementIsInSelection(node, node.getLabel()); } else { checkThatInnermostMatchingStatementIsInSelection(node, new LoopStatementMatcher()); } return true; } private void checkThatCorrespondingLabelStatementIsInSelection(ASTNode node, SimpleName nodeLabel) { ASTNode parent = node.getParent(); while (!parentMatchesLabel(parent, nodeLabel) && parent != node.getRoot()) parent = parent.getParent(); if (parent == node.getRoot() || !nodeInSelection(parent)) throw new IllegalStatementFoundException(node); } private boolean parentMatchesLabel(ASTNode parent, SimpleName nodeLabel) { return parent instanceof LabeledStatement && labelsMatches((LabeledStatement) parent, nodeLabel); } private boolean labelsMatches(LabeledStatement parentLabelStatement, SimpleName nodeLabel) { return parentLabelStatement.getLabel().getIdentifier().equals(nodeLabel.getIdentifier()); } private void checkThatInnermostMatchingStatementIsInSelection(ASTNode node, InstanceOfMatcher matcher) { ASTNode parent = node.getParent(); while (!matcher.matches(parent) && parent != node.getRoot()) parent = parent.getParent(); if (parent == node.getRoot()) throw new IllegalStatementFoundException(node); assert parent instanceof Statement; if (!nodeInSelection(parent)) throw new IllegalStatementFoundException(node); } @Override public boolean visit(Assignment node) { if (!nodeInSelection(node)) return false; if (assignmentIsLegal(node)) return true; throw new IllegalStatementFoundException(node); } private boolean assignmentIsLegal(Assignment node) { Expression lhs = node.getLeftHandSide(); if (lhs instanceof SimpleName) { SimpleName simpleName = (SimpleName) lhs; IBinding binding = simpleName.resolveBinding(); assert binding != null; // TODO: refine return !Modifier.isFinal(binding.getModifiers()); } else if (lhs instanceof QualifiedName || lhs instanceof ArrayAccess) { return true; } return false; } }