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

changeset 1
9a66ca7c79fa
child 50
b9bcea8bbe24
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,252 @@
     1.4 +/*
     1.5 + * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Sun designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Sun in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.26 + * have any questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.util;
    1.30 +
    1.31 +import javax.tools.JavaFileObject;
    1.32 +
    1.33 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticSource;
    1.34 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    1.35 +
    1.36 +/**
    1.37 + * A formatter for diagnostic messages.
    1.38 + * The formatter will format a diagnostic according to one of two format strings, depending on whether
    1.39 + * or not the source name and position are set. The format is a printf-like string,
    1.40 + * with the following special characters:
    1.41 + * <ul>
    1.42 + * <li>%b: the base of the source name, or "-" if not set
    1.43 + * <li>%f: the source name, or "-" if not set
    1.44 + * <li>%l: the line number of the diagnostic, derived from the character offset if set, or "-" otherwise
    1.45 + * <li>%c: the column number of the diagnostic, derived from the character offset if set, or "-" otherwise
    1.46 + * <li>%o: the character offset of the diagnostic if set, or "-" otherwise
    1.47 + * <li>%p: the prefix for the diagnostic, derived from the diagnostic type
    1.48 + * <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is
    1.49 + *        shown if the type is ERROR and if a source name is set
    1.50 + * <li>%m: the text or the diagnostic, including any appropriate arguments
    1.51 + * </ul>
    1.52 + */
    1.53 +public class DiagnosticFormatter {
    1.54 +    /**
    1.55 +     * A format string to be used for diagnostics with a given position.
    1.56 +     */
    1.57 +    protected String posFormat;
    1.58 +
    1.59 +    /**
    1.60 +     * A format string to be used for diagnostics regarding classfiles
    1.61 +     */
    1.62 +    protected String classFormat = DEFAULT_CLASS_FORMAT;
    1.63 +
    1.64 +    /**
    1.65 +     * A format string to be used for diagnostics without a given position.
    1.66 +     */
    1.67 +    protected String noPosFormat;
    1.68 +
    1.69 +    /**
    1.70 +     * A value to indicate whether to output the i18n key and args, instead of
    1.71 +     * the derived l10n message.
    1.72 +     */
    1.73 +    protected boolean raw;
    1.74 +
    1.75 +    /** The context key for the formatter. */
    1.76 +    protected static final Context.Key<DiagnosticFormatter> formatterKey =
    1.77 +        new Context.Key<DiagnosticFormatter>();
    1.78 +
    1.79 +    /** Get the DiagnosticFormatter instance for this context. */
    1.80 +    public static DiagnosticFormatter instance(Context context) {
    1.81 +        DiagnosticFormatter instance = context.get(formatterKey);
    1.82 +        if (instance == null)
    1.83 +            instance = new DiagnosticFormatter(context);
    1.84 +        return instance;
    1.85 +    }
    1.86 +
    1.87 +    /**
    1.88 +     * Create a formatter based on the supplied options.
    1.89 +     */
    1.90 +    protected DiagnosticFormatter(Context context) {
    1.91 +        Options options = Options.instance(context);
    1.92 +        raw = options.get("rawDiagnostics") != null;
    1.93 +        String fmt = options.get("diags");
    1.94 +        if (fmt != null) {
    1.95 +            int sep = fmt.indexOf('|');
    1.96 +            if (sep == -1)
    1.97 +                posFormat = noPosFormat = fmt;
    1.98 +            else {
    1.99 +                posFormat = fmt.substring(0, sep);
   1.100 +                noPosFormat = fmt.substring(sep + 1);
   1.101 +            }
   1.102 +        }
   1.103 +        else {
   1.104 +            posFormat = DEFAULT_POS_FORMAT;
   1.105 +            noPosFormat = DEFAULT_NO_POS_FORMAT;
   1.106 +        }
   1.107 +    }
   1.108 +
   1.109 +    public static final String DEFAULT_POS_FORMAT = "%f:%l: %t%m";
   1.110 +    public static final String DEFAULT_CLASS_FORMAT = "%f: %t%m";
   1.111 +    public static final String DEFAULT_NO_POS_FORMAT = "%p%m";
   1.112 +
   1.113 +    public DiagnosticFormatter() {
   1.114 +        posFormat = DEFAULT_POS_FORMAT;
   1.115 +        noPosFormat = DEFAULT_NO_POS_FORMAT;
   1.116 +        raw = false;
   1.117 +    }
   1.118 +
   1.119 +    public DiagnosticFormatter(String pos, String noPos) {
   1.120 +        posFormat = pos;
   1.121 +        noPosFormat = noPos;
   1.122 +        raw = false;
   1.123 +    }
   1.124 +
   1.125 +    String format(JCDiagnostic d) {
   1.126 +        return (raw ? format_raw(d) : format_std(d));
   1.127 +    }
   1.128 +
   1.129 +    private String format_raw(JCDiagnostic d) {
   1.130 +        DiagnosticSource source = d.getDiagnosticSource();
   1.131 +        int position = d.getIntPosition();
   1.132 +
   1.133 +        StringBuilder sb = new StringBuilder();
   1.134 +        if (position == Position.NOPOS)
   1.135 +            sb.append("-");
   1.136 +        else {
   1.137 +            sb.append(source.getName() + ":" + source.getLineNumber(position) + ":" + source.getColumnNumber(position) + ":");
   1.138 +        }
   1.139 +        sb.append(" ");
   1.140 +        sb.append(d.getCode());
   1.141 +        String sep = ": ";
   1.142 +        for (Object arg: d.getArgs()) {
   1.143 +            sb.append(sep);
   1.144 +            if (arg instanceof JCDiagnostic) {
   1.145 +                sb.append('(');
   1.146 +                sb.append(format_raw((JCDiagnostic) arg));
   1.147 +                sb.append(')');
   1.148 +            }
   1.149 +            else if (arg instanceof JavaFileObject)
   1.150 +                sb.append(JavacFileManager.getJavacBaseFileName((JavaFileObject) arg));
   1.151 +            else
   1.152 +                sb.append(arg);
   1.153 +            sep = ", ";
   1.154 +        }
   1.155 +        return sb.toString();
   1.156 +    }
   1.157 +
   1.158 +    private String format_std(JCDiagnostic d) {
   1.159 +        DiagnosticSource source = d.getDiagnosticSource();
   1.160 +        DiagnosticType type = d.getType();
   1.161 +        int position = d.getIntPosition();
   1.162 +
   1.163 +
   1.164 +        String format = noPosFormat;
   1.165 +        if (source != null) {
   1.166 +            if (position != Position.NOPOS) {
   1.167 +                format = posFormat;
   1.168 +            } else if (source.getFile() != null &&
   1.169 +                       source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
   1.170 +                format = classFormat;
   1.171 +            }
   1.172 +        }
   1.173 +
   1.174 +        StringBuilder sb = new StringBuilder();
   1.175 +
   1.176 +        for (int i = 0; i < format.length(); i++) {
   1.177 +            char c = format.charAt(i);
   1.178 +            if (c == '%' && i < format.length() - 1) {
   1.179 +                c = format.charAt(++i);
   1.180 +                switch (c) {
   1.181 +                case 'b':
   1.182 +                    sb.append(source == null ? "-" : source.getName());
   1.183 +                    break;
   1.184 +
   1.185 +                case 'e':
   1.186 +                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getEndPosition()));
   1.187 +                    break;
   1.188 +
   1.189 +                case 'f':
   1.190 +                    sb.append(source == null ? "-" : d.getSourceName());
   1.191 +                    break;
   1.192 +
   1.193 +                case 'l':
   1.194 +                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getLineNumber()));
   1.195 +                    break;
   1.196 +
   1.197 +                case 'c':
   1.198 +                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getColumnNumber()));
   1.199 +                    break;
   1.200 +
   1.201 +                case 'o':
   1.202 +                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(position));
   1.203 +                    break;
   1.204 +
   1.205 +                case 'p':
   1.206 +                    sb.append(d.getPrefix());
   1.207 +                    break;
   1.208 +
   1.209 +                case 's':
   1.210 +                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getStartPosition()));
   1.211 +                    break;
   1.212 +
   1.213 +                case 't': {
   1.214 +                    boolean usePrefix;
   1.215 +                    switch (type) {
   1.216 +                    case FRAGMENT:
   1.217 +                        usePrefix = false;
   1.218 +                        break;
   1.219 +
   1.220 +                    case ERROR:
   1.221 +                        usePrefix = (position == Position.NOPOS);
   1.222 +                        break;
   1.223 +
   1.224 +                    default:
   1.225 +                        usePrefix = true;
   1.226 +                    }
   1.227 +
   1.228 +                    if (usePrefix)
   1.229 +                        sb.append(d.getPrefix());
   1.230 +                    break;
   1.231 +                }
   1.232 +
   1.233 +                case 'm':
   1.234 +                    sb.append(d.getMessage(null));
   1.235 +                    break;
   1.236 +
   1.237 +                case '_':
   1.238 +                    sb.append(' ');
   1.239 +                    break;
   1.240 +
   1.241 +                case '%':
   1.242 +                    sb.append('%');
   1.243 +                    break;
   1.244 +
   1.245 +                default:
   1.246 +                    sb.append(c);
   1.247 +                    break;
   1.248 +                }
   1.249 +            }
   1.250 +            else
   1.251 +                sb.append(c);
   1.252 +        }
   1.253 +        return sb.toString();
   1.254 +    }
   1.255 +}

mercurial