71 return value + k; |
71 return value + k; |
72 } |
72 } |
73 final String value; |
73 final String value; |
74 } |
74 } |
75 |
75 |
|
76 /** |
|
77 * DiagnosticHandler's provide the initial handling for diagnostics. |
|
78 * When a diagnostic handler is created and has been initialized, it |
|
79 * should install itself as the current diagnostic handler. When a |
|
80 * client has finished using a handler, the client should call |
|
81 * {@code log.removeDiagnosticHandler();} |
|
82 * |
|
83 * Note that javax.tools.DiagnosticListener (if set) is called later in the |
|
84 * diagnostic pipeline. |
|
85 */ |
|
86 public static abstract class DiagnosticHandler { |
|
87 /** |
|
88 * The previously installed diagnostic handler. |
|
89 */ |
|
90 protected DiagnosticHandler prev; |
|
91 |
|
92 /** |
|
93 * Install this diagnostic handler as the current one, |
|
94 * recording the previous one. |
|
95 */ |
|
96 protected void install(Log log) { |
|
97 prev = log.diagnosticHandler; |
|
98 log.diagnosticHandler = this; |
|
99 } |
|
100 |
|
101 /** |
|
102 * Handle a diagnostic. |
|
103 */ |
|
104 public abstract void report(JCDiagnostic diag); |
|
105 } |
|
106 |
|
107 /** |
|
108 * A DiagnosticHandler that discards all diagnostics. |
|
109 */ |
|
110 public static class DiscardDiagnosticHandler extends DiagnosticHandler { |
|
111 public DiscardDiagnosticHandler(Log log) { |
|
112 install(log); |
|
113 } |
|
114 |
|
115 public void report(JCDiagnostic diag) { } |
|
116 } |
|
117 |
|
118 /** |
|
119 * A DiagnosticHandler that can defer some or all diagnostics, |
|
120 * by buffering them for later examination and/or reporting. |
|
121 * If a diagnostic is not deferred, or is subsequently reported |
|
122 * with reportAllDiagnostics(), it will be reported to the previously |
|
123 * active diagnostic handler. |
|
124 */ |
|
125 public static class DeferredDiagnosticHandler extends DiagnosticHandler { |
|
126 private Queue<JCDiagnostic> deferred = ListBuffer.lb(); |
|
127 private final Filter<JCDiagnostic> filter; |
|
128 |
|
129 public DeferredDiagnosticHandler(Log log) { |
|
130 this(log, null); |
|
131 } |
|
132 |
|
133 public DeferredDiagnosticHandler(Log log, Filter<JCDiagnostic> filter) { |
|
134 this.filter = filter; |
|
135 install(log); |
|
136 } |
|
137 |
|
138 public void report(JCDiagnostic diag) { |
|
139 if (filter == null || filter.accepts(diag)) |
|
140 deferred.add(diag); |
|
141 else |
|
142 prev.report(diag); |
|
143 } |
|
144 |
|
145 public Queue<JCDiagnostic> getDiagnostics() { |
|
146 return deferred; |
|
147 } |
|
148 |
|
149 /** Report all deferred diagnostics. */ |
|
150 public void reportDeferredDiagnostics() { |
|
151 reportDeferredDiagnostics(EnumSet.allOf(JCDiagnostic.Kind.class)); |
|
152 } |
|
153 |
|
154 /** Report selected deferred diagnostics. */ |
|
155 public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) { |
|
156 JCDiagnostic d; |
|
157 while ((d = deferred.poll()) != null) { |
|
158 if (kinds.contains(d.getKind())) |
|
159 prev.report(d); |
|
160 } |
|
161 deferred = null; // prevent accidental ongoing use |
|
162 } |
|
163 } |
|
164 |
76 public enum WriterKind { NOTICE, WARNING, ERROR }; |
165 public enum WriterKind { NOTICE, WARNING, ERROR }; |
77 |
166 |
78 protected PrintWriter errWriter; |
167 protected PrintWriter errWriter; |
79 |
168 |
80 protected PrintWriter warnWriter; |
169 protected PrintWriter warnWriter; |
126 * JavacMessages object used for localization. |
215 * JavacMessages object used for localization. |
127 */ |
216 */ |
128 private JavacMessages messages; |
217 private JavacMessages messages; |
129 |
218 |
130 /** |
219 /** |
131 * Deferred diagnostics |
220 + * Handler for initial dispatch of diagnostics. |
132 */ |
221 */ |
133 public Filter<JCDiagnostic> deferredDiagFilter; |
222 private DiagnosticHandler diagnosticHandler; |
134 public Queue<JCDiagnostic> deferredDiagnostics = new ListBuffer<JCDiagnostic>(); |
|
135 |
223 |
136 /** Construct a log with given I/O redirections. |
224 /** Construct a log with given I/O redirections. |
137 */ |
225 */ |
138 protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { |
226 protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { |
139 super(JCDiagnostic.Factory.instance(context)); |
227 super(JCDiagnostic.Factory.instance(context)); |
144 |
232 |
145 @SuppressWarnings("unchecked") // FIXME |
233 @SuppressWarnings("unchecked") // FIXME |
146 DiagnosticListener<? super JavaFileObject> dl = |
234 DiagnosticListener<? super JavaFileObject> dl = |
147 context.get(DiagnosticListener.class); |
235 context.get(DiagnosticListener.class); |
148 this.diagListener = dl; |
236 this.diagListener = dl; |
|
237 |
|
238 diagnosticHandler = new DefaultDiagnosticHandler(); |
149 |
239 |
150 messages = JavacMessages.instance(context); |
240 messages = JavacMessages.instance(context); |
151 messages.add(Main.javacBundleName); |
241 messages.add(Main.javacBundleName); |
152 |
242 |
153 final Options options = Options.instance(context); |
243 final Options options = Options.instance(context); |
301 this.errWriter = other.errWriter; |
391 this.errWriter = other.errWriter; |
302 } |
392 } |
303 |
393 |
304 public void setSourceMap(Log other) { |
394 public void setSourceMap(Log other) { |
305 this.sourceMap = other.sourceMap; |
395 this.sourceMap = other.sourceMap; |
|
396 } |
|
397 |
|
398 /** |
|
399 * Replace the specified diagnostic handler with the |
|
400 * handler that was current at the time this handler was created. |
|
401 * The given handler must be the currently installed handler; |
|
402 * it must be specified explicitly for clarity and consistency checking. |
|
403 */ |
|
404 public void popDiagnosticHandler(DiagnosticHandler h) { |
|
405 Assert.check(diagnosticHandler == h); |
|
406 diagnosticHandler = h.prev; |
306 } |
407 } |
307 |
408 |
308 /** Flush the logs |
409 /** Flush the logs |
309 */ |
410 */ |
310 public void flush() { |
411 public void flush() { |
441 public void strictWarning(DiagnosticPosition pos, String key, Object ... args) { |
542 public void strictWarning(DiagnosticPosition pos, String key, Object ... args) { |
442 writeDiagnostic(diags.warning(source, pos, key, args)); |
543 writeDiagnostic(diags.warning(source, pos, key, args)); |
443 nwarnings++; |
544 nwarnings++; |
444 } |
545 } |
445 |
546 |
446 /** Report all deferred diagnostics, and clear the deferDiagnostics flag. */ |
547 /** |
447 public void reportDeferredDiagnostics() { |
548 * Primary method to report a diagnostic. |
448 reportDeferredDiagnostics(EnumSet.allOf(JCDiagnostic.Kind.class)); |
549 * @param diagnostic |
449 } |
550 */ |
450 |
551 public void report(JCDiagnostic diagnostic) { |
451 /** Report selected deferred diagnostics, and clear the deferDiagnostics flag. */ |
552 diagnosticHandler.report(diagnostic); |
452 public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) { |
553 } |
453 deferredDiagFilter = null; |
|
454 JCDiagnostic d; |
|
455 while ((d = deferredDiagnostics.poll()) != null) { |
|
456 if (kinds.contains(d.getKind())) |
|
457 report(d); |
|
458 } |
|
459 } |
|
460 |
554 |
461 /** |
555 /** |
462 * Common diagnostic handling. |
556 * Common diagnostic handling. |
463 * The diagnostic is counted, and depending on the options and how many diagnostics have been |
557 * The diagnostic is counted, and depending on the options and how many diagnostics have been |
464 * reported so far, the diagnostic may be handed off to writeDiagnostic. |
558 * reported so far, the diagnostic may be handed off to writeDiagnostic. |
465 */ |
559 */ |
466 public void report(JCDiagnostic diagnostic) { |
560 private class DefaultDiagnosticHandler extends DiagnosticHandler { |
467 if (deferredDiagFilter != null && deferredDiagFilter.accepts(diagnostic)) { |
561 public void report(JCDiagnostic diagnostic) { |
468 deferredDiagnostics.add(diagnostic); |
562 if (expectDiagKeys != null) |
469 return; |
563 expectDiagKeys.remove(diagnostic.getCode()); |
470 } |
564 |
471 |
565 switch (diagnostic.getType()) { |
472 if (expectDiagKeys != null) |
566 case FRAGMENT: |
473 expectDiagKeys.remove(diagnostic.getCode()); |
567 throw new IllegalArgumentException(); |
474 |
568 |
475 switch (diagnostic.getType()) { |
569 case NOTE: |
476 case FRAGMENT: |
570 // Print out notes only when we are permitted to report warnings |
477 throw new IllegalArgumentException(); |
571 // Notes are only generated at the end of a compilation, so should be small |
478 |
572 // in number. |
479 case NOTE: |
573 if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) { |
480 // Print out notes only when we are permitted to report warnings |
574 writeDiagnostic(diagnostic); |
481 // Notes are only generated at the end of a compilation, so should be small |
575 } |
482 // in number. |
576 break; |
483 if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) { |
577 |
484 writeDiagnostic(diagnostic); |
578 case WARNING: |
|
579 if (emitWarnings || diagnostic.isMandatory()) { |
|
580 if (nwarnings < MaxWarnings) { |
|
581 writeDiagnostic(diagnostic); |
|
582 nwarnings++; |
|
583 } |
|
584 } |
|
585 break; |
|
586 |
|
587 case ERROR: |
|
588 if (nerrors < MaxErrors |
|
589 && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) { |
|
590 writeDiagnostic(diagnostic); |
|
591 nerrors++; |
|
592 } |
|
593 break; |
485 } |
594 } |
486 break; |
|
487 |
|
488 case WARNING: |
|
489 if (emitWarnings || diagnostic.isMandatory()) { |
|
490 if (nwarnings < MaxWarnings) { |
|
491 writeDiagnostic(diagnostic); |
|
492 nwarnings++; |
|
493 } |
|
494 } |
|
495 break; |
|
496 |
|
497 case ERROR: |
|
498 if (nerrors < MaxErrors |
|
499 && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) { |
|
500 writeDiagnostic(diagnostic); |
|
501 nerrors++; |
|
502 } |
|
503 break; |
|
504 } |
595 } |
505 } |
596 } |
506 |
597 |
507 /** |
598 /** |
508 * Write out a diagnostic. |
599 * Write out a diagnostic. |