src/share/classes/com/sun/tools/javac/main/Main.java

changeset 0
959103a6100f
child 2525
2eb010b6cb22
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java	Wed Apr 27 01:34:52 2016 +0800
     1.3 @@ -0,0 +1,699 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.main;
    1.30 +
    1.31 +import java.io.File;
    1.32 +import java.io.IOException;
    1.33 +import java.io.PrintWriter;
    1.34 +import java.net.URL;
    1.35 +import java.security.DigestInputStream;
    1.36 +import java.security.MessageDigest;
    1.37 +import java.util.Arrays;
    1.38 +import java.util.Collection;
    1.39 +import java.util.Iterator;
    1.40 +import java.util.LinkedHashSet;
    1.41 +import java.util.Set;
    1.42 +
    1.43 +import javax.annotation.processing.Processor;
    1.44 +import javax.tools.JavaFileManager;
    1.45 +import javax.tools.JavaFileObject;
    1.46 +
    1.47 +import com.sun.source.util.JavacTask;
    1.48 +import com.sun.source.util.Plugin;
    1.49 +import com.sun.tools.doclint.DocLint;
    1.50 +import com.sun.tools.javac.api.BasicJavacTask;
    1.51 +import com.sun.tools.javac.code.Source;
    1.52 +import com.sun.tools.javac.file.CacheFSInfo;
    1.53 +import com.sun.tools.javac.file.JavacFileManager;
    1.54 +import com.sun.tools.javac.jvm.Profile;
    1.55 +import com.sun.tools.javac.jvm.Target;
    1.56 +import com.sun.tools.javac.processing.AnnotationProcessingError;
    1.57 +import com.sun.tools.javac.processing.JavacProcessingEnvironment;
    1.58 +import com.sun.tools.javac.util.*;
    1.59 +import com.sun.tools.javac.util.Log.PrefixKind;
    1.60 +import com.sun.tools.javac.util.Log.WriterKind;
    1.61 +import com.sun.tools.javac.util.ServiceLoader;
    1.62 +import static com.sun.tools.javac.main.Option.*;
    1.63 +
    1.64 +/** This class provides a command line interface to the javac compiler.
    1.65 + *
    1.66 + *  <p><b>This is NOT part of any supported API.
    1.67 + *  If you write code that depends on this, you do so at your own risk.
    1.68 + *  This code and its internal interfaces are subject to change or
    1.69 + *  deletion without notice.</b>
    1.70 + */
    1.71 +public class Main {
    1.72 +
    1.73 +    /** The name of the compiler, for use in diagnostics.
    1.74 +     */
    1.75 +    String ownName;
    1.76 +
    1.77 +    /** The writer to use for diagnostic output.
    1.78 +     */
    1.79 +    PrintWriter out;
    1.80 +
    1.81 +    /** The log to use for diagnostic output.
    1.82 +     */
    1.83 +    public Log log;
    1.84 +
    1.85 +    /**
    1.86 +     * If true, certain errors will cause an exception, such as command line
    1.87 +     * arg errors, or exceptions in user provided code.
    1.88 +     */
    1.89 +    boolean apiMode;
    1.90 +
    1.91 +
    1.92 +    /** Result codes.
    1.93 +     */
    1.94 +    public enum Result {
    1.95 +        OK(0),        // Compilation completed with no errors.
    1.96 +        ERROR(1),     // Completed but reported errors.
    1.97 +        CMDERR(2),    // Bad command-line arguments
    1.98 +        SYSERR(3),    // System error or resource exhaustion.
    1.99 +        ABNORMAL(4);  // Compiler terminated abnormally
   1.100 +
   1.101 +        Result(int exitCode) {
   1.102 +            this.exitCode = exitCode;
   1.103 +        }
   1.104 +
   1.105 +        public boolean isOK() {
   1.106 +            return (exitCode == 0);
   1.107 +        }
   1.108 +
   1.109 +        public final int exitCode;
   1.110 +    }
   1.111 +
   1.112 +    private Option[] recognizedOptions =
   1.113 +            Option.getJavaCompilerOptions().toArray(new Option[0]);
   1.114 +
   1.115 +    private OptionHelper optionHelper = new OptionHelper() {
   1.116 +        @Override
   1.117 +        public String get(Option option) {
   1.118 +            return options.get(option);
   1.119 +        }
   1.120 +
   1.121 +        @Override
   1.122 +        public void put(String name, String value) {
   1.123 +            options.put(name, value);
   1.124 +        }
   1.125 +
   1.126 +        @Override
   1.127 +        public void remove(String name) {
   1.128 +            options.remove(name);
   1.129 +        }
   1.130 +
   1.131 +        @Override
   1.132 +        public Log getLog() {
   1.133 +            return log;
   1.134 +        }
   1.135 +
   1.136 +        @Override
   1.137 +        public String getOwnName() {
   1.138 +            return ownName;
   1.139 +        }
   1.140 +
   1.141 +        @Override
   1.142 +        public void error(String key, Object... args) {
   1.143 +            Main.this.error(key, args);
   1.144 +        }
   1.145 +
   1.146 +        @Override
   1.147 +        public void addFile(File f) {
   1.148 +            filenames.add(f);
   1.149 +        }
   1.150 +
   1.151 +        @Override
   1.152 +        public void addClassName(String s) {
   1.153 +            classnames.append(s);
   1.154 +        }
   1.155 +
   1.156 +    };
   1.157 +
   1.158 +    /**
   1.159 +     * Construct a compiler instance.
   1.160 +     */
   1.161 +    public Main(String name) {
   1.162 +        this(name, new PrintWriter(System.err, true));
   1.163 +    }
   1.164 +
   1.165 +    /**
   1.166 +     * Construct a compiler instance.
   1.167 +     */
   1.168 +    public Main(String name, PrintWriter out) {
   1.169 +        this.ownName = name;
   1.170 +        this.out = out;
   1.171 +    }
   1.172 +
   1.173 +    /** A table of all options that's passed to the JavaCompiler constructor.  */
   1.174 +    private Options options = null;
   1.175 +
   1.176 +    /** The list of source files to process
   1.177 +     */
   1.178 +    public Set<File> filenames = null; // XXX sb protected
   1.179 +
   1.180 +    /** List of class files names passed on the command line
   1.181 +     */
   1.182 +    public ListBuffer<String> classnames = null; // XXX sb protected
   1.183 +
   1.184 +    /** Report a usage error.
   1.185 +     */
   1.186 +    void error(String key, Object... args) {
   1.187 +        if (apiMode) {
   1.188 +            String msg = log.localize(PrefixKind.JAVAC, key, args);
   1.189 +            throw new PropagatedException(new IllegalStateException(msg));
   1.190 +        }
   1.191 +        warning(key, args);
   1.192 +        log.printLines(PrefixKind.JAVAC, "msg.usage", ownName);
   1.193 +    }
   1.194 +
   1.195 +    /** Report a warning.
   1.196 +     */
   1.197 +    void warning(String key, Object... args) {
   1.198 +        log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
   1.199 +    }
   1.200 +
   1.201 +    public Option getOption(String flag) {
   1.202 +        for (Option option : recognizedOptions) {
   1.203 +            if (option.matches(flag))
   1.204 +                return option;
   1.205 +        }
   1.206 +        return null;
   1.207 +    }
   1.208 +
   1.209 +    public void setOptions(Options options) {
   1.210 +        if (options == null)
   1.211 +            throw new NullPointerException();
   1.212 +        this.options = options;
   1.213 +    }
   1.214 +
   1.215 +    public void setAPIMode(boolean apiMode) {
   1.216 +        this.apiMode = apiMode;
   1.217 +    }
   1.218 +
   1.219 +    /** Process command line arguments: store all command line options
   1.220 +     *  in `options' table and return all source filenames.
   1.221 +     *  @param flags    The array of command line arguments.
   1.222 +     */
   1.223 +    public Collection<File> processArgs(String[] flags) { // XXX sb protected
   1.224 +        return processArgs(flags, null);
   1.225 +    }
   1.226 +
   1.227 +    public Collection<File> processArgs(String[] flags, String[] classNames) { // XXX sb protected
   1.228 +        int ac = 0;
   1.229 +        while (ac < flags.length) {
   1.230 +            String flag = flags[ac];
   1.231 +            ac++;
   1.232 +
   1.233 +            Option option = null;
   1.234 +
   1.235 +            if (flag.length() > 0) {
   1.236 +                // quick hack to speed up file processing:
   1.237 +                // if the option does not begin with '-', there is no need to check
   1.238 +                // most of the compiler options.
   1.239 +                int firstOptionToCheck = flag.charAt(0) == '-' ? 0 : recognizedOptions.length-1;
   1.240 +                for (int j=firstOptionToCheck; j<recognizedOptions.length; j++) {
   1.241 +                    if (recognizedOptions[j].matches(flag)) {
   1.242 +                        option = recognizedOptions[j];
   1.243 +                        break;
   1.244 +                    }
   1.245 +                }
   1.246 +            }
   1.247 +
   1.248 +            if (option == null) {
   1.249 +                error("err.invalid.flag", flag);
   1.250 +                return null;
   1.251 +            }
   1.252 +
   1.253 +            if (option.hasArg()) {
   1.254 +                if (ac == flags.length) {
   1.255 +                    error("err.req.arg", flag);
   1.256 +                    return null;
   1.257 +                }
   1.258 +                String operand = flags[ac];
   1.259 +                ac++;
   1.260 +                if (option.process(optionHelper, flag, operand))
   1.261 +                    return null;
   1.262 +            } else {
   1.263 +                if (option.process(optionHelper, flag))
   1.264 +                    return null;
   1.265 +            }
   1.266 +        }
   1.267 +
   1.268 +        if (options.get(PROFILE) != null && options.get(BOOTCLASSPATH) != null) {
   1.269 +            error("err.profile.bootclasspath.conflict");
   1.270 +            return null;
   1.271 +        }
   1.272 +
   1.273 +        if (this.classnames != null && classNames != null) {
   1.274 +            this.classnames.addAll(Arrays.asList(classNames));
   1.275 +        }
   1.276 +
   1.277 +        if (!checkDirectory(D))
   1.278 +            return null;
   1.279 +        if (!checkDirectory(S))
   1.280 +            return null;
   1.281 +
   1.282 +        String sourceString = options.get(SOURCE);
   1.283 +        Source source = (sourceString != null)
   1.284 +            ? Source.lookup(sourceString)
   1.285 +            : Source.DEFAULT;
   1.286 +        String targetString = options.get(TARGET);
   1.287 +        Target target = (targetString != null)
   1.288 +            ? Target.lookup(targetString)
   1.289 +            : Target.DEFAULT;
   1.290 +        // We don't check source/target consistency for CLDC, as J2ME
   1.291 +        // profiles are not aligned with J2SE targets; moreover, a
   1.292 +        // single CLDC target may have many profiles.  In addition,
   1.293 +        // this is needed for the continued functioning of the JSR14
   1.294 +        // prototype.
   1.295 +        if (Character.isDigit(target.name.charAt(0))) {
   1.296 +            if (target.compareTo(source.requiredTarget()) < 0) {
   1.297 +                if (targetString != null) {
   1.298 +                    if (sourceString == null) {
   1.299 +                        warning("warn.target.default.source.conflict",
   1.300 +                                targetString,
   1.301 +                                source.requiredTarget().name);
   1.302 +                    } else {
   1.303 +                        warning("warn.source.target.conflict",
   1.304 +                                sourceString,
   1.305 +                                source.requiredTarget().name);
   1.306 +                    }
   1.307 +                    return null;
   1.308 +                } else {
   1.309 +                    target = source.requiredTarget();
   1.310 +                    options.put("-target", target.name);
   1.311 +                }
   1.312 +            } else {
   1.313 +                if (targetString == null && !source.allowGenerics()) {
   1.314 +                    target = Target.JDK1_4;
   1.315 +                    options.put("-target", target.name);
   1.316 +                }
   1.317 +            }
   1.318 +        }
   1.319 +
   1.320 +        String profileString = options.get(PROFILE);
   1.321 +        if (profileString != null) {
   1.322 +            Profile profile = Profile.lookup(profileString);
   1.323 +            if (!profile.isValid(target)) {
   1.324 +                warning("warn.profile.target.conflict", profileString, target.name);
   1.325 +                return null;
   1.326 +            }
   1.327 +        }
   1.328 +
   1.329 +        // handle this here so it works even if no other options given
   1.330 +        String showClass = options.get("showClass");
   1.331 +        if (showClass != null) {
   1.332 +            if (showClass.equals("showClass")) // no value given for option
   1.333 +                showClass = "com.sun.tools.javac.Main";
   1.334 +            showClass(showClass);
   1.335 +        }
   1.336 +
   1.337 +        options.notifyListeners();
   1.338 +
   1.339 +        return filenames;
   1.340 +    }
   1.341 +    // where
   1.342 +        private boolean checkDirectory(Option option) {
   1.343 +            String value = options.get(option);
   1.344 +            if (value == null)
   1.345 +                return true;
   1.346 +            File file = new File(value);
   1.347 +            if (!file.exists()) {
   1.348 +                error("err.dir.not.found", value);
   1.349 +                return false;
   1.350 +            }
   1.351 +            if (!file.isDirectory()) {
   1.352 +                error("err.file.not.directory", value);
   1.353 +                return false;
   1.354 +            }
   1.355 +            return true;
   1.356 +        }
   1.357 +
   1.358 +    /** Programmatic interface for main function.
   1.359 +     * @param args    The command line parameters.
   1.360 +     */
   1.361 +    public Result compile(String[] args) {
   1.362 +        Context context = new Context();
   1.363 +        JavacFileManager.preRegister(context); // can't create it until Log has been set up
   1.364 +        Result result = compile(args, context);
   1.365 +        if (fileManager instanceof JavacFileManager) {
   1.366 +            // A fresh context was created above, so jfm must be a JavacFileManager
   1.367 +            ((JavacFileManager)fileManager).close();
   1.368 +        }
   1.369 +        return result;
   1.370 +    }
   1.371 +
   1.372 +    public Result compile(String[] args, Context context) {
   1.373 +        return compile(args, context, List.<JavaFileObject>nil(), null);
   1.374 +    }
   1.375 +
   1.376 +    /** Programmatic interface for main function.
   1.377 +     * @param args    The command line parameters.
   1.378 +     */
   1.379 +    public Result compile(String[] args,
   1.380 +                       Context context,
   1.381 +                       List<JavaFileObject> fileObjects,
   1.382 +                       Iterable<? extends Processor> processors)
   1.383 +    {
   1.384 +        return compile(args,  null, context, fileObjects, processors);
   1.385 +    }
   1.386 +
   1.387 +    public Result compile(String[] args,
   1.388 +                          String[] classNames,
   1.389 +                          Context context,
   1.390 +                          List<JavaFileObject> fileObjects,
   1.391 +                          Iterable<? extends Processor> processors)
   1.392 +    {
   1.393 +        context.put(Log.outKey, out);
   1.394 +        log = Log.instance(context);
   1.395 +
   1.396 +        if (options == null)
   1.397 +            options = Options.instance(context); // creates a new one
   1.398 +
   1.399 +        filenames = new LinkedHashSet<File>();
   1.400 +        classnames = new ListBuffer<String>();
   1.401 +        JavaCompiler comp = null;
   1.402 +        /*
   1.403 +         * TODO: Logic below about what is an acceptable command line
   1.404 +         * should be updated to take annotation processing semantics
   1.405 +         * into account.
   1.406 +         */
   1.407 +        try {
   1.408 +            if (args.length == 0
   1.409 +                    && (classNames == null || classNames.length == 0)
   1.410 +                    && fileObjects.isEmpty()) {
   1.411 +                Option.HELP.process(optionHelper, "-help");
   1.412 +                return Result.CMDERR;
   1.413 +            }
   1.414 +
   1.415 +            Collection<File> files;
   1.416 +            try {
   1.417 +                files = processArgs(CommandLine.parse(args), classNames);
   1.418 +                if (files == null) {
   1.419 +                    // null signals an error in options, abort
   1.420 +                    return Result.CMDERR;
   1.421 +                } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) {
   1.422 +                    // it is allowed to compile nothing if just asking for help or version info
   1.423 +                    if (options.isSet(HELP)
   1.424 +                        || options.isSet(X)
   1.425 +                        || options.isSet(VERSION)
   1.426 +                        || options.isSet(FULLVERSION))
   1.427 +                        return Result.OK;
   1.428 +                    if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
   1.429 +                        error("err.no.source.files.classes");
   1.430 +                    } else {
   1.431 +                        error("err.no.source.files");
   1.432 +                    }
   1.433 +                    return Result.CMDERR;
   1.434 +                }
   1.435 +            } catch (java.io.FileNotFoundException e) {
   1.436 +                warning("err.file.not.found", e.getMessage());
   1.437 +                return Result.SYSERR;
   1.438 +            }
   1.439 +
   1.440 +            boolean forceStdOut = options.isSet("stdout");
   1.441 +            if (forceStdOut) {
   1.442 +                log.flush();
   1.443 +                log.setWriters(new PrintWriter(System.out, true));
   1.444 +            }
   1.445 +
   1.446 +            // allow System property in following line as a Mustang legacy
   1.447 +            boolean batchMode = (options.isUnset("nonBatchMode")
   1.448 +                        && System.getProperty("nonBatchMode") == null);
   1.449 +            if (batchMode)
   1.450 +                CacheFSInfo.preRegister(context);
   1.451 +
   1.452 +            // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
   1.453 +            // invoke any available plugins
   1.454 +            String plugins = options.get(PLUGIN);
   1.455 +            if (plugins != null) {
   1.456 +                JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
   1.457 +                ClassLoader cl = pEnv.getProcessorClassLoader();
   1.458 +                ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
   1.459 +                Set<List<String>> pluginsToCall = new LinkedHashSet<List<String>>();
   1.460 +                for (String plugin: plugins.split("\\x00")) {
   1.461 +                    pluginsToCall.add(List.from(plugin.split("\\s+")));
   1.462 +                }
   1.463 +                JavacTask task = null;
   1.464 +                Iterator<Plugin> iter = sl.iterator();
   1.465 +                while (iter.hasNext()) {
   1.466 +                    Plugin plugin = iter.next();
   1.467 +                    for (List<String> p: pluginsToCall) {
   1.468 +                        if (plugin.getName().equals(p.head)) {
   1.469 +                            pluginsToCall.remove(p);
   1.470 +                            try {
   1.471 +                                if (task == null)
   1.472 +                                    task = JavacTask.instance(pEnv);
   1.473 +                                plugin.init(task, p.tail.toArray(new String[p.tail.size()]));
   1.474 +                            } catch (Throwable ex) {
   1.475 +                                if (apiMode)
   1.476 +                                    throw new RuntimeException(ex);
   1.477 +                                pluginMessage(ex);
   1.478 +                                return Result.SYSERR;
   1.479 +                            }
   1.480 +                        }
   1.481 +                    }
   1.482 +                }
   1.483 +                for (List<String> p: pluginsToCall) {
   1.484 +                    log.printLines(PrefixKind.JAVAC, "msg.plugin.not.found", p.head);
   1.485 +                }
   1.486 +            }
   1.487 +
   1.488 +            comp = JavaCompiler.instance(context);
   1.489 +
   1.490 +            // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
   1.491 +            String xdoclint = options.get(XDOCLINT);
   1.492 +            String xdoclintCustom = options.get(XDOCLINT_CUSTOM);
   1.493 +            if (xdoclint != null || xdoclintCustom != null) {
   1.494 +                Set<String> doclintOpts = new LinkedHashSet<String>();
   1.495 +                if (xdoclint != null)
   1.496 +                    doclintOpts.add(DocLint.XMSGS_OPTION);
   1.497 +                if (xdoclintCustom != null) {
   1.498 +                    for (String s: xdoclintCustom.split("\\s+")) {
   1.499 +                        if (s.isEmpty())
   1.500 +                            continue;
   1.501 +                        doclintOpts.add(s.replace(XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
   1.502 +                    }
   1.503 +                }
   1.504 +                if (!(doclintOpts.size() == 1
   1.505 +                        && doclintOpts.iterator().next().equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) {
   1.506 +                    JavacTask t = BasicJavacTask.instance(context);
   1.507 +                    // standard doclet normally generates H1, H2
   1.508 +                    doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
   1.509 +                    new DocLint().init(t, doclintOpts.toArray(new String[doclintOpts.size()]));
   1.510 +                    comp.keepComments = true;
   1.511 +                }
   1.512 +            }
   1.513 +
   1.514 +            fileManager = context.get(JavaFileManager.class);
   1.515 +
   1.516 +            if (!files.isEmpty()) {
   1.517 +                // add filenames to fileObjects
   1.518 +                comp = JavaCompiler.instance(context);
   1.519 +                List<JavaFileObject> otherFiles = List.nil();
   1.520 +                JavacFileManager dfm = (JavacFileManager)fileManager;
   1.521 +                for (JavaFileObject fo : dfm.getJavaFileObjectsFromFiles(files))
   1.522 +                    otherFiles = otherFiles.prepend(fo);
   1.523 +                for (JavaFileObject fo : otherFiles)
   1.524 +                    fileObjects = fileObjects.prepend(fo);
   1.525 +            }
   1.526 +            comp.compile(fileObjects,
   1.527 +                         classnames.toList(),
   1.528 +                         processors);
   1.529 +
   1.530 +            if (log.expectDiagKeys != null) {
   1.531 +                if (log.expectDiagKeys.isEmpty()) {
   1.532 +                    log.printRawLines("all expected diagnostics found");
   1.533 +                    return Result.OK;
   1.534 +                } else {
   1.535 +                    log.printRawLines("expected diagnostic keys not found: " + log.expectDiagKeys);
   1.536 +                    return Result.ERROR;
   1.537 +                }
   1.538 +            }
   1.539 +
   1.540 +            if (comp.errorCount() != 0)
   1.541 +                return Result.ERROR;
   1.542 +        } catch (IOException ex) {
   1.543 +            ioMessage(ex);
   1.544 +            return Result.SYSERR;
   1.545 +        } catch (OutOfMemoryError ex) {
   1.546 +            resourceMessage(ex);
   1.547 +            return Result.SYSERR;
   1.548 +        } catch (StackOverflowError ex) {
   1.549 +            resourceMessage(ex);
   1.550 +            return Result.SYSERR;
   1.551 +        } catch (FatalError ex) {
   1.552 +            feMessage(ex);
   1.553 +            return Result.SYSERR;
   1.554 +        } catch (AnnotationProcessingError ex) {
   1.555 +            if (apiMode)
   1.556 +                throw new RuntimeException(ex.getCause());
   1.557 +            apMessage(ex);
   1.558 +            return Result.SYSERR;
   1.559 +        } catch (ClientCodeException ex) {
   1.560 +            // as specified by javax.tools.JavaCompiler#getTask
   1.561 +            // and javax.tools.JavaCompiler.CompilationTask#call
   1.562 +            throw new RuntimeException(ex.getCause());
   1.563 +        } catch (PropagatedException ex) {
   1.564 +            throw ex.getCause();
   1.565 +        } catch (Throwable ex) {
   1.566 +            // Nasty.  If we've already reported an error, compensate
   1.567 +            // for buggy compiler error recovery by swallowing thrown
   1.568 +            // exceptions.
   1.569 +            if (comp == null || comp.errorCount() == 0 ||
   1.570 +                options == null || options.isSet("dev"))
   1.571 +                bugMessage(ex);
   1.572 +            return Result.ABNORMAL;
   1.573 +        } finally {
   1.574 +            if (comp != null) {
   1.575 +                try {
   1.576 +                    comp.close();
   1.577 +                } catch (ClientCodeException ex) {
   1.578 +                    throw new RuntimeException(ex.getCause());
   1.579 +                }
   1.580 +            }
   1.581 +            filenames = null;
   1.582 +            options = null;
   1.583 +        }
   1.584 +        return Result.OK;
   1.585 +    }
   1.586 +
   1.587 +    /** Print a message reporting an internal error.
   1.588 +     */
   1.589 +    void bugMessage(Throwable ex) {
   1.590 +        log.printLines(PrefixKind.JAVAC, "msg.bug", JavaCompiler.version());
   1.591 +        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.592 +    }
   1.593 +
   1.594 +    /** Print a message reporting a fatal error.
   1.595 +     */
   1.596 +    void feMessage(Throwable ex) {
   1.597 +        log.printRawLines(ex.getMessage());
   1.598 +        if (ex.getCause() != null && options.isSet("dev")) {
   1.599 +            ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.600 +        }
   1.601 +    }
   1.602 +
   1.603 +    /** Print a message reporting an input/output error.
   1.604 +     */
   1.605 +    void ioMessage(Throwable ex) {
   1.606 +        log.printLines(PrefixKind.JAVAC, "msg.io");
   1.607 +        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.608 +    }
   1.609 +
   1.610 +    /** Print a message reporting an out-of-resources error.
   1.611 +     */
   1.612 +    void resourceMessage(Throwable ex) {
   1.613 +        log.printLines(PrefixKind.JAVAC, "msg.resource");
   1.614 +        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.615 +    }
   1.616 +
   1.617 +    /** Print a message reporting an uncaught exception from an
   1.618 +     * annotation processor.
   1.619 +     */
   1.620 +    void apMessage(AnnotationProcessingError ex) {
   1.621 +        log.printLines(PrefixKind.JAVAC, "msg.proc.annotation.uncaught.exception");
   1.622 +        ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.623 +    }
   1.624 +
   1.625 +    /** Print a message reporting an uncaught exception from an
   1.626 +     * annotation processor.
   1.627 +     */
   1.628 +    void pluginMessage(Throwable ex) {
   1.629 +        log.printLines(PrefixKind.JAVAC, "msg.plugin.uncaught.exception");
   1.630 +        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
   1.631 +    }
   1.632 +
   1.633 +    /** Display the location and checksum of a class. */
   1.634 +    void showClass(String className) {
   1.635 +        PrintWriter pw = log.getWriter(WriterKind.NOTICE);
   1.636 +        pw.println("javac: show class: " + className);
   1.637 +        URL url = getClass().getResource('/' + className.replace('.', '/') + ".class");
   1.638 +        if (url == null)
   1.639 +            pw.println("  class not found");
   1.640 +        else {
   1.641 +            pw.println("  " + url);
   1.642 +            try {
   1.643 +                final String algorithm = "MD5";
   1.644 +                byte[] digest;
   1.645 +                MessageDigest md = MessageDigest.getInstance(algorithm);
   1.646 +                DigestInputStream in = new DigestInputStream(url.openStream(), md);
   1.647 +                try {
   1.648 +                    byte[] buf = new byte[8192];
   1.649 +                    int n;
   1.650 +                    do { n = in.read(buf); } while (n > 0);
   1.651 +                    digest = md.digest();
   1.652 +                } finally {
   1.653 +                    in.close();
   1.654 +                }
   1.655 +                StringBuilder sb = new StringBuilder();
   1.656 +                for (byte b: digest)
   1.657 +                    sb.append(String.format("%02x", b));
   1.658 +                pw.println("  " + algorithm + " checksum: " + sb);
   1.659 +            } catch (Exception e) {
   1.660 +                pw.println("  cannot compute digest: " + e);
   1.661 +            }
   1.662 +        }
   1.663 +    }
   1.664 +
   1.665 +    private JavaFileManager fileManager;
   1.666 +
   1.667 +    /* ************************************************************************
   1.668 +     * Internationalization
   1.669 +     *************************************************************************/
   1.670 +
   1.671 +//    /** Find a localized string in the resource bundle.
   1.672 +//     *  @param key     The key for the localized string.
   1.673 +//     */
   1.674 +//    public static String getLocalizedString(String key, Object... args) { // FIXME sb private
   1.675 +//        try {
   1.676 +//            if (messages == null)
   1.677 +//                messages = new JavacMessages(javacBundleName);
   1.678 +//            return messages.getLocalizedString("javac." + key, args);
   1.679 +//        }
   1.680 +//        catch (MissingResourceException e) {
   1.681 +//            throw new Error("Fatal Error: Resource for javac is missing", e);
   1.682 +//        }
   1.683 +//    }
   1.684 +//
   1.685 +//    public static void useRawMessages(boolean enable) {
   1.686 +//        if (enable) {
   1.687 +//            messages = new JavacMessages(javacBundleName) {
   1.688 +//                    @Override
   1.689 +//                    public String getLocalizedString(String key, Object... args) {
   1.690 +//                        return key;
   1.691 +//                    }
   1.692 +//                };
   1.693 +//        } else {
   1.694 +//            messages = new JavacMessages(javacBundleName);
   1.695 +//        }
   1.696 +//    }
   1.697 +
   1.698 +    public static final String javacBundleName =
   1.699 +        "com.sun.tools.javac.resources.javac";
   1.700 +//
   1.701 +//    private static JavacMessages messages;
   1.702 +}

mercurial