]> git.uio.no Git - ifi-stolz-refaktor.git/blame - software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/analyze/SearchBasedExtractAndMoveMethodAnalyzer.java
Moving comparators to no.uio.ifi.refaktor.analyze.comparators
[ifi-stolz-refaktor.git] / software / no.uio.ifi.refaktor / src / no / uio / ifi / refaktor / analyze / SearchBasedExtractAndMoveMethodAnalyzer.java
CommitLineData
b0b82148
EK
1package no.uio.ifi.refaktor.analyze;
2
34328ca2 3import java.util.Collections;
b0b82148
EK
4import java.util.HashSet;
5import java.util.LinkedList;
b0b82148
EK
6import java.util.Set;
7
d6c79186
EK
8import no.uio.ifi.refaktor.analyze.comparators.ExtractAndMoveMethodAnalysisResultComparator;
9import no.uio.ifi.refaktor.analyze.comparators.IgnorantAnalysisResultComparator;
b0b82148 10import no.uio.ifi.refaktor.utils.CompilationUnitTextSelection;
e70f7fb2 11import no.uio.ifi.refaktor.utils.RefaktorDebug;
b0b82148 12
7dc416b3 13import org.eclipse.jdt.core.Flags;
b0b82148 14import org.eclipse.jdt.core.IMethod;
e70f7fb2 15import org.eclipse.jdt.core.JavaModelException;
b0b82148
EK
16import org.eclipse.jdt.core.dom.Statement;
17
cce93a88
EK
18/**
19 * A class for searching through a method body to find the best
20 * candidate for the Extract and Move Method refactoring.
21 */
b0b82148
EK
22public class SearchBasedExtractAndMoveMethodAnalyzer implements Analyzer {
23
24 private final IMethod method;
14dc9ff0 25 private final ExtractAndMoveMethodAnalysisResultComparator analysisResultComparator;
e70f7fb2 26 private final AnalysisStatistics statistics;
b0b82148 27 private Set<CompilationUnitTextSelection> textSelections;
14dc9ff0
EK
28 private LinkedList<ExtractAndMoveMethodAnalysisResult> possibleResults;
29 private ExtractAndMoveMethodAnalysisResult chosenResult;
4f577e24 30 private StatementsCreator statementsCreator;
b0b82148
EK
31
32 public SearchBasedExtractAndMoveMethodAnalyzer(IMethod method) {
14dc9ff0
EK
33 this(method, new IgnorantAnalysisResultComparator());
34 }
35
e70f7fb2
EK
36 public SearchBasedExtractAndMoveMethodAnalyzer(IMethod method,
37 ExtractAndMoveMethodAnalysisResultComparator analysisResultComparator) {
38 this(method, analysisResultComparator, new AnalysisStatistics());
39 }
40
cce93a88
EK
41 /**
42 * @param method The handler for the method to analyze.
43 * @param analysisResultComparator A result comparator to compare two analysis results when deciding
44 * which of them that is the best candidate for the refactoring.
e70f7fb2 45 * @param statistics
cce93a88 46 */
e70f7fb2
EK
47 public SearchBasedExtractAndMoveMethodAnalyzer(IMethod method,
48 ExtractAndMoveMethodAnalysisResultComparator analysisResultComparator, AnalysisStatistics statistics) {
b0b82148 49 this.method = method;
14dc9ff0 50 this.analysisResultComparator = analysisResultComparator;
e70f7fb2 51 this.statistics = statistics;
b0b82148 52 textSelections = new HashSet<CompilationUnitTextSelection>();
14dc9ff0 53 possibleResults = new LinkedList<ExtractAndMoveMethodAnalysisResult>();
4f577e24 54 statementsCreator = new StatementsCreator(method);
b0b82148
EK
55 }
56
cce93a88
EK
57 public ExtractAndMoveMethodAnalysisResult getResult() {
58 return chosenResult;
59 }
60
b0b82148
EK
61 @Override
62 public void analyze() {
affb97cf
EK
63 statistics.incrementMethodCount();
64
e70f7fb2
EK
65 printDebugInfo();
66
7dc416b3
EK
67 // TODO: make the Extract and Move Method Refactoring work with static methods
68 abortIfStaticMethod();
69
b0b82148 70 generateTextSelections();
34328ca2
EK
71 generatePossibleResults();
72
73 if (possibleResults.isEmpty())
74 throw new NoTargetFoundException();
20f03b7c 75
34328ca2
EK
76 chooseResult();
77 }
78
e70f7fb2
EK
79 private void printDebugInfo() {
80 try {
affb97cf 81 RefaktorDebug.println("#" + statistics.getMethodCount() + " (" + statistics.timeSinceStart() + "): " + method.getDeclaringType().getElementName() + "." + method.getElementName() + " (" + "offset: "
e70f7fb2
EK
82 + method.getSourceRange().getOffset() + ", length: " + method.getSourceRange().getLength() + ")");
83 } catch (JavaModelException e) {
84 RefaktorDebug.println("No info about " + method.getElementName());
85 }
86 }
87
7dc416b3
EK
88 private void abortIfStaticMethod() {
89 try {
90 if (Flags.isStatic(method.getFlags()))
91 throw new NoTargetFoundException(method.getElementName() + " is static!");
92 } catch (JavaModelException e) {
93 RefaktorDebug.log(e);
94 throw new GenericAnalyzerException(e);
95 }
96 }
97
b0b82148 98 private void generateTextSelections() {
4f577e24 99 for (Statement statement: statementsCreator.getStatements())
b0b82148
EK
100 generateSelectionsFrom(statement);
101 }
102
103 private void generateSelectionsFrom(Statement statement) {
104 Set<CompilationUnitTextSelection> newSelections = new HashSet<CompilationUnitTextSelection>();
105 CompilationUnitTextSelection textSelectionFromStatement = createTextSelectionFromStatement(statement);
106 newSelections.add(textSelectionFromStatement);
107
108 for (CompilationUnitTextSelection textSelection: textSelections)
109 newSelections.add(addTextSelections(textSelection, textSelectionFromStatement));
34328ca2 110
b0b82148
EK
111 textSelections.addAll(newSelections);
112 }
113
34328ca2
EK
114 private CompilationUnitTextSelection createTextSelectionFromStatement(Statement statement) {
115 return new CompilationUnitTextSelection(method.getCompilationUnit(), statement.getStartPosition(), statement.getLength());
116 }
117
b0b82148
EK
118 private CompilationUnitTextSelection addTextSelections(
119 CompilationUnitTextSelection textSelectionOne, CompilationUnitTextSelection textSelectionTwo) {
120 int offset = Math.min(textSelectionOne.getOffset(), textSelectionTwo.getOffset());
121 int length = Math.max(textSelectionOne.getEnd(), textSelectionTwo.getEnd()) - offset;
122 return new CompilationUnitTextSelection(textSelectionOne.getCompilationUnit(), offset, length);
123 }
124
4f577e24
EK
125 private void generatePossibleResults() {
126 for (CompilationUnitTextSelection textSelection: textSelections) {
127 ExtractAndMoveMethodAnalyzer analyzer = new ExtractAndMoveMethodAnalyzer(textSelection);
128 analyzer.analyze();
09f273fa 129
4f577e24 130 if (analyzer.hasUsefulResults())
cce93a88 131 possibleResults.add(new ExtractAndMoveMethodAnalysisResult(method, analyzer, textSelection, statementsCreator.getNumberOfStatements(), textSelections.size()));
b0b82148 132 }
09f273fa
EK
133 }
134
4f577e24
EK
135 private void chooseResult() {
136 sortPossibleResults();
137 chosenResult = possibleResults.getLast();
b0b82148
EK
138 }
139
4f577e24
EK
140 private void sortPossibleResults() {
141 Collections.sort(possibleResults, analysisResultComparator);
b0b82148 142 }
b0b82148 143}