Search in sources :

Example 1 with UsageMessageNeededException

use of com.sun.tools.apt.comp.UsageMessageNeededException in project ceylon-compiler by ceylon.

the class Main method compile.

/** Programmatic interface for main function.
     * @param args    The command line parameters.
     */
public int compile(String[] args, AnnotationProcessorFactory factory) {
    int returnCode = 0;
    providedFactory = factory;
    Context context = new Context();
    JavacFileManager.preRegister(context);
    options = Options.instance(context);
    Bark bark;
    /*
         * Process the command line options to create the intial
         * options data.  This processing is at least partially reused
         * by any recursive apt calls.
         */
    // For testing: assume all arguments in forcedOpts are
    // prefixed to command line arguments.
    processArgs(forcedOpts);
    /*
         * A run of apt only gets passed the most recently generated
         * files; the initial run of apt gets passed the files from
         * the command line.
         */
    java.util.List<String> origFilenames;
    try {
        // assign args the result of parse to capture results of
        // '@file' expansion
        origFilenames = processArgs((args = CommandLine.parse(args)));
        if (options.get("suppress-tool-api-removal-message") == null) {
            Bark.printLines(out, getLocalizedString("misc.Deprecation"));
        }
        if (origFilenames == null) {
            return EXIT_CMDERR;
        } else if (origFilenames.size() == 0) {
            // it is allowed to compile nothing if just asking for help
            if (options.get("-help") != null || options.get("-X") != null)
                return EXIT_OK;
        }
    } catch (java.io.FileNotFoundException e) {
        Bark.printLines(out, ownName + ": " + getLocalizedString("err.file.not.found", e.getMessage()));
        return EXIT_SYSERR;
    } catch (IOException ex) {
        ioMessage(ex);
        return EXIT_SYSERR;
    } catch (OutOfMemoryError ex) {
        resourceMessage(ex);
        return EXIT_SYSERR;
    } catch (StackOverflowError ex) {
        resourceMessage(ex);
        return EXIT_SYSERR;
    } catch (FatalError ex) {
        feMessage(ex);
        return EXIT_SYSERR;
    } catch (sun.misc.ServiceConfigurationError sce) {
        sceMessage(sce);
        return EXIT_ABNORMAL;
    } catch (Throwable ex) {
        bugMessage(ex);
        return EXIT_ABNORMAL;
    }
    boolean firstRound = true;
    boolean needSourcePath = false;
    boolean needClassPath = false;
    boolean classesAsDecls = options.get("-XclassesAsDecls") != null;
    /*
         * Create augumented classpath and sourcepath values.
         *
         * If any of the prior apt rounds generated any new source
         * files, the n'th apt round (and any javac invocation) has the
         * source destination path ("-s path") as the last element of
         * the "-sourcepath" to the n'th call.
         *
         * If any of the prior apt rounds generated any new class files,
         * the n'th apt round (and any javac invocation) has the class
         * destination path ("-d path") as the last element of the
         * "-classpath" to the n'th call.
         */
    String augmentedSourcePath = "";
    String augmentedClassPath = "";
    String baseClassPath = "";
    try {
        /*
             * Record original options for future annotation processor
             * invocations.
             */
        origOptions = new HashMap<String, String>(options.size());
        for (String s : options.keySet()) {
            String value;
            if (s.equals(value = options.get(s)))
                origOptions.put(s, (String) null);
            else
                origOptions.put(s, value);
        }
        origOptions = Collections.unmodifiableMap(origOptions);
        JavacFileManager fm = (JavacFileManager) context.get(JavaFileManager.class);
        {
            // Note: it might be necessary to check for an empty
            // component ("") of the source path or class path
            String sourceDest = options.get("-s");
            if (fm.hasLocation(StandardLocation.SOURCE_PATH)) {
                for (File f : fm.getLocation(StandardLocation.SOURCE_PATH)) augmentedSourcePath += (f + File.pathSeparator);
                augmentedSourcePath += (sourceDest == null) ? "." : sourceDest;
            } else {
                augmentedSourcePath = ".";
                if (sourceDest != null)
                    augmentedSourcePath += (File.pathSeparator + sourceDest);
            }
            String classDest = options.get("-d");
            if (fm.hasLocation(StandardLocation.CLASS_PATH)) {
                for (File f : fm.getLocation(StandardLocation.CLASS_PATH)) baseClassPath += (f + File.pathSeparator);
                // put baseClassPath into map to handle any
                // value needed for the classloader
                options.put("-classpath", baseClassPath);
                augmentedClassPath = baseClassPath + ((classDest == null) ? "." : classDest);
            } else {
                baseClassPath = ".";
                if (classDest != null)
                    augmentedClassPath = baseClassPath + (File.pathSeparator + classDest);
            }
            assert options.get("-classpath") != null;
        }
        /*
             * Create base and augmented class loaders
             */
        ClassLoader augmentedAptCL = null;
        {
            /*
             * Use a url class loader to look for classes on the
             * user-specified class path. Prepend computed bootclass
             * path, which includes extdirs, to the URLClassLoader apt
             * uses.
             */
            String aptclasspath = "";
            String bcp = "";
            Iterable<? extends File> bootclasspath = fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
            if (bootclasspath != null) {
                for (File f : bootclasspath) bcp += (f + File.pathSeparator);
            }
            // If the factory path is set, use that path
            if (providedFactory == null)
                aptclasspath = options.get("-factorypath");
            if (aptclasspath == null)
                aptclasspath = options.get("-classpath");
            assert aptclasspath != null;
            aptclasspath = (bcp + aptclasspath);
            aptCL = new URLClassLoader(pathToURLs(aptclasspath));
            if (providedFactory == null && // same CL even if new class files written
            options.get("-factorypath") != null)
                augmentedAptCL = aptCL;
            else {
                // Create class loader in case new class files are
                // written
                augmentedAptCL = new URLClassLoader(pathToURLs(augmentedClassPath.substring(baseClassPath.length())), aptCL);
            }
        }
        // For -XPrintAptRounds
        int round = 0;
        do {
            round++;
            Context newContext = new Context();
            // creates a new context
            Options newOptions = Options.instance(newContext);
            newOptions.putAll(options);
            // if genSource files, must add destination to source path
            if (genSourceFileNames.size() > 0 && !firstRound) {
                newOptions.put("-sourcepath", augmentedSourcePath);
                needSourcePath = true;
            }
            aggregateGenSourceFileNames.addAll(genSourceFileNames);
            sourceFileNames.addAll(genSourceFileNames);
            genSourceFileNames.clear();
            // "foo" to class path if any class files are generated
            if (genClassFileNames.size() > 0) {
                newOptions.put("-classpath", augmentedClassPath);
                aptCL = augmentedAptCL;
                needClassPath = true;
            }
            aggregateGenClassFileNames.addAll(genClassFileNames);
            classFileNames.addAll(genClassFileNames);
            genClassFileNames.clear();
            options = newOptions;
            if (options.get("-XPrintAptRounds") != null) {
                out.println("apt Round : " + round);
                out.println("filenames: " + sourceFileNames);
                if (classesAsDecls)
                    out.println("classnames: " + classFileNames);
                out.println("options: " + options);
            }
            returnCode = compile(args, newContext);
            firstRound = false;
            // Check for reported errors before continuing
            bark = Bark.instance(newContext);
        } while (((genSourceFileNames.size() != 0) || (classesAsDecls && genClassFileNames.size() != 0)) && bark.nerrors == 0);
    } catch (UsageMessageNeededException umne) {
        help();
        // will cause usage message to be printed
        return EXIT_CMDERR;
    }
    /*
         * Do not compile if a processor has reported an error or if
         * there are no source files to process.  A more sophisticated
         * test would also fail for syntax errors caught by javac.
         */
    if (options.get("-nocompile") == null && options.get("-print") == null && bark.nerrors == 0 && (origFilenames.size() > 0 || aggregateGenSourceFileNames.size() > 0)) {
        /*
             * Need to create new argument string for calling javac:
             * 1. apt specific arguments (e.g. -factory) must be stripped out
             * 2. proper settings for sourcepath and classpath must be used
             * 3. generated class names must be added
             * 4. class file names as declarations must be removed
             */
        int newArgsLength = args.length + (needSourcePath ? 1 : 0) + (needClassPath ? 1 : 0) + aggregateGenSourceFileNames.size();
        // class names from the javac argument list
        argLoop: for (int i = 0; i < args.length; i++) {
            int matchPosition = -1;
            // "-A" by itself is recognized by apt but not javac
            if (args[i] != null && args[i].equals("-A")) {
                newArgsLength--;
                args[i] = null;
                continue argLoop;
            } else {
                optionLoop: for (int j = 0; j < recognizedOptions.length; j++) {
                    if (args[i] != null && recognizedOptions[j].matches(args[i])) {
                        matchPosition = j;
                        break optionLoop;
                    }
                }
                if (matchPosition != -1) {
                    Option op = recognizedOptions[matchPosition];
                    if (op.aptOnly) {
                        newArgsLength--;
                        args[i] = null;
                        if (op.hasArg()) {
                            newArgsLength--;
                            args[i + 1] = null;
                        }
                    } else {
                        if (op.hasArg()) {
                            // skip over next string
                            i++;
                            continue argLoop;
                        }
                        if ((options.get("-XclassesAsDecls") != null) && (matchPosition == (recognizedOptions.length - 1))) {
                            // consideration by javac.
                            if (!args[i].endsWith(".java")) {
                                newArgsLength--;
                                args[i] = null;
                            }
                        }
                    }
                }
            }
        }
        String[] newArgs = new String[newArgsLength];
        int j = 0;
        for (int i = 0; i < args.length; i++) {
            if (args[i] != null)
                newArgs[j++] = args[i];
        }
        if (needClassPath)
            newArgs[j++] = "-XD-classpath=" + augmentedClassPath;
        if (needSourcePath) {
            newArgs[j++] = "-XD-sourcepath=" + augmentedSourcePath;
            for (String s : aggregateGenSourceFileNames) newArgs[j++] = s;
        }
        returnCode = com.sun.tools.javac.Main.compile(newArgs);
    }
    return returnCode;
}
Also used : Bark(com.sun.tools.apt.util.Bark) UsageMessageNeededException(com.sun.tools.apt.comp.UsageMessageNeededException) URLClassLoader(java.net.URLClassLoader) JavaFileManager(javax.tools.JavaFileManager) IOException(java.io.IOException) JavacFileManager(com.sun.tools.javac.file.JavacFileManager) com.sun.tools.javac.util(com.sun.tools.javac.util) URLClassLoader(java.net.URLClassLoader) File(java.io.File)

Aggregations

UsageMessageNeededException (com.sun.tools.apt.comp.UsageMessageNeededException)1 Bark (com.sun.tools.apt.util.Bark)1 JavacFileManager (com.sun.tools.javac.file.JavacFileManager)1 com.sun.tools.javac.util (com.sun.tools.javac.util)1 File (java.io.File)1 IOException (java.io.IOException)1 URLClassLoader (java.net.URLClassLoader)1 JavaFileManager (javax.tools.JavaFileManager)1