All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.groovy.tools.FileSystemCompiler Maven / Gradle / Ivy

The newest version!
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.codehaus.groovy.tools;

import groovy.lang.Binding;
import groovy.lang.GroovyResourceLoader;
import groovy.lang.GroovyShell;
import groovy.lang.GroovySystem;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GroovyInternalPosixParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.ConfigurationException;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods;
import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Command-line compiler (aka. groovyc).
 */
public class FileSystemCompiler {
    private final CompilationUnit unit;

    public FileSystemCompiler(CompilerConfiguration configuration) throws ConfigurationException {
        this(configuration, null);
    }

    public FileSystemCompiler(CompilerConfiguration configuration, CompilationUnit cu) throws ConfigurationException {
        if (cu != null) {
            unit = cu;
        } else if (configuration.getJointCompilationOptions() != null) {
            unit = new JavaAwareCompilationUnit(configuration);
        } else {
            unit = new CompilationUnit(configuration);
        }
    }

    public void compile(String[] paths) throws Exception {
        unit.addSources(paths);
        unit.compile();
    }

    public void compile(File[] files) throws Exception {
        unit.addSources(files);
        unit.compile();
    }

    public static void displayHelp(final Options options) {
        final HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp(80, "groovyc [options] ", "options:", options, "");
    }

    public static void displayVersion() {
        String version = GroovySystem.getVersion();
        System.err.println("Groovy compiler version " + version);
        System.err.println("Copyright 2003-2020 The Apache Software Foundation. https://groovy-lang.org/");
        System.err.println("");
    }

    public static int checkFiles(String[] filenames) {
        int errors = 0;

        for (String filename : filenames) {
            File file = new File(filename);
            if (!file.exists()) {
                System.err.println("error: file not found: " + file);
                ++errors;
            } else if (!file.canRead()) {
                System.err.println("error: file not readable: " + file);
                ++errors;
            }
        }

        return errors;
    }

    public static boolean validateFiles(String[] filenames) {
        return checkFiles(filenames) == 0;
    }

    private static boolean displayStackTraceOnError = false;

    /**
     * Same as main(args) except that exceptions are thrown out instead of causing
     * the VM to exit.
     */
    public static void commandLineCompile(String[] args) throws Exception {
        commandLineCompile(args, true);
    }

    /**
     * Same as main(args) except that exceptions are thrown out instead of causing
     * the VM to exit and the lookup for .groovy files can be controlled
     */
    public static void commandLineCompile(String[] args, boolean lookupUnnamedFiles) throws Exception {
        Options options = createCompilationOptions();

        CommandLineParser cliParser = new GroovyInternalPosixParser();

        CommandLine cli;
        cli = cliParser.parse(options, args);

        if (cli.hasOption('h')) {
            displayHelp(options);
            return;
        }

        if (cli.hasOption('v')) {
            displayVersion();
            return;
        }

        displayStackTraceOnError = cli.hasOption('e');

        CompilerConfiguration configuration = generateCompilerConfigurationFromOptions(cli);

        //
        // Load the file name list
        String[] filenames = generateFileNamesFromOptions(cli);
        boolean fileNameErrors = filenames == null;
        if (!fileNameErrors && (filenames.length == 0)) {
            displayHelp(options);
            return;
        }

        fileNameErrors = fileNameErrors && !validateFiles(filenames);

        if (!fileNameErrors) {
            doCompilation(configuration, null, filenames, lookupUnnamedFiles);
        }
    }

