src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java

changeset 240
8c55d5b0ed71
parent 229
03bcd66bd8e7
parent 238
86b60aa941c6
child 288
d402db1005ad
     1.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Mon Mar 09 13:34:19 2009 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Mon Mar 09 23:53:41 2009 -0700
     1.3 @@ -38,6 +38,10 @@
     1.4  import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
     1.5  import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
     1.6  import com.sun.tools.javac.api.Formattable;
     1.7 +import com.sun.tools.javac.code.Printer;
     1.8 +import com.sun.tools.javac.code.Symbol;
     1.9 +import com.sun.tools.javac.code.Type;
    1.10 +import com.sun.tools.javac.code.Type.CapturedType;
    1.11  import com.sun.tools.javac.file.JavacFileManager;
    1.12  
    1.13  import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
    1.14 @@ -60,16 +64,31 @@
    1.15       * JavacMessages object used by this formatter for i18n.
    1.16       */
    1.17      protected JavacMessages messages;
    1.18 +
    1.19 +    /**
    1.20 +     * Configuration object used by this formatter
    1.21 +     */
    1.22      private SimpleConfiguration config;
    1.23 +
    1.24 +    /**
    1.25 +     * Current depth level of the disgnostic being formatted
    1.26 +     * (!= 0 for subdiagnostics)
    1.27 +     */
    1.28      protected int depth = 0;
    1.29  
    1.30      /**
    1.31 +     * Printer instance to be used for formatting types/symbol
    1.32 +     */
    1.33 +    protected Printer printer;
    1.34 +
    1.35 +    /**
    1.36       * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
    1.37       * @param messages
    1.38       */
    1.39      protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
    1.40          this.messages = messages;
    1.41          this.config = config;
    1.42 +        this.printer = new FormatterPrinter();
    1.43      }
    1.44  
    1.45      public String formatKind(JCDiagnostic d, Locale l) {
    1.46 @@ -83,6 +102,14 @@
    1.47          }
    1.48      }
    1.49  
    1.50 +    @Override
    1.51 +    public String format(JCDiagnostic d, Locale locale) {
    1.52 +        printer = new FormatterPrinter();
    1.53 +        return formatDiagnostic(d, locale);
    1.54 +    }
    1.55 +
    1.56 +    abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
    1.57 +
    1.58      public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
    1.59          assert (d.getPosition() != Position.NOPOS);
    1.60          return String.valueOf(getPosition(d, pk));
    1.61 @@ -143,12 +170,21 @@
    1.62          else if (arg instanceof Iterable<?>) {
    1.63              return formatIterable(d, (Iterable<?>)arg, l);
    1.64          }
    1.65 -        else if (arg instanceof JavaFileObject)
    1.66 +        else if (arg instanceof Type) {
    1.67 +            return printer.visit((Type)arg, l);
    1.68 +        }
    1.69 +        else if (arg instanceof Symbol) {
    1.70 +            return printer.visit((Symbol)arg, l);
    1.71 +        }
    1.72 +        else if (arg instanceof JavaFileObject) {
    1.73              return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg);
    1.74 -        else if (arg instanceof Formattable)
    1.75 +        }
    1.76 +        else if (arg instanceof Formattable) {
    1.77              return ((Formattable)arg).toString(l, messages);
    1.78 -        else
    1.79 +        }
    1.80 +        else {
    1.81              return String.valueOf(arg);
    1.82 +        }
    1.83      }
    1.84  
    1.85      /**
    1.86 @@ -404,4 +440,43 @@
    1.87              return caretEnabled;
    1.88          }
    1.89      }
    1.90 +
    1.91 +    /**
    1.92 +     * An enhanced printer for formatting types/symbols used by
    1.93 +     * AbstractDiagnosticFormatter. Provides alternate numbering of captured
    1.94 +     * types (they are numbered starting from 1 on each new diagnostic, instead
    1.95 +     * of relying on the underlying hashcode() method which generates unstable
    1.96 +     * output). Also detects cycles in wildcard messages (e.g. if the wildcard
    1.97 +     * type referred by a given captured type C contains C itself) which might
    1.98 +     * lead to infinite loops.
    1.99 +     */
   1.100 +    protected class FormatterPrinter extends Printer {
   1.101 +
   1.102 +        List<Type> allCaptured = List.nil();
   1.103 +        List<Type> seenCaptured = List.nil();
   1.104 +
   1.105 +        @Override
   1.106 +        protected String localize(Locale locale, String key, Object... args) {
   1.107 +            return AbstractDiagnosticFormatter.this.localize(locale, key, args);
   1.108 +        }
   1.109 +
   1.110 +        @Override
   1.111 +        public String visitCapturedType(CapturedType t, Locale locale) {
   1.112 +            if (seenCaptured.contains(t))
   1.113 +                return localize(locale, "compiler.misc.type.captureof.1",
   1.114 +                    allCaptured.indexOf(t) + 1);
   1.115 +            else {
   1.116 +                try {
   1.117 +                    seenCaptured = seenCaptured.prepend(t);
   1.118 +                    allCaptured = allCaptured.append(t);
   1.119 +                    return localize(locale, "compiler.misc.type.captureof",
   1.120 +                        allCaptured.indexOf(t) + 1,
   1.121 +                        visit(t.wildcard, locale));
   1.122 +                }
   1.123 +                finally {
   1.124 +                    seenCaptured = seenCaptured.tail;
   1.125 +                }
   1.126 +            }
   1.127 +        }
   1.128 +    }
   1.129  }

mercurial