Mon, 21 Jan 2013 20:13:56 +0000
8005244: Implement overload resolution as per latest spec EDR
Summary: Add support for stuck expressions and provisional applicability
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2009, 2013, 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 * @library ../../lib
30 * @build JavacTestingAbstractThreadedTest
31 * @run main/othervm T6769027
32 */
34 import java.net.URI;
35 import java.util.regex.Matcher;
36 import javax.tools.*;
37 import com.sun.tools.javac.util.*;
39 public class T6769027
40 extends JavacTestingAbstractThreadedTest
41 implements Runnable {
43 enum OutputKind {
44 RAW("rawDiagnostics","rawDiagnostics"),
45 BASIC("","");
47 String key;
48 String value;
50 void init(Options opts) {
51 opts.put(key, value);
52 }
54 OutputKind(String key, String value) {
55 this.key = key;
56 this.value = value;
57 }
58 }
60 enum CaretKind {
61 DEFAULT("", ""),
62 SHOW("showCaret","true"),
63 HIDE("showCaret","false");
65 String key;
66 String value;
68 void init(Options opts) {
69 opts.put(key, value);
70 }
72 CaretKind(String key, String value) {
73 this.key = key;
74 this.value = value;
75 }
77 boolean isEnabled() {
78 return this == DEFAULT || this == SHOW;
79 }
80 }
82 enum SourceLineKind {
83 DEFAULT("", ""),
84 AFTER_SUMMARY("sourcePosition", "top"),
85 BOTTOM("sourcePosition", "bottom");
87 String key;
88 String value;
90 void init(Options opts) {
91 opts.put(key, value);
92 }
94 SourceLineKind(String key, String value) {
95 this.key = key;
96 this.value = value;
97 }
99 boolean isAfterSummary() {
100 return this == DEFAULT || this == AFTER_SUMMARY;
101 }
102 }
104 enum XDiagsSource {
105 DEFAULT(""),
106 SOURCE("source"),
107 NO_SOURCE("-source");
109 String flag;
111 void init(Options opts) {
112 if (this != DEFAULT) {
113 String flags = opts.get("diags");
114 flags = flags == null ? flag : flags + "," + flag;
115 opts.put("diags", flags);
116 }
117 }
119 XDiagsSource(String flag) {
120 this.flag = flag;
121 }
123 String getOutput(CaretKind caretKind, IndentKind indent, OutputKind outKind) {
124 String spaces = (outKind == OutputKind.BASIC) ? indent.string : "";
125 return "\n" + spaces + "This is a source line" +
126 (caretKind.isEnabled() ? "\n" + spaces + " ^" : "");
127 }
128 }
130 enum XDiagsCompact {
131 DEFAULT(""),
132 COMPACT("short"),
133 NO_COMPACT("-short");
135 String flag;
137 void init(Options opts) {
138 if (this != DEFAULT) {
139 String flags = opts.get("diags");
140 flags = flags == null ? flag : flags + "," + flag;
141 opts.put("diags", flags);
142 }
143 }
145 XDiagsCompact(String flag) {
146 this.flag = flag;
147 }
148 }
150 enum ErrorKind {
151 SINGLE("single",
152 "compiler.err.single: Hello!",
153 "KXThis is a test error message Hello!"),
154 DOUBLE("double",
155 "compiler.err.double: Hello!",
156 "KXThis is a test error message.\n" +
157 "KXYThis is another line of the above error message Hello!");
159 String key;
160 String rawOutput;
161 String nonRawOutput;
163 String key() {
164 return key;
165 }
167 ErrorKind(String key, String rawOutput, String nonRawOutput) {
168 this.key = key;
169 this.rawOutput = rawOutput;
170 this.nonRawOutput = nonRawOutput;
171 }
173 String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent) {
174 return outKind == OutputKind.RAW ?
175 rawOutput :
176 nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", "");
177 }
179 String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent, String indent) {
180 return outKind == OutputKind.RAW ?
181 rawOutput :
182 nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", indent);
183 }
184 }
186 enum MultilineKind {
187 NONE(0),
188 DOUBLE(1),
189 NESTED(2),
190 DOUBLE_NESTED(3);
192 static String[][] rawTemplates = {
193 {"", ",{(E),(E)}", ",{(E,{(E)})}", ",{(E,{(E)}),(E,{(E)})}"}, //ENABLED
194 {"", "", "", "",""}, //DISABLED
195 {"", ",{(E)}", ",{(E,{(E)})}", ",{(E,{(E)})}"}, //LIMIT_LENGTH
196 {"", ",{(E),(E)}", ",{(E)}", ",{(E),(E)}"}, //LIMIT_DEPTH
197 {"", ",{(E)}", ",{(E)}", ",{(E)}"}}; //LIMIT_BOTH
199 static String[][] basicTemplates = {
200 {"", "\nE\nE", "\nE\nQ", "\nE\nQ\nE\nQ"}, //ENABLED
201 {"", "", "", "",""}, //DISABLED
202 {"", "\nE", "\nE\nQ", "\nE\nQ"}, //LIMIT_LENGTH
203 {"", "\nE\nE", "\nE", "\nE\nE"}, //LIMIT_DEPTH
204 {"", "\nE", "\nE", "\nE"}}; //LIMIT_BOTH
207 int index;
209 MultilineKind (int index) {
210 this.index = index;
211 }
213 boolean isDouble() {
214 return this == DOUBLE || this == DOUBLE_NESTED;
215 }
217 boolean isNested() {
218 return this == NESTED || this == DOUBLE_NESTED;
219 }
221 String getOutput(OutputKind outKind, ErrorKind errKind, MultilinePolicy policy,
222 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind multiIndent) {
223 String constIndent = (errKind == ErrorKind.DOUBLE) ?
224 summaryIndent.string + detailsIndent.string :
225 summaryIndent.string;
226 constIndent += multiIndent.string;
228 String errMsg1 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent);
229 String errMsg2 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent + constIndent);
231 errMsg1 = errMsg1.replaceAll("compiler.err", "compiler.misc");
232 errMsg1 = errMsg1.replaceAll("error message", "subdiagnostic");
233 errMsg2 = errMsg2.replaceAll("compiler.err", "compiler.misc");
234 errMsg2 = errMsg2.replaceAll("error message", "subdiagnostic");
236 String template = outKind == OutputKind.RAW ?
237 rawTemplates[policy.index][index] :
238 basicTemplates[policy.index][index];
240 template = template.replaceAll("E", errMsg1);
241 return template.replaceAll("Q", errMsg2);
242 }
243 }
245 enum MultilinePolicy {
246 ENABLED(0, "multilinePolicy", "enabled"),
247 DISABLED(1, "multilinePolicy", "disabled"),
248 LIMIT_LENGTH(2, "multilinePolicy", "limit:1:*"),
249 LIMIT_DEPTH(3, "multilinePolicy", "limit:*:1"),
250 LIMIT_BOTH(4, "multilinePolicy", "limit:1:1");
252 String name;
253 String value;
254 int index;
256 MultilinePolicy(int index, String name, String value) {
257 this.name = name;
258 this.value = value;
259 this.index = index;
260 }
262 void init(Options options) {
263 options.put(name, value);
264 }
265 }
267 enum PositionKind {
268 NOPOS(Position.NOPOS, "- ", "error: "),
269 POS(5, "Test.java:1:6: ", "/Test.java:1: error: ");
271 int pos;
272 String rawOutput;
273 String nonRawOutput;
275 PositionKind(int pos, String rawOutput, String nonRawOutput) {
276 this.pos = pos;
277 this.rawOutput = rawOutput;
278 this.nonRawOutput = nonRawOutput;
279 }
281 JCDiagnostic.DiagnosticPosition pos() {
282 return new JCDiagnostic.SimpleDiagnosticPosition(pos);
283 }
285 String getOutput(OutputKind outputKind) {
286 return outputKind == OutputKind.RAW ?
287 rawOutput :
288 nonRawOutput;
289 }
290 }
292 static class MyFileObject extends SimpleJavaFileObject {
293 private String text;
294 public MyFileObject(String text) {
295 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
296 this.text = text;
297 }
298 @Override
299 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
300 return text;
301 }
302 }
304 enum IndentKind {
305 NONE(""),
306 CUSTOM(" ");
308 String string;
310 IndentKind(String indent) {
311 string = indent;
312 }
313 }
315 class MyLog extends Log {
316 MyLog(Context ctx) {
317 super(ctx);
318 }
320 @Override
321 protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
322 return outWriter;
323 }
325 @Override
326 protected boolean shouldReport(JavaFileObject jfo, int pos) {
327 return true;
328 }
329 }
331 OutputKind outputKind;
332 ErrorKind errorKind;
333 MultilineKind multiKind;
334 MultilinePolicy multiPolicy;
335 PositionKind posKind;
336 XDiagsSource xdiagsSource;
337 XDiagsCompact xdiagsCompact;
338 CaretKind caretKind;
339 SourceLineKind sourceLineKind;
340 IndentKind summaryIndent;
341 IndentKind detailsIndent;
342 IndentKind sourceIndent;
343 IndentKind subdiagsIndent;
345 T6769027(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
346 MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
347 XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
348 IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
349 IndentKind subdiagsIndent) {
350 this.outputKind = outputKind;
351 this.errorKind = errorKind;
352 this.multiKind = multiKind;
353 this.multiPolicy = multiPolicy;
354 this.posKind = posKind;
355 this.xdiagsSource = xdiagsSource;
356 this.xdiagsCompact = xdiagsCompact;
357 this.caretKind = caretKind;
358 this.sourceLineKind = sourceLineKind;
359 this.summaryIndent = summaryIndent;
360 this.detailsIndent = detailsIndent;
361 this.sourceIndent = sourceIndent;
362 this.subdiagsIndent = subdiagsIndent;
363 }
365 @Override
366 public void run() {
367 Context ctx = new Context();
368 Options options = Options.instance(ctx);
369 outputKind.init(options);
370 multiPolicy.init(options);
371 xdiagsSource.init(options);
372 xdiagsCompact.init(options);
373 caretKind.init(options);
374 sourceLineKind.init(options);
375 String indentString = "";
376 indentString = (summaryIndent == IndentKind.CUSTOM) ? "3" : "0";
377 indentString += (detailsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
378 indentString += (sourceIndent == IndentKind.CUSTOM) ? "|3" : "|0";
379 indentString += (subdiagsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
380 options.put("diagsIndentation", indentString);
381 MyLog log = new MyLog(ctx);
382 JavacMessages messages = JavacMessages.instance(ctx);
383 messages.add("tester");
384 JCDiagnostic.Factory diags = JCDiagnostic.Factory.instance(ctx);
385 log.useSource(new MyFileObject("This is a source line"));
386 JCDiagnostic d = diags.error(log.currentSource(),
387 posKind.pos(),
388 errorKind.key(), "Hello!");
389 if (multiKind != MultilineKind.NONE) {
390 JCDiagnostic sub = diags.fragment(errorKind.key(), "Hello!");
391 if (multiKind.isNested())
392 sub = new JCDiagnostic.MultilineDiagnostic(sub, List.of(sub));
393 List<JCDiagnostic> subdiags = multiKind.isDouble() ?
394 List.of(sub, sub) :
395 List.of(sub);
396 d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
397 }
398 String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
399 checkOutput(diag);
400 }
402 public static void main(String[] args) throws Exception {
403 for (OutputKind outputKind : OutputKind.values()) {
404 for (ErrorKind errKind : ErrorKind.values()) {
405 for (MultilineKind multiKind : MultilineKind.values()) {
406 for (MultilinePolicy multiPolicy : MultilinePolicy.values()) {
407 for (PositionKind posKind : PositionKind.values()) {
408 for (XDiagsSource xdiagsSource : XDiagsSource.values()) {
409 for (XDiagsCompact xdiagsCompact : XDiagsCompact.values()) {
410 for (CaretKind caretKind : CaretKind.values()) {
411 for (SourceLineKind sourceLineKind : SourceLineKind.values()) {
412 for (IndentKind summaryIndent : IndentKind.values()) {
413 for (IndentKind detailsIndent : IndentKind.values()) {
414 for (IndentKind sourceIndent : IndentKind.values()) {
415 for (IndentKind subdiagsIndent : IndentKind.values()) {
416 pool.execute(new T6769027(outputKind,
417 errKind,
418 multiKind,
419 multiPolicy,
420 posKind,
421 xdiagsSource,
422 xdiagsCompact,
423 caretKind,
424 sourceLineKind,
425 summaryIndent,
426 detailsIndent,
427 sourceIndent,
428 subdiagsIndent));
429 }
430 }
431 }
432 }
433 }
434 }
435 }
436 }
437 }
438 }
439 }
440 }
441 }
443 checkAfterExec(false);
444 }
446 void printInfo(String msg, String errorLine) {
447 String sep = "*********************************************************";
448 String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
449 " multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
450 " diags= " + java.util.Arrays.asList(xdiagsSource.flag, xdiagsCompact.flag) +
451 " caret=" + caretKind + " sourcePosition=" + sourceLineKind +
452 " summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
453 " sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
454 errWriter.println(sep);
455 errWriter.println(desc);
456 errWriter.println(sep);
457 errWriter.println(msg);
458 errWriter.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
459 }
461 void checkOutput(String msg) {
462 boolean shouldPrintSource = posKind == PositionKind.POS &&
463 xdiagsSource != XDiagsSource.NO_SOURCE &&
464 (xdiagsSource == XDiagsSource.SOURCE ||
465 outputKind == OutputKind.BASIC);
466 String errorLine = posKind.getOutput(outputKind) +
467 errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
468 if (xdiagsCompact != XDiagsCompact.COMPACT)
469 errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy,
470 summaryIndent, detailsIndent, subdiagsIndent);
471 String[] lines = errorLine.split("\n");
472 if (xdiagsCompact == XDiagsCompact.COMPACT) {
473 errorLine = lines[0];
474 lines = new String[] {errorLine};
475 }
476 if (shouldPrintSource) {
477 if (sourceLineKind.isAfterSummary()) {
478 String sep = "\n";
479 if (lines.length == 1) {
480 errorLine += "\n";
481 sep = "";
482 }
483 errorLine = errorLine.replaceFirst("\n",
484 Matcher.quoteReplacement(xdiagsSource.getOutput(caretKind, sourceIndent, outputKind) + sep));
485 }
486 else
487 errorLine += xdiagsSource.getOutput(caretKind, sourceIndent, outputKind);
488 }
490 if (!msg.equals(errorLine)) {
491 printInfo(msg, errorLine);
492 errCount.incrementAndGet();
493 }
494 }
496 }