org.codehaus.groovy.control.CompilerConfiguration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of groovy Show documentation
Show all versions of groovy Show documentation
Groovy: A powerful multi-faceted language for the JVM
/*
* 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.control;
import org.apache.groovy.util.Maps;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.control.customizers.CompilationCustomizer;
import org.codehaus.groovy.control.io.NullWriter;
import org.codehaus.groovy.control.messages.WarningMessage;
import org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import static org.apache.groovy.util.SystemUtil.getBooleanSafe;
import static org.apache.groovy.util.SystemUtil.getIntegerSafe;
import static org.apache.groovy.util.SystemUtil.getSystemPropertySafe;
import static org.codehaus.groovy.runtime.StringGroovyMethods.isAtLeast;
/**
* Compilation control flags and coordination stuff.
*/
public class CompilerConfiguration {
/** Optimization Option for enabling invokedynamic
compilation. */
public static final String INVOKEDYNAMIC = "indy";
/** Optimization Option for enabling attaching groovydoc as AST node metadata. */
public static final String GROOVYDOC = "groovydoc";
/** Optimization Option for enabling attaching {@link groovy.lang.Groovydoc} annotation. */
public static final String RUNTIME_GROOVYDOC = "runtimeGroovydoc";
/** Optimization Option for enabling parallel parsing. */
public static final String PARALLEL_PARSE = "parallelParse";
/** Joint Compilation Option for enabling generating stubs in memory. */
public static final String MEM_STUB = "memStub";
/** This ("1.4"
) is the value for targetBytecode to compile for a JDK 1.4. */
@Deprecated public static final String JDK4 = "1.4";
/** This ("1.5"
) is the value for targetBytecode to compile for a JDK 1.5. */
@Deprecated public static final String JDK5 = "1.5";
/** This ("1.6"
) is the value for targetBytecode to compile for a JDK 1.6. */
@Deprecated public static final String JDK6 = "1.6";
/** This ("1.7"
) is the value for targetBytecode to compile for a JDK 1.7. */
@Deprecated public static final String JDK7 = "1.7";
/** This ("1.8"
) is the value for targetBytecode to compile for a JDK 1.8. */
@Deprecated public static final String JDK8 = "1.8";
/** This ("9"
) is the value for targetBytecode to compile for a JDK 9. */
@Deprecated public static final String JDK9 = "9";
/** This ("10"
) is the value for targetBytecode to compile for a JDK 10. */
@Deprecated public static final String JDK10 = "10";
/** This ("11"
) is the value for targetBytecode to compile for a JDK 11. */
public static final String JDK11 = "11";
/** This ("12"
) is the value for targetBytecode to compile for a JDK 12. */
public static final String JDK12 = "12";
/** This ("13"
) is the value for targetBytecode to compile for a JDK 13. */
public static final String JDK13 = "13";
/** This ("14"
) is the value for targetBytecode to compile for a JDK 14. */
public static final String JDK14 = "14";
/** This ("15"
) is the value for targetBytecode to compile for a JDK 15. */
public static final String JDK15 = "15";
/** This ("16"
) is the value for targetBytecode to compile for a JDK 16. */
public static final String JDK16 = "16";
/** This ("17"
) is the value for targetBytecode to compile for a JDK 17. */
public static final String JDK17 = "17";
/** This ("18"
) is the value for targetBytecode to compile for a JDK 18. */
public static final String JDK18 = "18";
/** This ("19"
) is the value for targetBytecode to compile for a JDK 19. */
public static final String JDK19 = "19";
/** This ("20"
) is the value for targetBytecode to compile for a JDK 20. */
public static final String JDK20 = "20";
/** This ("21"
) is the value for targetBytecode to compile for a JDK 21. */
public static final String JDK21 = "21";
/** This ("22"
) is the value for targetBytecode to compile for a JDK 22. */
public static final String JDK22 = "22";
/** This ("23"
) is the value for targetBytecode to compile for a JDK 23. */
public static final String JDK23 = "23";
/**
* JDK version to bytecode version mapping.
*/
public static final Map JDK_TO_BYTECODE_VERSION_MAP = Maps.of(
JDK11, Opcodes.V11,
JDK12, Opcodes.V12,
JDK13, Opcodes.V13,
JDK14, Opcodes.V14,
JDK15, Opcodes.V15,
JDK16, Opcodes.V16,
JDK17, Opcodes.V17,
JDK18, Opcodes.V18,
JDK19, Opcodes.V19,
JDK20, Opcodes.V20,
JDK21, Opcodes.V21,
JDK22, Opcodes.V22,
JDK23, Opcodes.V23
);
public static final String DEFAULT_TARGET_BYTECODE = defaultTargetBytecode();
/**
* The valid targetBytecode values.
*/
public static final String[] ALLOWED_JDKS = JDK_TO_BYTECODE_VERSION_MAP.keySet().toArray(new String[JDK_TO_BYTECODE_VERSION_MAP.size()]);
/**
* The ASM API version used when loading/parsing classes and generating proxy adapter classes.
*/
public static final int ASM_API_VERSION = Opcodes.ASM9;
/**
* The default source encoding.
*/
public static final String DEFAULT_SOURCE_ENCODING = "UTF-8";
/**
* A convenience for getting a default configuration. Do not modify it!
* See {@link #CompilerConfiguration(Properties)} for an example on how to
* make a suitable copy to modify. But if you're really starting from a
* default context, then you probably just want new CompilerConfiguration()
.
*/
public static final CompilerConfiguration DEFAULT = new CompilerConfiguration() {
@Override
public List getClasspath() {
return Collections.unmodifiableList(super.getClasspath());
}
@Override
public List getCompilationCustomizers() {
return Collections.unmodifiableList(super.getCompilationCustomizers());
}
@Override
public Set getDisabledGlobalASTTransformations() {
return Optional.ofNullable(super.getDisabledGlobalASTTransformations()).map(Collections::unmodifiableSet).orElse(null);
}
@Override
public Map getJointCompilationOptions() {
return Optional.ofNullable(super.getJointCompilationOptions()).map(Collections::unmodifiableMap).orElse(null);
}
@Override
public Map getOptimizationOptions() {
return Collections.unmodifiableMap(super.getOptimizationOptions());
}
@Override
public Set getScriptExtensions() {
return Collections.unmodifiableSet(super.getScriptExtensions());
}
@Override
public void setBytecodePostprocessor(final BytecodeProcessor bytecodePostprocessor) {
throw new UnsupportedOperationException();
}
@Override
public void setClasspath(final String classpath) {
throw new UnsupportedOperationException();
}
@Override
public void setClasspathList(final List parts) {
throw new UnsupportedOperationException();
}
@Override
public CompilerConfiguration addCompilationCustomizers(final CompilationCustomizer... customizers) {
throw new UnsupportedOperationException();
}
@Override
public void setDebug(final boolean debug) {
throw new UnsupportedOperationException();
}
@Override
public void setDefaultScriptExtension(final String defaultScriptExtension) {
throw new UnsupportedOperationException();
}
@Override
public void setDisabledGlobalASTTransformations(final Set disabledGlobalASTTransformations) {
throw new UnsupportedOperationException();
}
@Override
public void setJointCompilationOptions(final Map options) {
throw new UnsupportedOperationException();
}
@Override
public void setMinimumRecompilationInterval(final int time) {
throw new UnsupportedOperationException();
}
@Override
public void setOptimizationOptions(final Map options) {
throw new UnsupportedOperationException();
}
@Override
@Deprecated
public void setOutput(final PrintWriter output) {
throw new UnsupportedOperationException();
}
@Override
public void setParameters(final boolean parameters) {
throw new UnsupportedOperationException();
}
@Override
public void setPluginFactory(final ParserPluginFactory pluginFactory) {
throw new UnsupportedOperationException();
}
@Override
public void setPreviewFeatures(final boolean previewFeatures) {
throw new UnsupportedOperationException();
}
@Override
public void setRecompileGroovySource(final boolean recompile) {
throw new UnsupportedOperationException();
}
@Override
public void setScriptBaseClass(final String scriptBaseClass) {
throw new UnsupportedOperationException();
}
@Override
public void setScriptExtensions(final Set scriptExtensions) {
throw new UnsupportedOperationException();
}
@Override
public void setSourceEncoding(final String encoding) {
throw new UnsupportedOperationException();
}
@Override
public void setTargetBytecode(final String version) {
throw new UnsupportedOperationException();
}
@Override
public void setTargetDirectory(final File directory) {
throw new UnsupportedOperationException();
}
@Override
public void setTargetDirectory(final String directory) {
throw new UnsupportedOperationException();
}
@Override
public void setTolerance(final int tolerance) {
throw new UnsupportedOperationException();
}
@Override
public void setVerbose(final boolean verbose) {
throw new UnsupportedOperationException();
}
@Override
public void setWarningLevel(final int level) {
throw new UnsupportedOperationException();
}
@Override
public void setLogClassgen(boolean logClassgen) {
throw new UnsupportedOperationException();
}
@Override
public void setLogClassgenStackTraceMaxDepth(int logClassgenStackTraceMaxDepth) {
throw new UnsupportedOperationException();
}
};
/**
* See {@link WarningMessage} for levels.
*/
private int warningLevel;
/**
* Encoding for source files.
*/
private String sourceEncoding;
/**
* The PrintWriter
does nothing.
*/
private PrintWriter output;
/**
* Directory into which to write classes.
*/
private File targetDirectory;
/**
* Classpath for use during compilation.
*/
private List classpath;
/**
* If true, the compiler should produce action information.
*/
private boolean verbose;
/**
* If true, debugging code should be activated.
*/
private boolean debug;
/**
* If true, generates metadata for reflection on method parameters.
*/
private boolean parameters;
/**
* 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;
private ParserPluginFactory pluginFactory;
/**
* Extension used to find a groovy file.
*/
private String defaultScriptExtension;
/**
* Extensions used to find a groovy files.
*/
private Set scriptExtensions = new LinkedHashSet<>();
/**
* If set to true recompilation is enabled.
*/
private boolean recompileGroovySource;
/**
* The minimum of time after a script can be recompiled.
*/
private int minimumRecompilationInterval;
/**
* The bytecode version target.
*/
private String targetBytecode;
/**
* Whether the bytecode version has preview features enabled (JEP 12).
*/
private boolean previewFeatures;
/**
* Whether logging class generation is enabled
*/
private boolean logClassgen;
/**
* sets logging class generation stack trace max depth
*/
private int logClassgenStackTraceMaxDepth;
/**
* Options for joint compilation (null by default == no joint compilation).
*/
private Map jointCompilationOptions;
/**
* Options for optimizations (empty map by default).
*/
private Map optimizationOptions;
private final List compilationCustomizers = new LinkedList<>();
/**
* Global AST transformations which should not be loaded even if defined in
* META-INF/services/org.codehaus.groovy.transform.ASTTransformation
* files. By default, none are disabled.
*/
private Set disabledGlobalASTTransformations;
private BytecodeProcessor bytecodePostprocessor;
/**
* Sets the compiler flags/settings to default values.
*
* The following system properties are referenced when setting the configuration:
*
*
* Property Key Related Property Getter
* groovy.source.encoding
(defaulting to file.encoding
){@link #getSourceEncoding}
* groovy.target.bytecode
{@link #getTargetBytecode}
* groovy.target.directory
{@link #getTargetDirectory}
* groovy.parameters
{@link #getParameters()}
* groovy.preview.features
{@link #isPreviewFeatures}
* groovy.default.scriptExtension
{@link #getDefaultScriptExtension}
*
*
*
* The following system properties are referenced when setting the configuration optimization options:
*
*
* Property Key Related Property Getter
* groovy.target.indy
{@link #getOptimizationOptions}
* groovy.parallel.parse
{@link #getOptimizationOptions}
* groovy.attach.groovydoc
{@link #getOptimizationOptions}
* groovy.attach.runtime.groovydoc
{@link #getOptimizationOptions}
*
*
*/
public CompilerConfiguration() {
classpath = new LinkedList<>();
tolerance = 10;
minimumRecompilationInterval = 100;
warningLevel = WarningMessage.LIKELY_ERRORS;
parameters = getBooleanSafe("groovy.parameters");
previewFeatures = getBooleanSafe("groovy.preview.features");
logClassgen = getBooleanSafe("groovy.log.classgen");
logClassgenStackTraceMaxDepth = getIntegerSafe("groovy.log.classgen.stacktrace.max.depth", 0);
sourceEncoding = getSystemPropertySafe("groovy.source.encoding",
getSystemPropertySafe("file.encoding", DEFAULT_SOURCE_ENCODING));
setTargetDirectorySafe(getSystemPropertySafe("groovy.target.directory"));
setTargetBytecodeIfValid(getSystemPropertySafe("groovy.target.bytecode", DEFAULT_TARGET_BYTECODE));
defaultScriptExtension = getSystemPropertySafe("groovy.default.scriptExtension", ".groovy");
optimizationOptions = new HashMap<>(4);
handleOptimizationOption(INVOKEDYNAMIC, getSystemPropertySafe("groovy.target.indy", "true"));
handleOptimizationOption(GROOVYDOC, getSystemPropertySafe("groovy.attach.groovydoc"));
handleOptimizationOption(RUNTIME_GROOVYDOC, getSystemPropertySafe("groovy.attach.runtime.groovydoc"));
handleOptimizationOption(PARALLEL_PARSE, getSystemPropertySafe("groovy.parallel.parse", "true"));
if (getBooleanSafe("groovy.mem.stub")) {
jointCompilationOptions = new HashMap<>(2);
jointCompilationOptions.put(MEM_STUB, Boolean.TRUE);
}
}
private void handleOptimizationOption(String key, String val) {
if (val != null) optimizationOptions.put(key, Boolean.valueOf(val));
}
/**
* Copy constructor. Use this if you have a mostly correct configuration
* for your compilation but you want to make a some changes programmatically.
* An important reason to prefer this approach is that your code will most
* likely be forward compatible with future changes to this configuration API.
*
* An example of this copy constructor at work:
*
* // In all likelihood there is already a configuration in your code's context
* // for you to copy, but for the sake of this example we'll use the global default.
* CompilerConfiguration myConfiguration = new CompilerConfiguration(CompilerConfiguration.DEFAULT);
* myConfiguration.setDebug(true);
*
*
* @param configuration The configuration to copy.
*/
public CompilerConfiguration(final CompilerConfiguration configuration) {
setWarningLevel(configuration.getWarningLevel());
setTargetDirectory(configuration.getTargetDirectory());
setClasspathList(configuration.getClasspath());
setVerbose(configuration.getVerbose());
setDebug(configuration.getDebug());
setParameters(configuration.getParameters());
setTolerance(configuration.getTolerance());
setScriptBaseClass(configuration.getScriptBaseClass());
setRecompileGroovySource(configuration.getRecompileGroovySource());
setMinimumRecompilationInterval(configuration.getMinimumRecompilationInterval());
setTargetBytecode(configuration.getTargetBytecode());
setPreviewFeatures(configuration.isPreviewFeatures());
setLogClassgen(configuration.isLogClassgen());
setLogClassgenStackTraceMaxDepth(configuration.getLogClassgenStackTraceMaxDepth());
setDefaultScriptExtension(configuration.getDefaultScriptExtension());
setSourceEncoding(configuration.getSourceEncoding());
setPluginFactory(configuration.getPluginFactory());
setDisabledGlobalASTTransformations(configuration.getDisabledGlobalASTTransformations());
setScriptExtensions(new LinkedHashSet<>(configuration.getScriptExtensions()));
setOptimizationOptions(new HashMap<>(configuration.getOptimizationOptions()));
setBytecodePostprocessor(configuration.getBytecodePostprocessor());
Map jointCompilationOptions = configuration.getJointCompilationOptions();
setJointCompilationOptions(null != jointCompilationOptions ? new HashMap<>(jointCompilationOptions) : jointCompilationOptions);
// TODO GROOVY-9585: add line below once gradle build issues fixed
// compilationCustomizers.addAll(configuration.getCompilationCustomizers());
}
/**
* Sets the configuration flags/settings according to values from the supplied {@code Properties} instance
* or if not found, supplying a default value.
*
* Note that unlike {@link #CompilerConfiguration()}, the "defaults" here do not in general
* include checking the settings in {@link System#getProperties()}.
* If you want to set a few flags but keep Groovy's default
* configuration behavior then be sure to make your settings in
* a {@code Properties} object that is backed by System.getProperties()
(which
* is done using this constructor). That might be done like this:
*
* Properties myProperties = new Properties(System.getProperties());
* myProperties.setProperty("groovy.output.debug", "true");
* myConfiguration = new CompilerConfiguration(myProperties);
*
* And you also have to contend with a possible {@code SecurityException} when
* getting the system properties (See {@link System#getProperties()}).
* A safer approach would be to copy a default
* {@code CompilerConfiguration} and make your changes there using the setter:
*
* // In all likelihood there is already a configuration for you to copy,
* // but for the sake of this example we'll use the global default.
* CompilerConfiguration myConfiguration = new CompilerConfiguration(CompilerConfiguration.DEFAULT);
* myConfiguration.setDebug(true);
*
*
* The following properties are referenced when setting the configuration:
*
*
*
* Property Key Related Property Getter
* groovy.warnings
{@link #getWarningLevel}
* groovy.source.encoding
(defaulting to file.encoding
){@link #getSourceEncoding}
* groovy.target.directory
{@link #getTargetDirectory}
* groovy.target.bytecode
{@link #getTargetBytecode}
* groovy.parameters
{@link #getParameters()}
* groovy.preview.features
{@link #isPreviewFeatures}
* groovy.classpath
{@link #getClasspath}
* groovy.output.verbose
{@link #getVerbose}
* groovy.output.debug
{@link #getDebug}
* groovy.errors.tolerance
{@link #getTolerance}
* groovy.default.scriptExtension
{@link #getDefaultScriptExtension}
* groovy.script.base
{@link #getScriptBaseClass}
* groovy.recompile
{@link #getRecompileGroovySource}
* groovy.recompile.minimumInterval
{@link #getMinimumRecompilationInterval}
* groovy.disabled.global.ast.transformations
{@link #getDisabledGlobalASTTransformations}
*
*
*
* @param configuration The properties to get flag values from.
*/
public CompilerConfiguration(final Properties configuration) throws ConfigurationException {
this();
configure(configuration);
}
/**
* Checks if the specified bytecode version string represents a JDK 1.5+ compatible
* bytecode version.
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 1.5+
*/
@Deprecated
public static boolean isPostJDK5(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK5);
}
/**
* Checks if the specified bytecode version string represents a JDK 1.7+ compatible
* bytecode version.
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 1.7+
*/
@Deprecated
public static boolean isPostJDK7(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK7);
}
/**
* Checks if the specified bytecode version string represents a JDK 1.8+ compatible
* bytecode version.
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 1.8+
*/
@Deprecated
public static boolean isPostJDK8(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK8);
}
/**
* Checks if the specified bytecode version string represents a JDK 9+ compatible
* bytecode version.
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 9+
*/
@Deprecated
public static boolean isPostJDK9(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK9);
}
/**
* Checks if the specified bytecode version string represents a JDK 10+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 10+
*/
@Deprecated
public static boolean isPostJDK10(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK10);
}
/**
* Checks if the specified bytecode version string represents a JDK 11+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 11+
*/
public static boolean isPostJDK11(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK11);
}
/**
* Checks if the specified bytecode version string represents a JDK 12+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 12+
*/
public static boolean isPostJDK12(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK12);
}
/**
* Checks if the specified bytecode version string represents a JDK 13+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 13+
*/
public static boolean isPostJDK13(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK13);
}
/**
* Checks if the specified bytecode version string represents a JDK 14+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 14+
*/
public static boolean isPostJDK14(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK14);
}
/**
* Checks if the specified bytecode version string represents a JDK 15+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 15+
*/
public static boolean isPostJDK15(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK15);
}
/**
* Checks if the specified bytecode version string represents a JDK 16+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 16+
*/
public static boolean isPostJDK16(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK16);
}
/**
* Checks if the specified bytecode version string represents a JDK 17+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 17+
*/
public static boolean isPostJDK17(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK17);
}
/**
* Checks if the specified bytecode version string represents a JDK 18+ compatible bytecode version.
*
* @param bytecodeVersion The parameter can take one of the values in {@link #ALLOWED_JDKS}.
* @return true if the bytecode version is JDK 18+
*/
public static boolean isPostJDK18(final String bytecodeVersion) {
return isAtLeast(bytecodeVersion, JDK18);
}
/**
* Method to configure a CompilerConfiguration by using Properties.
* For a list of available properties look at {@link #CompilerConfiguration(Properties)}.
* @param configuration The properties to get flag values from.
*/
public void configure(final Properties configuration) throws ConfigurationException {
String text;
int numeric;
numeric = getWarningLevel();
text = configuration.getProperty("groovy.warnings", "likely errors");
try {
numeric = Integer.parseInt(text);
} catch (NumberFormatException e) {
text = text.toLowerCase();
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("unrecognized groovy.warnings: " + text);
}
}
setWarningLevel(numeric);
text = configuration.getProperty("groovy.source.encoding");
if (text == null) {
text = configuration.getProperty("file.encoding", DEFAULT_SOURCE_ENCODING);
}
setSourceEncoding(text);
text = configuration.getProperty("groovy.target.directory");
if (text != null) setTargetDirectory(text);
text = configuration.getProperty("groovy.target.bytecode");
if (text != null) setTargetBytecode(text);
text = configuration.getProperty("groovy.parameters");
if (text != null) setParameters(text.equalsIgnoreCase("true"));
text = configuration.getProperty("groovy.preview.features");
if (text != null) setPreviewFeatures(text.equalsIgnoreCase("true"));
text = configuration.getProperty("groovy.log.classgen");
if (text != null) setLogClassgen(text.equalsIgnoreCase("true"));
text = configuration.getProperty("groovy.log.classgen.stacktrace.max.depth");
if (text != null) {
int logClassgenStackTraceMaxDepth = 0;
try {
logClassgenStackTraceMaxDepth = Integer.parseInt(text);
} catch (Exception ignored) {
}
setLogClassgenStackTraceMaxDepth(Math.max(logClassgenStackTraceMaxDepth, 0));
}
text = configuration.getProperty("groovy.classpath");
if (text != null) setClasspath(text);
text = configuration.getProperty("groovy.output.verbose");
if (text != null) setVerbose(text.equalsIgnoreCase("true"));
text = configuration.getProperty("groovy.output.debug");
if (text != null) setDebug(text.equalsIgnoreCase("true"));
numeric = 10;
text = configuration.getProperty("groovy.errors.tolerance", "10");
try {
numeric = Integer.parseInt(text);
} catch (NumberFormatException e) {
throw new ConfigurationException(e);
}
setTolerance(numeric);
text = configuration.getProperty("groovy.default.scriptExtension");
if (text != null) setDefaultScriptExtension(text);
text = configuration.getProperty("groovy.script.base");
if (text != null) setScriptBaseClass(text);
text = configuration.getProperty("groovy.recompile");
if (text != null) setRecompileGroovySource(text.equalsIgnoreCase("true"));
numeric = 100;
text = configuration.getProperty("groovy.recompile.minimumIntervall"); // legacy misspelling
try {
if (text == null) text = configuration.getProperty("groovy.recompile.minimumInterval");
if (text != null) {
numeric = Integer.parseInt(text);
}
} catch (NumberFormatException e) {
throw new ConfigurationException(e);
}
setMinimumRecompilationInterval(numeric);
text = configuration.getProperty("groovy.disabled.global.ast.transformations");
if (text != null) {
String[] classNames = text.split(",\\s*}");
Set disabledTransforms = new HashSet<>(Arrays.asList(classNames));
setDisabledGlobalASTTransformations(disabledTransforms);
}
}
/**
* Gets the currently configured warning level. See {@link WarningMessage}
* for level details.
*/
public int getWarningLevel() {
return this.warningLevel;
}
/**
* Sets the warning level. See {@link WarningMessage} for level details.
*/
public void setWarningLevel(final 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(final String encoding) {
this.sourceEncoding = Optional.ofNullable(encoding).orElse(DEFAULT_SOURCE_ENCODING);
}
/**
* Gets the currently configured output writer.
* @deprecated not used anymore
*/
@Deprecated
public PrintWriter getOutput() {
return this.output;
}
/**
* Sets the output writer.
* @deprecated not used anymore, has no effect
*/
@Deprecated
public void setOutput(final 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(final String directory) {
setTargetDirectorySafe(directory);
}
private void setTargetDirectorySafe(final String directory) {
if (directory != null && directory.length() > 0) {
this.targetDirectory = new File(directory);
} else {
this.targetDirectory = null;
}
}
/**
* Sets the target directory.
*/
public void setTargetDirectory(final File directory) {
this.targetDirectory = directory;
}
/**
* @return the classpath
*/
public List getClasspath() {
return this.classpath;
}
/**
* Sets the classpath.
*/
public void setClasspath(final String classpath) {
this.classpath = new LinkedList<>();
StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
while (tokenizer.hasMoreTokens()) {
this.classpath.add(tokenizer.nextToken());
}
}
/**
* sets the classpath using a list of Strings
* @param parts list of strings containing the classpath parts
*/
public void setClasspathList(final List parts) {
this.classpath = new LinkedList<>(parts);
}
/**
* Returns true if verbose operation has been requested.
*/
public boolean getVerbose() {
return this.verbose;
}
/**
* Turns verbose operation on or off.
*/
public void setVerbose(final 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(final boolean debug) {
this.debug = debug;
}
/**
* Returns true if parameter metadata generation has been enabled.
*/
public boolean getParameters() {
return this.parameters;
}
/**
* Turns parameter metadata generation on or off.
*/
public void setParameters(final boolean parameters) {
this.parameters = parameters;
}
/**
* 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(final 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(final String scriptBaseClass) {
this.scriptBaseClass = scriptBaseClass;
}
public ParserPluginFactory getPluginFactory() {
if (pluginFactory == null) {
pluginFactory = ParserPluginFactory.antlr4();
}
return pluginFactory;
}
public void setPluginFactory(final ParserPluginFactory pluginFactory) {
this.pluginFactory = pluginFactory;
}
public void setScriptExtensions(final Set scriptExtensions) {
this.scriptExtensions = Optional.ofNullable(scriptExtensions).orElseGet(LinkedHashSet::new);
}
public Set getScriptExtensions() {
if (scriptExtensions == null || scriptExtensions.isEmpty()) {
/*
* this happens
* * when groovyc calls FileSystemCompiler in forked mode, or
* * when FileSystemCompiler is run from the command line directly, or
* * when groovy was not started using groovyc or FileSystemCompiler either
*/
scriptExtensions = SourceExtensionHandler.getRegisteredExtensions(getClass().getClassLoader());
}
return scriptExtensions;
}
public String getDefaultScriptExtension() {
return defaultScriptExtension;
}
public void setDefaultScriptExtension(final String defaultScriptExtension) {
this.defaultScriptExtension = defaultScriptExtension;
}
public boolean getRecompileGroovySource() {
return recompileGroovySource;
}
public void setRecompileGroovySource(final boolean recompile) {
recompileGroovySource = recompile;
}
public int getMinimumRecompilationInterval() {
return minimumRecompilationInterval;
}
public void setMinimumRecompilationInterval(final int time) {
minimumRecompilationInterval = Math.max(0,time);
}
/**
* Sets the bytecode compatibility level. The parameter can take one of the
* values in {@link #ALLOWED_JDKS}.
*
* @param version the bytecode compatibility level
*/
public void setTargetBytecode(final String version) {
setTargetBytecodeIfValid(version);
}
private void setTargetBytecodeIfValid(final String version) {
int index = Arrays.binarySearch(ALLOWED_JDKS, !version.startsWith("1") && !version.startsWith("2") ? "1." + version : version);
if (index >= 0) {
targetBytecode = ALLOWED_JDKS[index];
} else {
index = Math.abs(index) - 2; // closest version
targetBytecode = ALLOWED_JDKS[Math.max(0, index)];
}
}
/**
* Retrieves the compiler bytecode compatibility level. Defaults to the minimum
* officially supported bytecode version for any particular Groovy version.
*
* @return bytecode compatibility level
*/
public String getTargetBytecode() {
return this.targetBytecode;
}
/**
* Returns the targeted bytecode (aka Java class file) version number.
*
* @since 4.0.0
*/
public final int getBytecodeVersion() {
Integer bytecodeVersion = JDK_TO_BYTECODE_VERSION_MAP.get(getTargetBytecode());
if (bytecodeVersion == null) {
throw new GroovyBugError("Bytecode version '" + getTargetBytecode() + "' is not supported by the compiler");
}
if (isPreviewFeatures()) {
return bytecodeVersion | Opcodes.V_PREVIEW;
} else {
return bytecodeVersion;
}
}
/**
* Returns the default target bytecode compatibility level
*
* @return the default target bytecode compatibility level
* @since 4.0.0
*/
private static String defaultTargetBytecode() {
String javaVersion = Integer.toString(Runtime.version().feature());
if (JDK_TO_BYTECODE_VERSION_MAP.containsKey(javaVersion)) {
return javaVersion;
}
return JDK11;
}
/**
* Whether the bytecode version has preview features enabled (JEP 12)
*
* @return preview features
*/
public boolean isPreviewFeatures() {
return previewFeatures;
}
/**
* Sets whether the bytecode version has preview features enabled (JEP 12).
*
* @param previewFeatures whether to support preview features
*/
public void setPreviewFeatures(final boolean previewFeatures) {
this.previewFeatures = previewFeatures;
}
/**
* Returns whether logging class generation is enabled
*
* @return whether logging class generation is enabled
* @since 4.0.0
*/
public boolean isLogClassgen() {
return logClassgen;
}
/**
* Sets whether logging class generation is enabled
*
* @param logClassgen whether to enable logging class generation
* @since 4.0.0
*/
public void setLogClassgen(boolean logClassgen) {
this.logClassgen = logClassgen;
}
/**
* Returns stack trace max depth of logging class generation
*
* @return stack trace max depth of logging class generation
* @since 4.0.0
*/
public int getLogClassgenStackTraceMaxDepth() {
return logClassgenStackTraceMaxDepth;
}
/**
* Sets stack trace max depth of logging class generation
*
* @param logClassgenStackTraceMaxDepth stack trace max depth of logging class generation
* @since 4.0.0
*/
public void setLogClassgenStackTraceMaxDepth(int logClassgenStackTraceMaxDepth) {
this.logClassgenStackTraceMaxDepth = logClassgenStackTraceMaxDepth;
}
/**
* Gets the joint compilation options for this configuration.
* @return the options
*/
public Map getJointCompilationOptions() {
return jointCompilationOptions;
}
/**
* Sets the joint compilation options for this configuration.
* Using null will disable joint compilation.
* @param options the options
*/
public void setJointCompilationOptions(final Map options) {
jointCompilationOptions = options;
}
/**
* Gets the optimization options for this configuration.
* @return the options (always not null)
*/
public Map getOptimizationOptions() {
return optimizationOptions;
}
/**
* Sets the optimization options for this configuration.
* No entry or a true for that entry means to enable that optimization,
* a false means the optimization is disabled.
* Valid keys are "all" and "int".
* @param options the options.
* @throws IllegalArgumentException if the options are null
*/
public void setOptimizationOptions(final Map options) {
if (options == null) throw new IllegalArgumentException("provided option map must not be null");
optimizationOptions = options;
}
/**
* Adds compilation customizers to the compilation process. A compilation customizer is a class node
* operation which performs various operations going from adding imports to access control.
* @param customizers the list of customizers to be added
* @return this configuration instance
*/
public CompilerConfiguration addCompilationCustomizers(final CompilationCustomizer... customizers) {
if (customizers == null) throw new IllegalArgumentException("provided customizers list must not be null");
Collections.addAll(compilationCustomizers, customizers);
return this;
}
/**
* Returns the list of compilation customizers.
* @return the customizers (always not null)
*/
public List getCompilationCustomizers() {
return compilationCustomizers;
}
/**
* Returns the list of disabled global AST transformation class names.
* @return a list of global AST transformation fully qualified class names
*/
public Set getDisabledGlobalASTTransformations() {
return disabledGlobalASTTransformations;
}
/**
* Disables the specified global AST transformations. In order to avoid class loading side effects,
* it is not recommended to use MyASTTransformation.class.getName() but instead directly use the class
* name as a string. Disabled AST transformations only apply to automatically loaded global AST
* transformations, that is to say transformations defined in a
* META-INF/services/org.codehaus.groovy.transform.ASTTransformation file.
* If you explicitly add a global AST transformation in your compilation process,
* for example using the {@link org.codehaus.groovy.control.customizers.ASTTransformationCustomizer} or
* using a {@link org.codehaus.groovy.control.CompilationUnit.IPrimaryClassNodeOperation},
* then nothing will prevent the transformation from being loaded.
*
* @param disabledGlobalASTTransformations a set of fully qualified class names of global AST transformations
* which should not be loaded.
*/
public void setDisabledGlobalASTTransformations(final Set disabledGlobalASTTransformations) {
this.disabledGlobalASTTransformations = disabledGlobalASTTransformations;
}
public BytecodeProcessor getBytecodePostprocessor() {
return bytecodePostprocessor;
}
public void setBytecodePostprocessor(final BytecodeProcessor bytecodePostprocessor) {
this.bytecodePostprocessor = bytecodePostprocessor;
}
/**
* Checks if invoke dynamic is enabled.
*/
public boolean isIndyEnabled() {
return !Boolean.FALSE.equals(getOptimizationOptions().get(INVOKEDYNAMIC));
}
/**
* Checks if groovydoc is enabled.
*/
public boolean isGroovydocEnabled() {
return Boolean.TRUE.equals(getOptimizationOptions().get(GROOVYDOC));
}
/**
* Checks if runtime groovydoc is enabled.
*/
public boolean isRuntimeGroovydocEnabled() {
return Boolean.TRUE.equals(getOptimizationOptions().get(RUNTIME_GROOVYDOC));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy