package no.uio.ifi.refaktor.analyze.analyzers; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import no.uio.ifi.refaktor.analyze.CollectorManager; import no.uio.ifi.refaktor.analyze.collectors.PrefixesCollector; import no.uio.ifi.refaktor.analyze.collectors.SelectionValidator; import no.uio.ifi.refaktor.analyze.collectors.UnfixesCollector; import no.uio.ifi.refaktor.analyze.exceptions.NoTargetFoundException; import no.uio.ifi.refaktor.change.ExtractAndMoveMethodChanger; import no.uio.ifi.refaktor.changers.exceptions.RefaktorChangerException; import no.uio.ifi.refaktor.prefix.Prefix; import no.uio.ifi.refaktor.prefix.PrefixSet; import no.uio.ifi.refaktor.utils.CompilationUnitTextSelection; import org.eclipse.jdt.core.dom.IVariableBinding; //TODO: rewrite docs /** * A property extractor that collects all the expression prefixes within a selection * (see {@link PrefixesCollector}) that forms the base for calculating the * candidates for the move refactoring, and also the unfixes * that are non-candidates for the move refactoring. * * The set of prefixes that are not enclosing any unfixes is put in the set of safe prefixes. * This set is used by an Extract and Move Method refactoring to find a suitable target * for the Move Method. * * The class is typically used by the {@link ExtractAndMoveMethodChanger}. */ public class ExtractAndMoveMethodAnalyzer implements Analyzer { private final CompilationUnitTextSelection selection; private final PrefixesCollector prefixesCollector; private final UnfixesCollector unfixesCollector; public ExtractAndMoveMethodAnalyzer(CompilationUnitTextSelection selection) { this.selection = selection; prefixesCollector = new PrefixesCollector(selection); unfixesCollector = new UnfixesCollector(selection); } public PrefixSet calculateSafePrefixes() { return prefixesCollector.getPrefixes().minusEnclosedPrefixesFrom(unfixesCollector.getUnfixes()); } protected PrefixSet getPrefixes() { return prefixesCollector.getPrefixes(); } public PrefixSet getUnfixes() { return unfixesCollector.getUnfixes(); } public void checkPreconditions() throws RefaktorChangerException { SelectionValidator.checkIfSelectionIsValid(selection); analyze(); checkIfUsefulTargetFound(); } private void checkIfUsefulTargetFound() { if (!hasUsefulResults()) throw new NoTargetFoundException(); } public boolean hasUsefulResults() { return !calculateSafePrefixes().isEmpty(); } @Override public void analyze() { CollectorManager.collectProperties(selection, prefixesCollector, unfixesCollector); } public IVariableBinding calculateOriginalTarget() { return calculateMostFrequentPrefix().getVariableBindingOfFirstExpression(); } public Prefix calculateMostFrequentPrefix() { LinkedList listOfSafePrefixes = calculateListOfSafePrefixes(); sortAscendingByCountAndLength(listOfSafePrefixes); return listOfSafePrefixes.getLast(); } private LinkedList calculateListOfSafePrefixes() { return calculateSafePrefixes().toList(); } private void sortAscendingByCountAndLength(LinkedList values) { Collections.sort(values, new Comparator() { @Override public int compare(Prefix p1, Prefix p2) { if (p1.getCount() > p2.getCount()) { return 1; } else if (p1.getCount() < p2.getCount()) { return -1; } else if (p1.length() > p2.length()) { return 1; } else if (p1.length() < p2.length()) { return -1; } return 0; } }); } }