1
2
3
4
5 package mockit.coverage.reporting.sourceFiles;
6
7 import edu.umd.cs.findbugs.annotations.NonNull;
8 import edu.umd.cs.findbugs.annotations.Nullable;
9
10 import java.io.PrintWriter;
11
12 import mockit.coverage.reporting.parsing.LineElement;
13 import mockit.coverage.reporting.parsing.LineParser;
14
15 final class NeutralOutput {
16 @NonNull
17 private final PrintWriter output;
18 private boolean previousLineInImports;
19 private boolean previousLineInComments;
20 @Nullable
21 private String lineIndentation;
22 private boolean blankLinesPending;
23
24 NeutralOutput(@NonNull PrintWriter output) {
25 this.output = output;
26 }
27
28 boolean writeLineWithoutCoverageInfo(@NonNull LineParser lineParser) {
29 if (previousLineInComments || !previousLineInImports) {
30 if (writeLineInComments(lineParser) || writeLineInImports(lineParser)) {
31 return true;
32 }
33 } else if (writeLineInImports(lineParser) || writeLineInComments(lineParser)) {
34 return true;
35 }
36
37 if (lineParser.isBlankLine()) {
38 blankLinesPending = true;
39 return true;
40 }
41
42 writeBlankLineIfPending();
43 return false;
44 }
45
46 private boolean writeLineInComments(@NonNull LineParser lineParser) {
47 LineElement initialElement = lineParser.getInitialElement();
48
49 if (lineParser.isInComments()
50 || previousLineInComments && initialElement.isComment() && initialElement.getNext() == null) {
51 String lineText = initialElement.toString();
52
53 if (previousLineInComments) {
54 output.println();
55 } else {
56 writeOpeningForCollapsibleBlockOfLines();
57 output.write(" <td class='cm' onclick='shLns(this)'><div>");
58 extractLineIndentation(lineText);
59 previousLineInComments = true;
60 }
61
62 output.write(lineText);
63 return true;
64 }
65 if (previousLineInComments) {
66 output.append("</div><span>").append(lineIndentation).println("/*...*/</span></td>");
67 output.println(" </tr>");
68 previousLineInComments = false;
69 }
70
71 return false;
72 }
73
74 private void writeOpeningForCollapsibleBlockOfLines() {
75 writeBlankLineIfPending();
76 output.println(" <tr>");
77 output.println(" <td></td><td></td>");
78 }
79
80 private void writeBlankLineIfPending() {
81 if (blankLinesPending) {
82 output.println(" <tr><td></td><td></td><td></td></tr>");
83 blankLinesPending = false;
84 }
85 }
86
87 private void extractLineIndentation(@NonNull String lineText) {
88 int indentationSize = 0;
89
90 for (int i = 0; i < lineText.length(); i++, indentationSize++) {
91 if (lineText.charAt(i) > ' ') {
92 break;
93 }
94 }
95
96 lineIndentation = lineText.substring(0, indentationSize);
97 }
98
99 private boolean writeLineInImports(@NonNull LineParser lineParser) {
100 LineElement initialElement = lineParser.getInitialElement();
101 boolean isImport = initialElement.isKeyword("import");
102
103 if (!previousLineInImports && isImport || previousLineInImports && (isImport || lineParser.isBlankLine())) {
104 String lineText = initialElement.toString();
105
106 if (previousLineInImports) {
107 output.println();
108 blankLinesPending = !isImport;
109 } else {
110 writeOpeningForCollapsibleBlockOfLines();
111 output.write(" <td><pre class='ims pp' onclick='shLns(this)'><div>");
112 previousLineInImports = true;
113 }
114
115 output.write(lineText);
116 return true;
117 }
118 if (previousLineInImports) {
119 output.println("</div><span>import ...</span></pre></td>");
120 output.println(" </tr>");
121 previousLineInImports = false;
122 }
123
124 return false;
125 }
126 }