--- /dev/null
+package no.uio.ifi.refaktor.analyze.checkers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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.textselection.CompilationUnitTextSelection;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+
+class AmbiguousReturnValueChecker extends PropertyCollector implements Checker {
+
+ private class AssigneesUsedOutsideSelectionChecker extends PropertyCollector {
+
+ private final Set<String> referrals;
+
+ public AssigneesUsedOutsideSelectionChecker(CompilationUnitTextSelection selection) {
+ super(selection);
+ referrals = new HashSet<String>();
+ }
+
+ @Override
+ public void clearData() {
+ referrals.clear();
+ }
+
+ @Override
+ public boolean visit(SimpleName node) {
+ if (nodeInSelectionOrBefore(node))
+ return false;
+
+ IBinding binding = node.resolveBinding();
+
+ if (binding instanceof IVariableBinding && assigneesBindingKeys.contains(binding.getKey())) {
+ referrals.add(binding.getKey());
+ if (selectionContainsReturn || referrals.size() > 1)
+ throw new IllegalStatementFoundException(SimpleName.class);
+ }
+
+ return true;
+ }
+
+ private boolean nodeInSelectionOrBefore(ASTNode node) {
+ return nodeInSelection(node) || nodeBeforeSelection(node);
+ }
+
+ private boolean nodeBeforeSelection(ASTNode node) {
+ int nodeEndPosition = node.getStartPosition() + node.getLength();
+ return node.getStartPosition() < selection.getOffset() && nodeEndPosition < selection.getOffset();
+ }
+
+ }
+
+ private final Set<String> assigneesBindingKeys;
+ private boolean selectionContainsReturn;
+
+ public AmbiguousReturnValueChecker(CompilationUnitTextSelection selection) {
+ super(selection);
+ assigneesBindingKeys = new HashSet<String>();
+ selectionContainsReturn = false;
+ }
+
+ @Override
+ public void check() throws IllegalStatementFoundException, IllegalExpressionFoundException {
+ CollectorManager.collectProperties(selection, this);
+ CollectorManager.collectPropertiesFromEnclosingMethod(selection, new AssigneesUsedOutsideSelectionChecker(selection));
+ }
+
+ @Override
+ public void clearData() {
+ assigneesBindingKeys.clear();
+ selectionContainsReturn = false;
+ }
+
+ @Override
+ public boolean visit(Assignment node) {
+ if (!nodeInSelection(node))
+ return false;
+
+ if (node.getLeftHandSide() instanceof SimpleName) {
+ SimpleName name = (SimpleName) node.getLeftHandSide();
+ IBinding binding = name.resolveBinding();
+ assert binding instanceof IVariableBinding;
+ if (!((IVariableBinding) binding).isField())
+ assigneesBindingKeys.add(binding.getKey());
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(VariableDeclarationFragment node) {
+ if (!nodeInSelection(node))
+ return false;
+
+ IBinding binding = node.getName().resolveBinding();
+ assert binding instanceof IVariableBinding;
+ assigneesBindingKeys.add(binding.getKey());
+
+ return true;
+ }
+
+ @Override
+ public boolean visit(ReturnStatement node) {
+ if (!nodeInSelection(node))
+ return false;
+
+ selectionContainsReturn = true;
+ return true;
+ }
+}
+