View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
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 }