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

Tue, 25 May 2010 15:54:51 -0700

author
ohair
date
Tue, 25 May 2010 15:54:51 -0700
changeset 554
9d9f26857129
parent 174
fdfed22db054
child 581
f2fdd52e4e87
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 2005, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * 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 enforceMandatory
   105      *                True if mandatory warnings and notes are being enforced.
   106      * @param prefix  A common prefix for the set of message keys for
   107      *                the messages that may be generated.
   108      */
   109     public MandatoryWarningHandler(Log log, boolean verbose,
   110                                    boolean enforceMandatory, String prefix) {
   111         this.log = log;
   112         this.verbose = verbose;
   113         this.prefix = prefix;
   114         this.enforceMandatory = enforceMandatory;
   115     }
   117     /**
   118      * Report a mandatory warning.
   119      */
   120     public void report(DiagnosticPosition pos, String msg, Object... args) {
   121         JavaFileObject currentSource = log.currentSourceFile();
   123         if (verbose) {
   124             if (sourcesWithReportedWarnings == null)
   125                 sourcesWithReportedWarnings = new HashSet<JavaFileObject>();
   127             if (log.nwarnings < log.MaxWarnings) {
   128                 // generate message and remember the source file
   129                 logMandatoryWarning(pos, msg, args);
   130                 sourcesWithReportedWarnings.add(currentSource);
   131             } else if (deferredDiagnosticKind == null) {
   132                 // set up deferred message
   133                 if (sourcesWithReportedWarnings.contains(currentSource)) {
   134                     // more errors in a file that already has reported warnings
   135                     deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILE;
   136                 } else {
   137                     // warnings in a new source file
   138                     deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
   139                 }
   140                 deferredDiagnosticSource = currentSource;
   141                 deferredDiagnosticArg = currentSource;
   142             } else if ((deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE
   143                         || deferredDiagnosticKind == DeferredDiagnosticKind.ADDITIONAL_IN_FILE)
   144                        && !equal(deferredDiagnosticSource, currentSource)) {
   145                 // additional errors in more than one source file
   146                 deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILES;
   147                 deferredDiagnosticArg = null;
   148             }
   149         } else {
   150             if (deferredDiagnosticKind == null) {
   151                 // warnings in a single source
   152                 deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
   153                 deferredDiagnosticSource = currentSource;
   154                 deferredDiagnosticArg = currentSource;
   155             }  else if (deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE &&
   156                         !equal(deferredDiagnosticSource, currentSource)) {
   157                 // warnings in multiple source files
   158                 deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILES;
   159                 deferredDiagnosticArg = null;
   160             }
   161         }
   162     }
   164     /**
   165      * Report any diagnostic that might have been deferred by previous calls of report().
   166      */
   167     public void reportDeferredDiagnostic() {
   168         if (deferredDiagnosticKind != null) {
   169             if (deferredDiagnosticArg == null)
   170                 logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
   171             else
   172                 logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
   174             if (!verbose)
   175                 logMandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
   176         }
   177     }
   179     /**
   180      * Check two objects, each possibly null, are either both null or are equal.
   181      */
   182     private static boolean equal(Object o1, Object o2) {
   183         return ((o1 == null || o2 == null) ? (o1 == o2) : o1.equals(o2));
   184     }
   186     /**
   187      * The log to which to report warnings.
   188      */
   189     private Log log;
   191     /**
   192      * Whether or not to report individual warnings, or simply to report a
   193      * single aggregate warning at the end of the compilation.
   194      */
   195     private boolean verbose;
   197     /**
   198      * The common prefix for all I18N message keys generated by this handler.
   199      */
   200     private String prefix;
   202     /**
   203      * A set containing the names of the source files for which specific
   204      * warnings have been generated -- i.e. in verbose mode.  If a source name
   205      * appears in this list, then deferred diagnostics will be phrased to
   206      * include "additionally"...
   207      */
   208     private Set<JavaFileObject> sourcesWithReportedWarnings;
   210     /**
   211      * A variable indicating the latest best guess at what the final
   212      * deferred diagnostic will be. Initially as specific and helpful
   213      * as possible, as more warnings are reported, the scope of the
   214      * diagnostic will be broadened.
   215      */
   216     private DeferredDiagnosticKind deferredDiagnosticKind;
   218     /**
   219      * If deferredDiagnosticKind is IN_FILE or ADDITIONAL_IN_FILE, this variable
   220      * gives the value of log.currentSource() for the file in question.
   221      */
   222     private JavaFileObject deferredDiagnosticSource;
   224     /**
   225      * An optional argument to be used when constructing the
   226      * deferred diagnostic message, based on deferredDiagnosticKind.
   227      * This variable should normally be set/updated whenever
   228      * deferredDiagnosticKind is updated.
   229      */
   230     private Object deferredDiagnosticArg;
   232     /**
   233      * True if mandatory warnings and notes are being enforced.
   234      */
   235     private final boolean enforceMandatory;
   237     /**
   238      * Reports a mandatory warning to the log.  If mandatory warnings
   239      * are not being enforced, treat this as an ordinary warning.
   240      */
   241     private void logMandatoryWarning(DiagnosticPosition pos, String msg,
   242                                      Object... args) {
   243         if (enforceMandatory)
   244             log.mandatoryWarning(pos, msg, args);
   245         else
   246             log.warning(pos, msg, args);
   247     }
   249     /**
   250      * Reports a mandatory note to the log.  If mandatory notes are
   251      * not being enforced, treat this as an ordinary note.
   252      */
   253     private void logMandatoryNote(JavaFileObject file, String msg, Object... args) {
   254         if (enforceMandatory)
   255             log.mandatoryNote(file, msg, args);
   256         else
   257             log.note(file, msg, args);
   258     }
   259 }

mercurial