]> git.uio.no Git - ifi-stolz-refaktor.git/blame - software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/analyze/analyzers/ExtractAndMoveMethodAnalyzer.java
Adding checks for return statements. (A lot.)
[ifi-stolz-refaktor.git] / software / no.uio.ifi.refaktor / src / no / uio / ifi / refaktor / analyze / analyzers / ExtractAndMoveMethodAnalyzer.java
CommitLineData
33b364ef 1package no.uio.ifi.refaktor.analyze.analyzers;
64970e7f 2
e411ecf3
EK
3import java.util.Collections;
4import java.util.Comparator;
e09f9054 5import java.util.Iterator;
e411ecf3 6import java.util.LinkedList;
2f82d251 7
33b364ef 8import no.uio.ifi.refaktor.analyze.CollectorManager;
5748b416 9import no.uio.ifi.refaktor.analyze.collectors.BranchingStatementsChecker;
fc35e1b0
EK
10import no.uio.ifi.refaktor.analyze.collectors.PrefixesCollector;
11import no.uio.ifi.refaktor.analyze.collectors.SelectionValidator;
12import no.uio.ifi.refaktor.analyze.collectors.UnfixesCollector;
ee0f23c0 13import no.uio.ifi.refaktor.analyze.exceptions.NoTargetFoundException;
a554b0ce 14import no.uio.ifi.refaktor.analyze.exceptions.RefaktorAnalyzerException;
2b4a9262 15import no.uio.ifi.refaktor.change.changers.ExtractAndMoveMethodChanger;
e411ecf3 16import no.uio.ifi.refaktor.prefix.Prefix;
e0fe6563 17import no.uio.ifi.refaktor.prefix.PrefixSet;
1d39ea7d 18import no.uio.ifi.refaktor.utils.CompilationUnitTextSelection;
64970e7f 19
0b904053
EK
20import org.eclipse.jdt.core.dom.IVariableBinding;
21
fc35e1b0 22//TODO: rewrite docs
7a978020 23/**
520985c2
EK
24 * A property extractor that collects all the expression prefixes within a selection
25 * (see {@link PrefixesCollector}) that forms the base for calculating the
26 * candidates for the move refactoring, and also the unfixes
27 * that are non-candidates for the move refactoring.
28 *
29 * The set of prefixes that are not enclosing any unfixes is put in the set of safe prefixes.
30 * This set is used by an Extract and Move Method refactoring to find a suitable target
31 * for the Move Method.
32 *
33 * The class is typically used by the {@link ExtractAndMoveMethodChanger}.
7a978020 34 */
fc35e1b0 35public class ExtractAndMoveMethodAnalyzer implements Analyzer {
64970e7f 36
ee6a0b5b 37 private final CompilationUnitTextSelection selection;
05d2dee5
EK
38 private final PrefixesCollector prefixesCollector;
39 private final UnfixesCollector unfixesCollector;
64970e7f 40
fc35e1b0 41 public ExtractAndMoveMethodAnalyzer(CompilationUnitTextSelection selection) {
ee6a0b5b 42 this.selection = selection;
2f82d251
EK
43 prefixesCollector = new PrefixesCollector(selection);
44 unfixesCollector = new UnfixesCollector(selection);
64970e7f 45 }
74581229 46
95330826 47 public PrefixSet calculateSafePrefixes() {
e09f9054
EK
48 PrefixSet safePrefixes = prefixesCollector.getPrefixes().minusEnclosedPrefixesFrom(unfixesCollector.getUnfixes());
49 removeUnusablePrefixes(safePrefixes);
50 return safePrefixes;
51 }
52
53 private void removeUnusablePrefixes(PrefixSet safePrefixes) {
54 for (Iterator<Prefix> iter = safePrefixes.iterator(); iter.hasNext();) {
55 if (prefixHasSimpleExpressionAndOnlyOneOccurrence(iter.next()))
56 iter.remove();
57 }
58 }
59
60 private boolean prefixHasSimpleExpressionAndOnlyOneOccurrence(Prefix prefix) {
61 return prefix.getNumberOfSegments() == 1 && prefix.getCount() == 1;
087a79bf 62 }
c4d4c07b
EK
63
64 protected PrefixSet getPrefixes() {
65 return prefixesCollector.getPrefixes();
66 }
67
34328ca2 68 public PrefixSet getUnfixes() {
c4d4c07b
EK
69 return unfixesCollector.getUnfixes();
70 }
e411ecf3 71
5748b416 72 public void checkPreconditions() throws RefaktorAnalyzerException {
e15b42b4
EK
73 SelectionValidator.checkIfSelectionIsValid(selection);
74 analyze();
75 checkIfUsefulTargetFound();
76 }
77
78 private void checkIfUsefulTargetFound() {
79 if (!hasUsefulResults())
80 throw new NoTargetFoundException();
81 }
82
b0b82148 83 public boolean hasUsefulResults() {
e15b42b4
EK
84 return !calculateSafePrefixes().isEmpty();
85 }
86
87 @Override
a554b0ce 88 public void analyze() throws RefaktorAnalyzerException {
5748b416
EK
89 BranchingStatementsChecker branchingStatementsChecker = new BranchingStatementsChecker(selection);
90 if (branchingStatementsChecker.allStatementsOK())
91 CollectorManager.collectProperties(selection, prefixesCollector, unfixesCollector);
e15b42b4
EK
92 }
93
94 public IVariableBinding calculateOriginalTarget() {
95 return calculateMostFrequentPrefix().getVariableBindingOfFirstExpression();
96 }
97
34328ca2 98 public Prefix calculateMostFrequentPrefix() {
e15b42b4 99 LinkedList<Prefix> listOfSafePrefixes = calculateListOfSafePrefixes();
e411ecf3
EK
100 sortAscendingByCountAndLength(listOfSafePrefixes);
101 return listOfSafePrefixes.getLast();
102 }
103
e15b42b4 104 private LinkedList<Prefix> calculateListOfSafePrefixes() {
95330826 105 return calculateSafePrefixes().toList();
e411ecf3
EK
106 }
107
108 private void sortAscendingByCountAndLength(LinkedList<Prefix> values) {
109 Collections.sort(values, new Comparator<Prefix>() {
110 @Override
111 public int compare(Prefix p1, Prefix p2) {
112 if (p1.getCount() > p2.getCount()) {
113 return 1;
114 } else if (p1.getCount() < p2.getCount()) {
115 return -1;
116 } else if (p1.length() > p2.length()) {
117 return 1;
118 } else if (p1.length() < p2.length()) {
119 return -1;
120 }
121 return 0;
122 }
123 });
124 }
64970e7f 125}