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