JDK-6768932 : Add support for multiline diagnostics
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2008-11-07
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b41Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Recent work on javac diagnostics have underlined the need for better diagnostics; the diagnostics to be improved, esp. those regarding the type-system area of the compiler, would hugely benefit from some kind of multiline/tabular support.

Examples:

1) Type-system diagnostic:

Test.java:3: method test in class Foo<T #0> cannot be applied to given types
   required: T #0
   found: T #1
      where T #0,T #1 are typevariables:
          T #0 extends String
              (declared in class Foo)
          T #1 extends Integer
              (declared in method <T>foo(T))
1 error

2) Method resolution diagnostics

Test.java:6: no suitable method m found for (String,String)
    method: <T>m(T,T) in Test
      (inferred type argument(s) String do not conform to bounds of type variable(s) T)
    method: m(Integer) in Test       
1 error

All the above diagnostics suggests the need of a more structured way of representing the contents of a diagnostic sub-elements. In both examples we have that the diagnostic is composed of subparts (where clause in the first case, list of unapplicable method in the second case) that should displayed with the correct amount of indentation. This requires some sort of basic multiline support at the level of the javac diagnostic system.

Comments
SUGGESTED FIX I choosed a different approach - actually I created a new JCDiagnostic subclass called MultilineDiagnostic; the constructor of this kind of diagnostic accepts a base diagnostic (could be anything, error, warning, note, etc.) and a *list* of subdiagnostics (better if they're fragments). The code in AbstractDiagnosticFormatter has been slightly adjusted in order to deal with multiline diagnostics in the proper way (e.g. adding the correct amount of indentation). A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/4cdaaf4c5dca
12-11-2008

EVALUATION Will do that. I've considered a bunch of alternative approaches: 1) Adding an int field to JCDiagnostic so that diagnostics can be associated with a depth value that can be exploited by the diagnostic formatter in order to get things right. 2) Add a list of subdiagnostic to a JCDiagnostic and add proper support to diagnostic formatters so that they will be able to render a diagnostic' subdiagnostics in the proper way. Solution 1) is simpler, but it has a couple of bad disadvantages: *) Subdiagnostics elements must be given their depth a-priori; not always we have the possibility of doing so within javac - e.g we would like to be able to arbitrarily nest a diagnostic fragment into another diagnostic, without needing to know which depth to assign to the nested element so that the layout will be as expected. *) The fact that a diagnostic has a level of depth != 0 has an impact on raw warnings too; e.g. we probably don't want that multiline support affects the way in which raw diagnostics are generated (e.g. we don't want extra new-lines, indentation, and so forth - meaning that subdiagnostics should be displayed in the usual way, as if they were diagnostic arguments). This is very hard to do if we only rely upn the depth field. On the other hand, solution 2 solves both problems: *) The formatter has an additional method called formatSubdiagnostics, that automatically takes care of formatting the nested elements of a given diagnostic. When doing so, the formatter could update an internal depth field, so that it always know whcih indentation should be used for any nested diagnostic to be displayed. Clients don't have to know the depth of a nested fragment a-priori - all is automatically done within the formatter. *) Raw diagnostics can easily be customized by overriding formatSubdiagnostics, so that a more appropriate raw representation ofr subdiagnostics can be provided. In order to preserve backward compatibility, I suggest that multiline diagnostics should be created as standard ones - this is crucial, as diagnostics are mostly created by the log, and the log interface is almost fixed, so that we can't add extra stuff there. My proposal is that diagnostics that do need multiline support should have a key in compiler.properties that ends with the '.multiline' suffix. All such diagnostics should be created so that their first argument is a List<JCDiagnostic> - when creating a multiline diagnostic, the first argument should be stripped away from the diagnostic argument list, and converted into a subdiagnostic list.
07-11-2008