KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > uka > ipd > coverage > natures > BlockCoverageNature


1 /*
2  * Created on Sep 2, 2004
3  * @author Matthias Kempka
4  */

5 package de.uka.ipd.coverage.natures;
6
7 import java.util.*;
8
9 import org.apache.bcel.classfile.*;
10 import org.eclipse.jface.resource.ImageDescriptor;
11
12 import de.uka.ipd.coverage.plugin.CoveragePlugin;
13 import de.uka.ipd.coverage.plugin.ui.CoverageNatureDescriptor;
14 import de.uka.ipd.coverage.recording.*;
15 import de.uka.ipd.coverage.utils.Logger;
16
17 /**
18  * @author Matthias Kempka
19  *
20  */

21 public class BlockCoverageNature implements CoverageNature {
22
23     private Logger logger = new Logger(this);
24     private List registeredMethods = new LinkedList(); // contains RegisteredMethod objects
25
private Map testedClasses = new HashMap(); // contains TestedClass objects
26

27     public static final CoverageNatureDescriptor DESCRIPTOR = new CoverageNatureDescriptor() {
28
29         public String JavaDoc getName() {
30             return Messages.getString("BlockCoverageNature.0"); //$NON-NLS-1$
31
}
32
33         public String JavaDoc getDescription() {
34             return Messages.getString("BlockCoverageNature.1"); //$NON-NLS-1$
35
}
36
37         public String JavaDoc getID() {
38             return "de.uka.ipd.coverage.natures.BlockCoverageNature"; //$NON-NLS-1$
39
}
40
41         public ImageDescriptor getImageDescriptor() {
42             String JavaDoc iconPath = "icons/coverageNatures/"; //$NON-NLS-1$
43
String JavaDoc[] icons = new String JavaDoc[] {"block_coverage_nature"}; //$NON-NLS-1$
44
return CoveragePlugin.getDefault().getImageDescriptors(
45                 icons, iconPath)[0];
46         }
47         
48         
49     };
50     
51     /* (non-Javadoc)
52      * @see de.uka.ipd.coverage.natures.CoverageNature#getMeasuredClasses()
53      */

54     public TestedClass[] getMeasuredClasses() {
55         return (TestedClass[]) testedClasses.values().toArray(
56                 new TestedClass[testedClasses.size()]);
57     }
58
59     /* (non-Javadoc)
60      * @see de.uka.ipd.coverage.natures.CoverageNature#getCompleteCoverage(java.lang.Class)
61      */

62     public CompleteCoverage getCompleteCoverage(JavaClass jclass) {
63         // get all registeredMethods for the given jclass
64
List methodList = findRegisteredMethods(jclass);
65         CompleteCoverage result = new CompleteCoverage(jclass);
66         
67         // build the result
68
for (Iterator iter = methodList.iterator(); iter.hasNext();) {
69             
70             // prepare the instructionList and line number table
71
RegisteredMethod element = (RegisteredMethod) iter.next();
72             LineNumberTable lineNumberTable =
73                 element.getMethod().getCode().getLineNumberTable();
74             LineNumber[] lineNumbers = lineNumberTable.getLineNumberTable();
75             TranslatingBasicBlock[] transBlocks =
76                 (TranslatingBasicBlock[]) element.getBasicBlocks();
77             
78             recordLineNumbers(lineNumbers, transBlocks);
79             
80             // iterate over all lineNumbers and record their coverage state
81
recordCoverageState(result, element, lineNumbers, transBlocks);
82         }
83         return result;
84     }
85
86     private void recordCoverageState(
87             CompleteCoverage result,
88             RegisteredMethod element,
89             LineNumber[] lineNumbers,
90             TranslatingBasicBlock[] transBlocks) {
91         int currentLineNumber = Integer.MIN_VALUE;
92         for (int i = 0; i < lineNumbers.length; i++) {
93             if (lineNumbers[i].getLineNumber() != currentLineNumber) {
94                 currentLineNumber = lineNumbers[i].getLineNumber();
95                 TranslatingBasicBlock[] correspondingBlocks =
96                     getCorrespondingBlocks(transBlocks, currentLineNumber);
97                 
98                 assert correspondingBlocks.length > 0 :
99                     "Line " + currentLineNumber + //$NON-NLS-1$
100
" in Method " + element.getMethod().getName() + //$NON-NLS-1$
101
" of class " + element.getJavaClass().getClassName() + //$NON-NLS-1$
102
" is not covered by a block!"; //$NON-NLS-1$
103

104                 CoverageState currentLineState
105                         = correspondingBlocks[0].getCoverageState();
106                 for (int j = 1; j < correspondingBlocks.length; j++) {
107                     CoverageState.mergeCoverages(currentLineState,
108                             correspondingBlocks[j].getCoverageState());
109                 }
110                 String JavaDoc reason = makeReason(currentLineState);
111                 result.addLine(new SourceCodeLine(currentLineNumber),
112                                 currentLineState, reason);
113             }
114         }
115     }
116
117     /**
118      * @param currentLineState
119      */

120     private String JavaDoc makeReason(CoverageState currentLineState) {
121         String JavaDoc reason;
122         if (currentLineState == CoverageState.FULL_COVERAGE) {
123             reason = Messages.getString("BlockCoverageNature.10"); //$NON-NLS-1$
124
} else if (currentLineState == CoverageState.PARTIAL_COVERAGE) {
125             reason = Messages.getString("BlockCoverageNature.11"); //$NON-NLS-1$
126
} else {
127             reason = Messages.getString("BlockCoverageNature.12"); //$NON-NLS-1$
128
}
129         return reason;
130     }
131
132     private void recordLineNumbers(LineNumber[] lineNumbers, TranslatingBasicBlock[] transBlocks) {
133         // iterate over the instructions and record the line numbers
134
for (int i = 0; i < transBlocks.length; i++) {
135             List correspondingLineNumbers = new ArrayList();
136             for (int j = transBlocks[i].getStartLine();
137                     j <= transBlocks[i].getEndLine(); j++) {
138                 LineNumber lineNumber = getCorrespondingLineNumber(
139                         lineNumbers, j);
140                 if (lineNumber != null) {
141                     correspondingLineNumbers.add(lineNumber);
142                 }
143             }
144             transBlocks[i].setCorrespondingLineNumbers(
145                     (LineNumber[]) correspondingLineNumbers.toArray(
146                             new LineNumber[correspondingLineNumbers.size()]));
147         }
148     }
149
150     /**
151      * @param lineNumbers
152      * @param pc
153      * @return returns the LineNumber object, pc is the start instruction of.
154      * returns null if pc points to no start instruction of the given linenumber array.
155      */

156     private LineNumber getCorrespondingLineNumber(
157             LineNumber[] lineNumbers,
158             int pc) {
159         for (int i = 0; i < lineNumbers.length; i++) {
160             if (lineNumbers[i].getStartPC() == pc) {
161                 return lineNumbers[i];
162             }
163         }
164         return null;
165     }
166
167     /**
168      * @param transBlocks
169      * @param currentLineNumber a line number in sourcecode
170      * @return returns a set of TranslatingBasicBlocks that cover the given
171      * source line number
172      */

173     private TranslatingBasicBlock[] getCorrespondingBlocks(
174             TranslatingBasicBlock[] transBlocks,
175             int currentLineNumber) {
176         List result = new ArrayList();
177         for (int i = 0; i < transBlocks.length; i++) {
178             if (transBlocks[i].contains(currentLineNumber)) {
179                 result.add(transBlocks[i]);
180             }
181         }
182         return (TranslatingBasicBlock[]) result.toArray(
183                 new TranslatingBasicBlock[result.size()]);
184     }
185
186     /**
187      * @param jclass
188      */

189     private List findRegisteredMethods(JavaClass jclass) {
190         List result = new LinkedList();
191         for (Iterator iter = registeredMethods.iterator(); iter.hasNext();) {
192             RegisteredMethod element = (RegisteredMethod) iter.next();
193             if (element.getJavaClass().getClassName().equals(jclass.getClassName())) {
194                 result.add(element);
195             }
196         }
197         return result;
198     }
199
200     /* (non-Javadoc)
201      * create TestedClass list
202      */

203     public void visitCode(RegisteredMethod callback, Code code) {
204         BasicBlock[] blocks = callback.getBasicBlocks();
205         TranslatingBasicBlock[] transBlocks = new TranslatingBasicBlock[blocks.length];
206         if (blocks != null && blocks.length > 0) {
207             Path singleBlockPath = new Path();
208             singleBlockPath.addEnteredBlock(blocks[0]);
209             singleBlockPath.addExitedBlock(blocks[0]);
210             CoverageState state = callback.isCovered(singleBlockPath);
211             for (int i = 0; i < blocks.length; i++) {
212                 singleBlockPath = new Path();
213                 singleBlockPath.addEnteredBlock(blocks[i]);
214                 singleBlockPath.addExitedBlock(blocks[i]);
215                 // record the state for the block
216
CoverageState blockCoverage = callback.isCovered(singleBlockPath);
217                 transBlocks[i] = new TranslatingBasicBlock(blocks[i], blockCoverage);
218                 
219                 state = CoverageState.mergeCoverages(state, blockCoverage);
220                 
221             }
222             callback.setBasicBlocks(transBlocks);
223
224             // record the state for the class
225
TestedClass classRecord;
226             if (!testedClasses.containsKey(callback.getJavaClass())) {
227                 classRecord = new TestedClass(callback.getJavaClass(),
228                         state);
229             } else {
230                 classRecord = (TestedClass)
231                         testedClasses.get(callback.getJavaClass());
232                 CoverageState classCoverage =
233                     CoverageState.mergeCoverages(classRecord.getState(), state);
234                 classRecord.setState(classCoverage);
235             }
236             testedClasses.put(callback.getJavaClass(), classRecord);
237             registeredMethods.add(callback);
238         }
239     }
240
241
242     public CoverageNatureDescriptor getCoverageNatureDescriptor() {
243         return DESCRIPTOR;
244     }
245
246     /* (non-Javadoc)
247      * @see de.uka.ipd.coverage.natures.CoverageNature#clear()
248      */

249     public void clear() {
250         registeredMethods.clear();
251         testedClasses.clear();
252     }
253
254 }
Popular Tags