Wed, 06 Apr 2011 20:33:44 -0700
7033660: Update copyright year to 2011 on any files changed in 2011
Reviewed-by: dholmes
1 /*
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /**
25 * @test
26 * @bug 6769027
27 * @summary Source line should be displayed immediately after the first diagnostic line
28 * @author Maurizio Cimadamore
29 * @run main/othervm T6769027
30 */
31 import java.net.URI;
32 import java.util.regex.Matcher;
33 import javax.tools.*;
34 import com.sun.tools.javac.util.*;
36 public class T6769027 {
38 enum OutputKind {
39 RAW("rawDiagnostics","rawDiagnostics"),
40 BASIC("","");
42 String key;
43 String value;
45 void init(Options opts) {
46 opts.put(key, value);
47 }
49 OutputKind(String key, String value) {
50 this.key = key;
51 this.value = value;
52 }
53 }
55 enum CaretKind {
56 DEFAULT("", ""),
57 SHOW("showCaret","true"),
58 HIDE("showCaret","false");
60 String key;
61 String value;
63 void init(Options opts) {
64 opts.put(key, value);
65 }
67 CaretKind(String key, String value) {
68 this.key = key;
69 this.value = value;
70 }
72 boolean isEnabled() {
73 return this == DEFAULT || this == SHOW;
74 }
75 }
77 enum SourceLineKind {
78 DEFAULT("", ""),
79 AFTER_SUMMARY("sourcePosition", "top"),
80 BOTTOM("sourcePosition", "bottom");
82 String key;
83 String value;
85 void init(Options opts) {
86 opts.put(key, value);
87 }
89 SourceLineKind(String key, String value) {
90 this.key = key;
91 this.value = value;
92 }
94 boolean isAfterSummary() {
95 return this == DEFAULT || this == AFTER_SUMMARY;
96 }
97 }
99 enum XDiagsSource {
100 DEFAULT(""),
101 SOURCE("source"),
102 NO_SOURCE("-source");
104 String flag;
106 void init(Options opts) {
107 if (this != DEFAULT) {
108 String flags = opts.get("diags");
109 flags = flags == null ? flag : flags + "," + flag;
110 opts.put("diags", flags);
111 }
112 }
114 XDiagsSource(String flag) {
115 this.flag = flag;
116 }
118 String getOutput(CaretKind caretKind, IndentKind indent, OutputKind outKind) {
119 String spaces = (outKind == OutputKind.BASIC) ? indent.string : "";
120 return "\n" + spaces + "This is a source line" +
121 (caretKind.isEnabled() ? "\n" + spaces + " ^" : "");
122 }
123 }
125 enum XDiagsCompact {
126 DEFAULT(""),
127 COMPACT("short"),
128 NO_COMPACT("-short");
130 String flag;
132 void init(Options opts) {
133 if (this != DEFAULT) {
134 String flags = opts.get("diags");
135 flags = flags == null ? flag : flags + "," + flag;
136 opts.put("diags", flags);
137 }
138 }
140 XDiagsCompact(String flag) {
141 this.flag = flag;
142 }
143 }
145 enum ErrorKind {
146 SINGLE("single",
147 "compiler.err.single: Hello!",
148 "KXThis is a test error message Hello!"),
149 DOUBLE("double",
150 "compiler.err.double: Hello!",
151 "KXThis is a test error message.\n" +
152 "KXYThis is another line of the above error message Hello!");
154 String key;
155 String rawOutput;
156 String nonRawOutput;
158 String key() {
159 return key;
160 }
162 ErrorKind(String key, String rawOutput, String nonRawOutput) {
163 this.key = key;
164 this.rawOutput = rawOutput;
165 this.nonRawOutput = nonRawOutput;
166 }
168 String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent) {
169 return outKind == OutputKind.RAW ?
170 rawOutput :
171 nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", "");
172 }
174 String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent, String indent) {
175 return outKind == OutputKind.RAW ?
176 rawOutput :
177 nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", indent);
178 }
179 }
181 enum MultilineKind {
182 NONE(0),
183 DOUBLE(1),
184 NESTED(2),
185 DOUBLE_NESTED(3);
187 static String[][] rawTemplates = {
188 {"", ",{(E),(E)}", ",{(E,{(E)})}", ",{(E,{(E)}),(E,{(E)})}"}, //ENABLED
189 {"", "", "", "",""}, //DISABLED
190 {"", ",{(E)}", ",{(E,{(E)})}", ",{(E,{(E)})}"}, //LIMIT_LENGTH
191 {"", ",{(E),(E)}", ",{(E)}", ",{(E),(E)}"}, //LIMIT_DEPTH
192 {"", ",{(E)}", ",{(E)}", ",{(E)}"}}; //LIMIT_BOTH
194 static String[][] basicTemplates = {
195 {"", "\nE\nE", "\nE\nQ", "\nE\nQ\nE\nQ"}, //ENABLED
196 {"", "", "", "",""}, //DISABLED
197 {"", "\nE", "\nE\nQ", "\nE\nQ"}, //LIMIT_LENGTH
198 {"", "\nE\nE", "\nE", "\nE\nE"}, //LIMIT_DEPTH
199 {"", "\nE", "\nE", "\nE"}}; //LIMIT_BOTH
202 int index;
204 MultilineKind (int index) {
205 this.index = index;
206 }
208 boolean isDouble() {
209 return this == DOUBLE || this == DOUBLE_NESTED;
210 }
212 boolean isNested() {
213 return this == NESTED || this == DOUBLE_NESTED;
214 }
216 String getOutput(OutputKind outKind, ErrorKind errKind, MultilinePolicy policy,
217 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind multiIndent) {
218 String constIndent = (errKind == ErrorKind.DOUBLE) ?
219 summaryIndent.string + detailsIndent.string :
220 summaryIndent.string;
221 constIndent += multiIndent.string;
223 String errMsg1 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent);
224 String errMsg2 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent + constIndent);
226 errMsg1 = errMsg1.replaceAll("compiler.err", "compiler.misc");
227 errMsg1 = errMsg1.replaceAll("error message", "subdiagnostic");
228 errMsg2 = errMsg2.replaceAll("compiler.err", "compiler.misc");
229 errMsg2 = errMsg2.replaceAll("error message", "subdiagnostic");
231 String template = outKind == OutputKind.RAW ?
232 rawTemplates[policy.index][index] :
233 basicTemplates[policy.index][index];
235 template = template.replaceAll("E", errMsg1);
236 return template.replaceAll("Q", errMsg2);
237 }
238 }
240 enum MultilinePolicy {
241 ENABLED(0, "multilinePolicy", "enabled"),
242 DISABLED(1, "multilinePolicy", "disabled"),
243 LIMIT_LENGTH(2, "multilinePolicy", "limit:1:*"),
244 LIMIT_DEPTH(3, "multilinePolicy", "limit:*:1"),
245 LIMIT_BOTH(4, "multilinePolicy", "limit:1:1");
247 String name;
248 String value;
249 int index;
251 MultilinePolicy(int index, String name, String value) {
252 this.name = name;
253 this.value = value;
254 this.index = index;
255 }
257 void init(Options options) {
258 options.put(name, value);
259 }
260 }
262 enum PositionKind {
263 NOPOS(Position.NOPOS, "- ", "error: "),
264 POS(5, "Test.java:1:6: ", "/Test.java:1: error: ");
266 int pos;
267 String rawOutput;
268 String nonRawOutput;
270 PositionKind(int pos, String rawOutput, String nonRawOutput) {
271 this.pos = pos;
272 this.rawOutput = rawOutput;
273 this.nonRawOutput = nonRawOutput;
274 }
276 JCDiagnostic.DiagnosticPosition pos() {
277 return new JCDiagnostic.SimpleDiagnosticPosition(pos);
278 }
280 String getOutput(OutputKind outputKind) {
281 return outputKind == OutputKind.RAW ?
282 rawOutput :
283 nonRawOutput;
284 }
285 }
287 static class MyFileObject extends SimpleJavaFileObject {
288 private String text;
289 public MyFileObject(String text) {
290 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
291 this.text = text;
292 }
293 @Override
294 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
295 return text;
296 }
297 }
299 enum IndentKind {
300 NONE(""),
301 CUSTOM(" ");
303 String string;
305 IndentKind(String indent) {
306 string = indent;
307 }
308 }
310 class MyLog extends Log {
311 MyLog(Context ctx) {
312 super(ctx);
313 }
315 @Override
316 protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
317 return new java.io.PrintWriter(System.out);
318 }
320 @Override
321 protected boolean shouldReport(JavaFileObject jfo, int pos) {
322 return true;
323 }
324 }
326 int nerrors = 0;
328 void exec(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
329 MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
330 XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
331 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
332 IndentKind subdiagsIndent) {
333 Context ctx = new Context();
334 Options options = Options.instance(ctx);
335 outputKind.init(options);
336 multiPolicy.init(options);
337 xdiagsSource.init(options);
338 xdiagsCompact.init(options);
339 caretKind.init(options);
340 sourceLineKind.init(options);
341 String indentString = "";
342 indentString = (summaryIndent == IndentKind.CUSTOM) ? "3" : "0";
343 indentString += (detailsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
344 indentString += (sourceIndent == IndentKind.CUSTOM) ? "|3" : "|0";
345 indentString += (subdiagsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
346 options.put("diagsIndentation", indentString);
347 MyLog log = new MyLog(ctx);
348 JavacMessages messages = JavacMessages.instance(ctx);
349 messages.add("tester");
350 JCDiagnostic.Factory diags = JCDiagnostic.Factory.instance(ctx);
351 log.useSource(new MyFileObject("This is a source line"));
352 JCDiagnostic d = diags.error(log.currentSource(),
353 posKind.pos(),
354 errorKind.key(), "Hello!");
355 if (multiKind != MultilineKind.NONE) {
356 JCDiagnostic sub = diags.fragment(errorKind.key(), "Hello!");
357 if (multiKind.isNested())
358 sub = new JCDiagnostic.MultilineDiagnostic(sub, List.of(sub));
359 List<JCDiagnostic> subdiags = multiKind.isDouble() ?
360 List.of(sub, sub) :
361 List.of(sub);
362 d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
363 }
364 String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
365 checkOutput(diag,
366 outputKind,
367 errorKind,
368 multiKind,
369 multiPolicy,
370 posKind,
371 xdiagsSource,
372 xdiagsCompact,
373 caretKind,
374 sourceLineKind,
375 summaryIndent,
376 detailsIndent,
377 sourceIndent,
378 subdiagsIndent);
379 }
381 void test() {
382 for (OutputKind outputKind : OutputKind.values()) {
383 for (ErrorKind errKind : ErrorKind.values()) {
384 for (MultilineKind multiKind : MultilineKind.values()) {
385 for (MultilinePolicy multiPolicy : MultilinePolicy.values()) {
386 for (PositionKind posKind : PositionKind.values()) {
387 for (XDiagsSource xdiagsSource : XDiagsSource.values()) {
388 for (XDiagsCompact xdiagsCompact : XDiagsCompact.values()) {
389 for (CaretKind caretKind : CaretKind.values()) {
390 for (SourceLineKind sourceLineKind : SourceLineKind.values()) {
391 for (IndentKind summaryIndent : IndentKind.values()) {
392 for (IndentKind detailsIndent : IndentKind.values()) {
393 for (IndentKind sourceIndent : IndentKind.values()) {
394 for (IndentKind subdiagsIndent : IndentKind.values()) {
395 exec(outputKind,
396 errKind,
397 multiKind,
398 multiPolicy,
399 posKind,
400 xdiagsSource,
401 xdiagsCompact,
402 caretKind,
403 sourceLineKind,
404 summaryIndent,
405 detailsIndent,
406 sourceIndent,
407 subdiagsIndent);
408 }
409 }
410 }
411 }
412 }
413 }
414 }
415 }
416 }
417 }
418 }
419 }
420 }
421 if (nerrors != 0)
422 throw new AssertionError(nerrors + " errors found");
423 }
425 void printInfo(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
426 MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
427 XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
428 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
429 IndentKind subdiagsIndent, String errorLine) {
430 String sep = "*********************************************************";
431 String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
432 " multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
433 " diags= " + java.util.Arrays.asList(xdiagsSource.flag, xdiagsCompact.flag) +
434 " caret=" + caretKind + " sourcePosition=" + sourceLineKind +
435 " summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
436 " sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
437 System.out.println(sep);
438 System.out.println(desc);
439 System.out.println(sep);
440 System.out.println(msg);
441 System.out.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
442 }
444 void checkOutput(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
445 MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
446 XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
447 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
448 IndentKind subdiagsIndent) {
449 boolean shouldPrintSource = posKind == PositionKind.POS &&
450 xdiagsSource != XDiagsSource.NO_SOURCE &&
451 (xdiagsSource == XDiagsSource.SOURCE ||
452 outputKind == OutputKind.BASIC);
453 String errorLine = posKind.getOutput(outputKind) +
454 errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
455 if (xdiagsCompact != XDiagsCompact.COMPACT)
456 errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy, summaryIndent, detailsIndent, subdiagsIndent);
457 String[] lines = errorLine.split("\n");
458 if (xdiagsCompact == XDiagsCompact.COMPACT) {
459 errorLine = lines[0];
460 lines = new String[] {errorLine};
461 }
462 if (shouldPrintSource) {
463 if (sourceLineKind.isAfterSummary()) {
464 String sep = "\n";
465 if (lines.length == 1) {
466 errorLine += "\n";
467 sep = "";
468 }
469 errorLine = errorLine.replaceFirst("\n",
470 Matcher.quoteReplacement(xdiagsSource.getOutput(caretKind, sourceIndent, outputKind) + sep));
471 }
472 else
473 errorLine += xdiagsSource.getOutput(caretKind, sourceIndent, outputKind);
474 }
476 if (!msg.equals(errorLine)) {
477 printInfo(msg,
478 outputKind,
479 errorKind,
480 multiKind,
481 multiPolicy,
482 posKind,
483 xdiagsSource,
484 xdiagsCompact,
485 caretKind,
486 sourceLineKind,
487 summaryIndent,
488 detailsIndent,
489 sourceIndent,
490 subdiagsIndent,
491 errorLine);
492 nerrors++;
493 }
494 }
496 public static void main(String... args) throws Exception {
497 new T6769027().test();
498 }
499 }