blob: adbdd0dbc29872b0154c51d645a3758f1767e493 [file] [log] [blame]
/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed 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.control;
import org.codehaus.groovy.control.io.NullWriter;
import org.codehaus.groovy.control.messages.WarningMessage;
import java.io.File;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* Compilation control flags and coordination stuff.
*
* @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
* @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
* @version $Id$
*/
public class CompilerConfiguration {
public static final CompilerConfiguration DEFAULT = new CompilerConfiguration();
/** Whether to use the JSR parser or not if no property is explicitly stated */
protected static final boolean DEFAULT_JSR_FLAG = true;
private static final String JDK5_CLASSNAME_CHECK = "java.lang.annotation.Annotation";
public static final String POST_JDK5 = "1.5";
public static final String PRE_JDK5 = "1.4";
private static boolean jsrGroovy;
/**
* See WarningMessage for levels
*/
private int warningLevel;
/**
* Encoding for source files
*/
private String sourceEncoding;
/**
* A PrintWriter for communicating with the user
*/
private PrintWriter output;
/**
* Directory into which to write classes
*/
private File targetDirectory;
/**
* Classpath for use during compilation
*/
private LinkedList classpath;
/**
* If true, the compiler should produce action information
*/
private boolean verbose;
/**
* If true, debugging code should be activated
*/
private boolean debug;
/**
* The number of non-fatal errors to allow before bailing
*/
private int tolerance;
/**
* Base class name for scripts (must derive from Script)
*/
private String scriptBaseClass;
/**
* should we use the New JSR Groovy parser or stay with the static one
*/
private boolean useNewGroovy = getDefaultJsrFlag();
private ParserPluginFactory pluginFactory;
/**
* extension used to find a groovy file
*/
private String defaultScriptExtension = ".groovy";
/**
* if set to true recompilation is enabled
*/
private boolean recompileGroovySource;
/**
* sets the minimum of time after a script can be recompiled.
*/
private int minimumRecompilationInterval;
/**
* sets the bytecode version target
*/
private String targetBytecode;
/**
* options for joint compilation (null by default == no joint compilation)
*/
private Map jointCompilationOptions;
/**
* Sets the Flags to defaults.
*/
public CompilerConfiguration() {
//
// Set in safe defaults
setWarningLevel(WarningMessage.LIKELY_ERRORS);
setOutput(null);
setTargetDirectory((File) null);
setClasspath("");
setVerbose(false);
setDebug(false);
setTolerance(10);
setScriptBaseClass(null);
setRecompileGroovySource(false);
setMinimumRecompilationInterval(100);
setTargetBytecode(getVMVersion());
//
// Source file encoding
String encoding = null;
try {
encoding = System.getProperty("file.encoding", "US-ASCII");
} catch (Exception e) {
// IGNORE
}
try {
encoding = System.getProperty("groovy.source.encoding", encoding);
} catch (Exception e) {
// IGNORE
}
setSourceEncoding(encoding);
try {
setOutput(new PrintWriter(System.err));
}
catch (Exception e) {
// IGNORE
}
/*try {
setClasspath(System.getProperty("java.class.path"));
}
catch (Exception e) {
}*/
try {
String target = System.getProperty("groovy.target.directory");
if (target != null) {
setTargetDirectory(target);
}
}
catch (Exception e) {
// IGNORE
}
}
/**
* Sets the Flags to the specified configuration, with defaults
* for those not supplied.
*/
public CompilerConfiguration(Properties configuration) throws ConfigurationException {
this();
String text = null;
int numeric = 0;
//
// Warning level
numeric = getWarningLevel();
try {
text = configuration.getProperty("groovy.warnings", "likely errors");
numeric = Integer.parseInt(text);
}
catch (NumberFormatException e) {
if (text.equals("none")) {
numeric = WarningMessage.NONE;
}
else if (text.startsWith("likely")) {
numeric = WarningMessage.LIKELY_ERRORS;
}
else if (text.startsWith("possible")) {
numeric = WarningMessage.POSSIBLE_ERRORS;
}
else if (text.startsWith("paranoia")) {
numeric = WarningMessage.PARANOIA;
}
else {
throw new ConfigurationException("unrecogized groovy.warnings: " + text);
}
}
setWarningLevel(numeric);
//
// Source file encoding
text = configuration.getProperty("groovy.source.encoding");
if (text != null) {
setSourceEncoding(text);
}
//
// Target directory for classes
text = configuration.getProperty("groovy.target.directory");
if (text != null) {
setTargetDirectory(text);
}
//
// Target bytecode
setTargetBytecode(getVMVersion());
text = configuration.getProperty("groovy.target.bytecode");
if (text != null) {
setTargetBytecode(text);
}
//
// Classpath
text = configuration.getProperty("groovy.classpath");
if (text != null) {
setClasspath(text);
}
//
// Verbosity
text = configuration.getProperty("groovy.output.verbose");
if (text != null && text.equals("true")) {
setVerbose(true);
}
//
// Debugging
text = configuration.getProperty("groovy.output.debug");
if (text != null && text.equals("true")) {
setDebug(true);
}
//
// Tolerance
numeric = 10;
try {
text = configuration.getProperty("groovy.errors.tolerance", "10");
numeric = Integer.parseInt(text);
}
catch (NumberFormatException e) {
throw new ConfigurationException(e);
}
setTolerance(numeric);
//
// Script Base Class
text = configuration.getProperty("groovy.script.base");
setScriptBaseClass(text);
text = configuration.getProperty("groovy.jsr");
if (text != null) {
setUseNewGroovy(text.equalsIgnoreCase("true"));
}
//
// recompilation options
//
text = configuration.getProperty("groovy.recompile");
if (text != null) {
setRecompileGroovySource(text.equalsIgnoreCase("true"));
}
numeric = 100;
try {
text = configuration.getProperty("groovy.recompile.minimumIntervall", ""+numeric);
numeric = Integer.parseInt(text);
}
catch (NumberFormatException e) {
throw new ConfigurationException(e);
}
setMinimumRecompilationInterval(numeric);
}
/**
* Gets the currently configured warning level. See WarningMessage
* for level details.
*/
public int getWarningLevel() {
return this.warningLevel;
}
/**
* Sets the warning level. See WarningMessage for level details.
*/
public void setWarningLevel(int level) {
if (level < WarningMessage.NONE || level > WarningMessage.PARANOIA) {
this.warningLevel = WarningMessage.LIKELY_ERRORS;
}
else {
this.warningLevel = level;
}
}
/**
* Gets the currently configured source file encoding.
*/
public String getSourceEncoding() {
return this.sourceEncoding;
}
/**
* Sets the encoding to be used when reading source files.
*/
public void setSourceEncoding(String encoding) {
if (encoding == null) encoding = "US-ASCII";
this.sourceEncoding = encoding;
}
/**
* Gets the currently configured output writer.
*/
public PrintWriter getOutput() {
return this.output;
}
/**
* Sets the output writer.
*/
public void setOutput(PrintWriter output) {
if (output == null) {
this.output = new PrintWriter(NullWriter.DEFAULT);
}
else {
this.output = output;
}
}
/**
* Gets the target directory for writing classes.
*/
public File getTargetDirectory() {
return this.targetDirectory;
}
/**
* Sets the target directory.
*/
public void setTargetDirectory(String directory) {
if (directory != null && directory.length() > 0) {
this.targetDirectory = new File(directory);
}
else {
this.targetDirectory = null;
}
}
/**
* Sets the target directory.
*/
public void setTargetDirectory(File directory) {
this.targetDirectory = directory;
}
/**
* Gets the classpath.
*/
public List getClasspath() {
return this.classpath;
}
/**
* Sets the classpath.
*/
public void setClasspath(String classpath) {
this.classpath = new LinkedList();
StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
while (tokenizer.hasMoreTokens()) {
this.classpath.add(tokenizer.nextToken());
}
}
/**
* Returns true if verbose operation has been requested.
*/
public boolean getVerbose() {
return this.verbose;
}
/**
* Turns verbose operation on or off.
*/
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
/**
* Returns true if debugging operation has been requested.
*/
public boolean getDebug() {
return this.debug;
}
/**
* Turns debugging operation on or off.
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
/**
* Returns the requested error tolerance.
*/
public int getTolerance() {
return this.tolerance;
}
/**
* Sets the error tolerance, which is the number of
* non-fatal errors (per unit) that should be tolerated before
* compilation is aborted.
*/
public void setTolerance(int tolerance) {
this.tolerance = tolerance;
}
/**
* Gets the name of the base class for scripts. It must be a subclass
* of Script.
*/
public String getScriptBaseClass() {
return this.scriptBaseClass;
}
/**
* Sets the name of the base class for scripts. It must be a subclass
* of Script.
*/
public void setScriptBaseClass(String scriptBaseClass) {
this.scriptBaseClass = scriptBaseClass;
}
/**
* Returns true if the new groovy (JSR) parser is enabled
*/
public boolean isUseNewGroovy() {
return useNewGroovy;
}
public void setUseNewGroovy(boolean useNewGroovy) {
this.useNewGroovy = useNewGroovy;
}
public ParserPluginFactory getPluginFactory() {
if (pluginFactory == null) {
pluginFactory = ParserPluginFactory.newInstance(isUseNewGroovy());
}
return pluginFactory;
}
public void setPluginFactory(ParserPluginFactory pluginFactory) {
this.pluginFactory = pluginFactory;
}
/**
* Returns true if we are the JSR compatible Groovy language
*/
public static boolean isJsrGroovy() {
return jsrGroovy;
}
/**
* Should only be called by the JSR parser
*/
public static void setJsrGroovy(boolean value) {
jsrGroovy = value;
}
protected static boolean getDefaultJsrFlag() {
// TODO a temporary hack while we have 2 parsers
String property = null;
try {
property = System.getProperty("groovy.jsr");
}
catch (Throwable e) {
// ignore security warnings
}
if (property != null) {
return "true".equalsIgnoreCase(property);
}
return DEFAULT_JSR_FLAG;
}
public String getDefaultScriptExtension() {
return defaultScriptExtension;
}
public void setDefaultScriptExtension(String defaultScriptExtension) {
this.defaultScriptExtension = defaultScriptExtension;
}
public void setRecompileGroovySource(boolean recompile) {
recompileGroovySource = recompile;
}
public boolean getRecompileGroovySource(){
return recompileGroovySource;
}
public void setMinimumRecompilationInterval(int time) {
minimumRecompilationInterval = Math.max(0,time);
}
public int getMinimumRecompilationInterval() {
return minimumRecompilationInterval;
}
/**
* Allow setting the bytecode compatibility. The parameter can take
* one of the values <tt>1.5</tt> or <tt>1.4</tt>. If wrong parameter
* then the value will default to VM determined version.
*
* @param version the bytecode compatibility mode
*/
public void setTargetBytecode(String version) {
if(PRE_JDK5.equals(version) || POST_JDK5.equals(version)) {
this.targetBytecode = version;
}
}
/**
* Retrieves the compiler bytecode compatibility mode.
*
* @return bytecode compatibity mode. Can be either <tt>1.5</tt> or <tt>1.4</tt>.
*/
public String getTargetBytecode() {
return this.targetBytecode;
}
private static String getVMVersion() {
try {
Class.forName(JDK5_CLASSNAME_CHECK);
return POST_JDK5;
}
catch(Exception ex) {
// IGNORE
}
return PRE_JDK5;
}
public Map getJointCompilationOptions() {
return jointCompilationOptions;
}
public void setJointCompilationOptions(Map options) {
jointCompilationOptions = options;
}
}