    /**
     * Primary entry point for compiling from the command line
     * (using the groovyc script).
     * 

* If calling inside a process and you don't want the JVM to exit on an * error call commandLineCompile(String[]), which this method simply wraps * * @param args command line arguments */ public static void main(String[] args) { commandLineCompileWithErrorHandling(args, true); } /** * Primary entry point for compiling from the command line * (using the groovyc script). *

* If calling inside a process and you don't want the JVM to exit on an * error call commandLineCompile(String[]), which this method simply wraps * * @param args command line arguments * @param lookupUnnamedFiles do a lookup for .groovy files not part of * the given list of files to compile */ public static void commandLineCompileWithErrorHandling(String[] args, boolean lookupUnnamedFiles) { try { commandLineCompile(args, lookupUnnamedFiles); } catch (Throwable e) { new ErrorReporter(e, displayStackTraceOnError).write(System.err); System.exit(1); } } public static void doCompilation(CompilerConfiguration configuration, CompilationUnit unit, String[] filenames) throws Exception { doCompilation(configuration, unit, filenames, true); } public static void doCompilation(CompilerConfiguration configuration, CompilationUnit unit, String[] filenames, boolean lookupUnnamedFiles) throws Exception { File tmpDir = null; // if there are any joint compilation options set stubDir if not set try { if ((configuration.getJointCompilationOptions() != null) && !configuration.getJointCompilationOptions().containsKey("stubDir")) { tmpDir = DefaultGroovyStaticMethods.createTempDir(null, "groovy-generated-", "-java-source"); configuration.getJointCompilationOptions().put("stubDir", tmpDir); } FileSystemCompiler compiler = new FileSystemCompiler(configuration, unit); if (lookupUnnamedFiles) { for (String filename : filenames) { File file = new File(filename); if (file.isFile()) { URL url = file.getAbsoluteFile().getParentFile().toURI().toURL(); compiler.unit.getClassLoader().addURL(url); } } } else { compiler.unit.getClassLoader().setResourceLoader(new GroovyResourceLoader() { public URL loadGroovySource(String filename) throws MalformedURLException { return null; } }); } compiler.compile(filenames); } finally { try { if (tmpDir != null) deleteRecursive(tmpDir); } catch (Throwable t) { System.err.println("error: could not delete temp files - " + tmpDir.getPath()); } } } public static String[] generateFileNamesFromOptions(CommandLine cli) { String[] filenames = cli.getArgs(); List fileList = new ArrayList(filenames.length); boolean errors = false; for (String filename : filenames) { if (filename.startsWith("@")) { String fn = filename.substring(1); BufferedReader br = null; try { br = new BufferedReader(new FileReader(fn)); for (String file; (file = br.readLine()) != null; ) { fileList.add(file); } } catch (IOException ioe) { System.err.println("error: file not readable: " + fn); errors = true; } finally { if (null != br) { try { br.close(); } catch (IOException e) { System.err.println("error: failed to close buffered reader: " + fn); errors = true; } } } } else { fileList.add(filename); } } if (errors) { return null; } else { return fileList.toArray(new String[fileList.size()]); } } public static CompilerConfiguration generateCompilerConfigurationFromOptions(CommandLine cli) throws IOException { // // Setup the configuration data CompilerConfiguration configuration = new CompilerConfiguration(); if (cli.hasOption("classpath")) { configuration.setClasspath(cli.getOptionValue("classpath")); } if (cli.hasOption('d')) { configuration.setTargetDirectory(cli.getOptionValue('d')); } if (cli.hasOption("encoding")) { configuration.setSourceEncoding(cli.getOptionValue("encoding")); } if (cli.hasOption("basescript")) { configuration.setScriptBaseClass(cli.getOptionValue("basescript")); } // joint compilation parameters if (cli.hasOption('j')) { Map compilerOptions = new HashMap(); String[] opts = cli.getOptionValues("J"); compilerOptions.put("namedValues", opts); opts = cli.getOptionValues("F"); compilerOptions.put("flags", opts); configuration.setJointCompilationOptions(compilerOptions); } if (cli.hasOption("indy")) { configuration.getOptimizationOptions().put("int", false); configuration.getOptimizationOptions().put("indy", true); } if (cli.hasOption("configscript")) { String path = cli.getOptionValue("configscript"); File groovyConfigurator = new File(path); Binding binding = new Binding(); binding.setVariable("configuration", configuration); CompilerConfiguration configuratorConfig = new CompilerConfiguration(); ImportCustomizer customizer = new ImportCustomizer(); customizer.addStaticStars("org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder"); configuratorConfig.addCompilationCustomizers(customizer); GroovyShell shell = new GroovyShell(binding, configuratorConfig); shell.evaluate(groovyConfigurator); } return configuration; } @SuppressWarnings({"AccessStaticViaInstance"}) public static Options createCompilationOptions() { // // Parse the command line Options options = new Options(); options.addOption(OptionBuilder.hasArg().withArgName("path").withDescription("Specify where to find the class files - must be first argument").create("classpath")); options.addOption(OptionBuilder.withLongOpt("classpath").hasArg().withArgName("path").withDescription("Aliases for '-classpath'").create("cp")); options.addOption(OptionBuilder.withLongOpt("sourcepath").hasArg().withArgName("path").withDescription("Specify where to find the source files").create()); options.addOption(OptionBuilder.withLongOpt("temp").hasArg().withArgName("temp").withDescription("Specify temporary directory").create()); options.addOption(OptionBuilder.withLongOpt("encoding").hasArg().withArgName("encoding").withDescription("Specify the encoding of the user class files").create()); options.addOption(OptionBuilder.hasArg().withDescription("Specify where to place generated class files").create('d')); // options.addOption(OptionBuilder.withLongOpt("strict").withDescription("Turn on strict type safety.").create('s')); options.addOption(OptionBuilder.withLongOpt("help").withDescription("Print a synopsis of standard options").create('h')); options.addOption(OptionBuilder.withLongOpt("version").withDescription("Print the version").create('v')); options.addOption(OptionBuilder.withLongOpt("exception").withDescription("Print stack trace on error").create('e')); options.addOption(OptionBuilder.withLongOpt("jointCompilation").withDescription("Attach javac compiler to compile .java files").create('j')); options.addOption(OptionBuilder.withLongOpt("basescript").hasArg().withArgName("class").withDescription("Base class name for scripts (must derive from Script)").create('b')); options.addOption( OptionBuilder.withArgName("property=value") .withValueSeparator() .hasArgs(2) .withDescription("name-value pairs to pass to javac") .create("J")); options.addOption( OptionBuilder.withArgName("flag") .hasArg() .withDescription("passed to javac for joint compilation") .create("F")); options.addOption(OptionBuilder.withLongOpt("indy").withDescription("enables compilation using invokedynamic").create()); options.addOption(OptionBuilder.withLongOpt("configscript").hasArg().withDescription("A script for tweaking the configuration options").create()); return options; } /** * Creates a temporary directory in the default temporary directory (as specified by the system * property java.io.tmpdir. * * @deprecated Use {@link DefaultGroovyStaticMethods#createTempDir(java.io.File, String, String)} instead. */ @Deprecated public static File createTempDir() throws IOException { return DefaultGroovyStaticMethods.createTempDir(null); } public static void deleteRecursive(File file) { if (!file.exists()) { return; } if (file.isFile()) { file.delete(); } else if (file.isDirectory()) { File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { deleteRecursive(files[i]); } file.delete(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy