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

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1
9a66ca7c79fa
child 60
29d2485c1085
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.util;
    28 import java.util.HashSet;
    29 import java.util.Set;
    30 import javax.tools.JavaFileObject;
    32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    35 /**
    36  * A handler to process mandatory warnings, setting up a deferred diagnostic
    37  * to be printed at the end of the compilation if some warnings get suppressed
    38  * because too many warnings have already been generated.
    39  *
    40  * Note that the SuppressWarnings annotation can be used to suppress warnings
    41  * about conditions that would otherwise merit a warning. Such processing
    42  * is done when the condition is detected, and in those cases, no call is
    43  * made on any API to generate a warning at all. In consequence, this handler only
    44  * gets to handle those warnings that JLS says must be generated.
    45  *
    46  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    47  *  you write code that depends on this, you do so at your own risk.
    48  *  This code and its internal interfaces are subject to change or
    49  *  deletion without notice.</b>
    50  */
    51 public class MandatoryWarningHandler {
    53     /**
    54      * The kinds of different deferred diagnostics that might be generated
    55      * if a mandatory warning is suppressed because too many warnings have
    56      * already been output.
    57      *
    58      * The parameter is a fragment used to build an I18N message key for Log.
    59      */
    60     private enum DeferredDiagnosticKind {
    61         /**
    62          * This kind is used when a single specific file is found to have warnings
    63          * and no similar warnings have already been given.
    64          * It generates a message like:
    65          *      FILE has ISSUES
    66          */
    67         IN_FILE(".filename"),
    68         /**
    69          * This kind is used when a single specific file is found to have warnings
    70          * and when similar warnings have already been reported for the file.
    71          * It generates a message like:
    72          *      FILE has additional ISSUES
    73          */
    74         ADDITIONAL_IN_FILE(".filename.additional"),
    75         /**
    76          * This kind is used when multiple files have been found to have warnings,
    77          * and none of them have had any similar warnings.
    78          * It generates a message like:
    79          *      Some files have ISSUES
    80          */
    81         IN_FILES(".plural"),
    82         /**
    83          * This kind is used when multiple files have been found to have warnings,
    84          * and some of them have had already had specific similar warnings.
    85          * It generates a message like:
    86          *      Some files have additional ISSUES
    87          */
    88         ADDITIONAL_IN_FILES(".plural.additional");
    90         DeferredDiagnosticKind(String v) { value = v; }
    91         String getKey(String prefix) { return prefix + value; }
    93         private String value;
    94     }
    97     /**
    98      * Create a handler for mandatory warnings.
    99      * @param log     The log on which to generate any diagnostics
   100      * @param verbose Specify whether or not detailed messages about
   101      *                individual instances should be given, or whether an aggregate
   102      *                message should be generated at the end of the compilation.
   103      *                Typically set via  -Xlint:option.
   104      * @param prefix  A common prefix for the set of message keys for
   105      *                the messages that may be generated.
   106      */
   107     public MandatoryWarningHandler(Log log, boolean verbose, String prefix) {
   108         this.log = log;
   109         this.verbose = verbose;
   110         this.prefix = prefix;
   111     }
   113     /**
   114      * Report a mandatory warning.
   115      */
   116     public void report(DiagnosticPosition pos, String msg, Object... args) {
   117         JavaFileObject currentSource = log.currentSource();
   119         if (verbose) {
   120             if (sourcesWithReportedWarnings == null)
   121                 sourcesWithReportedWarnings = new HashSet<JavaFileObject>();
   123             if (log.nwarnings < log.MaxWarnings) {
   124                 // generate message and remember the source file
   125                 log.mandatoryWarning(pos, msg, args);
   126                 sourcesWithReportedWarnings.add(currentSource);
   127             } else if (deferredDiagnosticKind == null) {
   128                 // set up deferred message
   129                 if (sourcesWithReportedWarnings.contains(currentSource)) {
   130                     // more errors in a file that already has reported warnings
   131                     deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILE;
   132                 } else {
   133                     // warnings in a new source file
   134                     deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
   135                 }
   136                 deferredDiagnosticSource = currentSource;
   137                 deferredDiagnosticArg = currentSource;
   138             } else if ((deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE
   139                         || deferredDiagnosticKind == DeferredDiagnosticKind.ADDITIONAL_IN_FILE)
   140                        && !equal(deferredDiagnosticSource, currentSource)) {
   141                 // additional errors in more than one source file
   142                 deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILES;
   143                 deferredDiagnosticArg = null;
   144             }
   145         } else {
   146             if (deferredDiagnosticKind == null) {
   147                 // warnings in a single source
   148                 deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
   149                 deferredDiagnosticSource = currentSource;
   150                 deferredDiagnosticArg = currentSource;
   151             }  else if (deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE &&
   152                         !equal(deferredDiagnosticSource, currentSource)) {
   153                 // warnings in multiple source files
   154                 deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILES;
   155                 deferredDiagnosticArg = null;
   156             }
   157         }
   158     }
   160     /**
   161      * Report any diagnostic that might have been deferred by previous calls of report().
   162      */
   163     public void reportDeferredDiagnostic() {
   164         if (deferredDiagnosticKind != null) {
   165             if (deferredDiagnosticArg == null)
   166                 log.mandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
   167             else
   168                 log.mandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
   170             if (!verbose)
   171                 log.mandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
   172         }
   173     }
   175     /**
   176      * Check two objects, each possibly null, are either both null or are equal.
   177      */
   178     private static boolean equal(Object o1, Object o2) {
   179         return ((o1 == null || o2 == null) ? (o1 == o2) : o1.equals(o2));
   180     }
   182     /**
   183      * The log to which to report warnings.
   184      */
   185     private Log log;
   187     /**
   188      * Whether or not to report individual warnings, or simply to report a
   189      * single aggregate warning at the end of the compilation.
   190      */
   191     private boolean verbose;
   193     /**
   194      * The common prefix for all I18N message keys generated by this handler.
   195      */
   196     private String prefix;
   198     /**
   199      * A set containing the names of the source files for which specific
   200      * warnings have been generated -- i.e. in verbose mode.  If a source name
   201      * appears in this list, then deferred diagnostics will be phrased to
   202      * include "additionally"...
   203      */
   204     private Set<JavaFileObject> sourcesWithReportedWarnings;
   206     /**
   207      * A variable indicating the latest best guess at what the final
   208      * deferred diagnostic will be. Initially as specific and helpful
   209      * as possible, as more warnings are reported, the scope of the
   210      * diagnostic will be broadened.
   211      */
   212     private DeferredDiagnosticKind deferredDiagnosticKind;
   214     /**
   215      * If deferredDiagnosticKind is IN_FILE or ADDITIONAL_IN_FILE, this variable
   216      * gives the value of log.currentSource() for the file in question.
   217      */
   218     private JavaFileObject deferredDiagnosticSource;
   220     /**
   221      * An optional argument to be used when constructing the
   222      * deferred diagnostic message, based on deferredDiagnosticKind.
   223      * This variable should normally be set/updated whenever
   224      * deferredDiagnosticKind is updated.
   225      */
   226     private Object deferredDiagnosticArg;
   227 }

mercurial