1
2
3
4
5
6 package mockit.coverage.reporting.dataCoverage;
7
8 import edu.umd.cs.findbugs.annotations.NonNull;
9 import edu.umd.cs.findbugs.annotations.Nullable;
10
11 import mockit.coverage.dataItems.FieldData;
12 import mockit.coverage.dataItems.InstanceFieldData;
13 import mockit.coverage.dataItems.PerFileDataCoverage;
14 import mockit.coverage.dataItems.StaticFieldData;
15 import mockit.coverage.reporting.parsing.FileParser;
16 import mockit.coverage.reporting.parsing.LineElement;
17
18 import org.checkerframework.checker.index.qual.NonNegative;
19
20 public final class DataCoverageOutput {
21 @NonNull
22 private final StringBuilder openingTag;
23 @NonNull
24 private final PerFileDataCoverage coverageInfo;
25 @NonNegative
26 private int nextField;
27 @Nullable
28 private String classAndFieldNames;
29 @Nullable
30 private String className;
31 @Nullable
32 private String fieldName;
33
34 public DataCoverageOutput(@NonNull PerFileDataCoverage coverageInfo) {
35 openingTag = new StringBuilder(50);
36 this.coverageInfo = coverageInfo;
37 moveToNextField();
38 }
39
40 private void moveToNextField() {
41 if (nextField >= coverageInfo.allFields.size()) {
42 classAndFieldNames = null;
43 className = null;
44 fieldName = null;
45 return;
46 }
47
48 classAndFieldNames = coverageInfo.allFields.get(nextField);
49 nextField++;
50
51 int p = classAndFieldNames.indexOf('.');
52 className = classAndFieldNames.substring(0, p);
53 fieldName = classAndFieldNames.substring(p + 1);
54 }
55
56 public void writeCoverageInfoIfLineStartsANewFieldDeclaration(@NonNull FileParser fileParser) {
57 if (classAndFieldNames != null) {
58 assert className != null;
59
60 if (className.equals(fileParser.getCurrentlyPendingClass())) {
61 LineElement initialLineElement = fileParser.lineParser.getInitialElement();
62
63 assert fieldName != null;
64 LineElement elementWithFieldName = initialLineElement.findWord(fieldName);
65
66 if (elementWithFieldName != null) {
67 buildOpeningTagForFieldWrapper();
68 elementWithFieldName.wrapText(openingTag.toString(), "</span>");
69 moveToNextField();
70 }
71 }
72 }
73 }
74
75 private void buildOpeningTagForFieldWrapper() {
76 openingTag.setLength(0);
77 openingTag.append("<span class='");
78
79 assert classAndFieldNames != null;
80 StaticFieldData staticData = coverageInfo.getStaticFieldData(classAndFieldNames);
81 boolean staticField = staticData != null;
82 openingTag.append(staticField ? "static" : "instance");
83
84 openingTag.append(coverageInfo.isCovered(classAndFieldNames) ? " cvd" : " uncvd");
85
86 InstanceFieldData instanceData = coverageInfo.getInstanceFieldData(classAndFieldNames);
87
88 if (staticField || instanceData != null) {
89 openingTag.append("' title='");
90 appendAccessCounts(staticField ? staticData : instanceData);
91 }
92
93 openingTag.append("'>");
94 }
95
96 private void appendAccessCounts(@NonNull FieldData fieldData) {
97 openingTag.append("Reads: ").append(fieldData.getReadCount());
98 openingTag.append(" Writes: ").append(fieldData.getWriteCount());
99 }
100 }