use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy by apache.
the class GroovyTypeCheckingExtensionSupport method setup.
@Override
public void setup() {
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass("org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport.TypeCheckingDSL");
ImportCustomizer ic = new ImportCustomizer();
ic.addStarImports("org.codehaus.groovy.ast.expr");
ic.addStaticStars("org.codehaus.groovy.ast.ClassHelper");
ic.addStaticStars("org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport");
config.addCompilationCustomizers(ic);
final GroovyClassLoader transformLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : typeCheckingVisitor.getSourceUnit().getClassLoader();
// since Groovy 2.2, it is possible to use FQCN for type checking extension scripts
TypeCheckingDSL script = null;
try {
Class<?> clazz = transformLoader.loadClass(scriptPath, false, true);
if (TypeCheckingDSL.class.isAssignableFrom(clazz)) {
script = (TypeCheckingDSL) clazz.newInstance();
} else if (TypeCheckingExtension.class.isAssignableFrom(clazz)) {
// since 2.4, we can also register precompiled type checking extensions which are not scripts
try {
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(StaticTypeCheckingVisitor.class);
TypeCheckingExtension extension = (TypeCheckingExtension) declaredConstructor.newInstance(typeCheckingVisitor);
typeCheckingVisitor.addTypeCheckingExtension(extension);
extension.setup();
return;
} catch (InstantiationException e) {
addLoadingError(config);
} catch (IllegalAccessException e) {
addLoadingError(config);
} catch (NoSuchMethodException e) {
context.getErrorCollector().addFatalError(new SimpleMessage("Static type checking extension '" + scriptPath + "' could not be loaded because it doesn't have a constructor accepting StaticTypeCheckingVisitor.", config.getDebug(), typeCheckingVisitor.getSourceUnit()));
} catch (InvocationTargetException e) {
addLoadingError(config);
}
}
} catch (ClassNotFoundException e) {
// silent
} catch (InstantiationException e) {
addLoadingError(config);
} catch (IllegalAccessException e) {
addLoadingError(config);
}
if (script == null) {
ClassLoader cl = typeCheckingVisitor.getSourceUnit().getClassLoader();
// cast to prevent incorrect @since 1.7 warning
InputStream is = ((ClassLoader) transformLoader).getResourceAsStream(scriptPath);
if (is == null) {
// fallback to the source unit classloader
is = cl.getResourceAsStream(scriptPath);
}
if (is == null) {
// fallback to the compiler classloader
cl = GroovyTypeCheckingExtensionSupport.class.getClassLoader();
is = cl.getResourceAsStream(scriptPath);
}
if (is == null) {
// if the input stream is still null, we've not found the extension
context.getErrorCollector().addFatalError(new SimpleMessage("Static type checking extension '" + scriptPath + "' was not found on the classpath.", config.getDebug(), typeCheckingVisitor.getSourceUnit()));
}
try {
GroovyShell shell = new GroovyShell(transformLoader, new Binding(), config);
script = (TypeCheckingDSL) shell.parse(new InputStreamReader(is, typeCheckingVisitor.getSourceUnit().getConfiguration().getSourceEncoding()));
} catch (CompilationFailedException e) {
throw new GroovyBugError("An unexpected error was thrown during custom type checking", e);
} catch (UnsupportedEncodingException e) {
throw new GroovyBugError("Unsupported encoding found in compiler configuration", e);
}
}
if (script != null) {
script.extension = this;
script.run();
List<Closure> list = eventHandlers.get("setup");
if (list != null) {
for (Closure closure : list) {
safeCall(closure);
}
}
}
}
use of org.codehaus.groovy.control.messages.SimpleMessage in project gradle by gradle.
the class ApiGroovyCompiler method execute.
@Override
public WorkResult execute(final GroovyJavaJointCompileSpec spec) {
GroovySystemLoaderFactory groovySystemLoaderFactory = new GroovySystemLoaderFactory();
ClassLoader compilerClassLoader = this.getClass().getClassLoader();
GroovySystemLoader compilerGroovyLoader = groovySystemLoaderFactory.forClassLoader(compilerClassLoader);
CompilerConfiguration configuration = new CompilerConfiguration();
configuration.setVerbose(spec.getGroovyCompileOptions().isVerbose());
configuration.setSourceEncoding(spec.getGroovyCompileOptions().getEncoding());
configuration.setTargetBytecode(spec.getTargetCompatibility());
configuration.setTargetDirectory(spec.getDestinationDir());
canonicalizeValues(spec.getGroovyCompileOptions().getOptimizationOptions());
if (spec.getGroovyCompileOptions().getConfigurationScript() != null) {
applyConfigurationScript(spec.getGroovyCompileOptions().getConfigurationScript(), configuration);
}
try {
configuration.setOptimizationOptions(spec.getGroovyCompileOptions().getOptimizationOptions());
} catch (NoSuchMethodError ignored) {
/* method was only introduced in Groovy 1.8 */
}
Map<String, Object> jointCompilationOptions = new HashMap<String, Object>();
final File stubDir = spec.getGroovyCompileOptions().getStubDir();
stubDir.mkdirs();
jointCompilationOptions.put("stubDir", stubDir);
jointCompilationOptions.put("keepStubs", spec.getGroovyCompileOptions().isKeepStubs());
configuration.setJointCompilationOptions(jointCompilationOptions);
ClassLoader classPathLoader;
VersionNumber version = parseGroovyVersion();
if (version.compareTo(VersionNumber.parse("2.0")) < 0) {
// using a transforming classloader is only required for older buggy Groovy versions
classPathLoader = new GroovyCompileTransformingClassLoader(getExtClassLoader(), new DefaultClassPath(spec.getCompileClasspath()));
} else {
classPathLoader = new DefaultClassLoaderFactory().createIsolatedClassLoader(new DefaultClassPath(spec.getCompileClasspath()));
}
GroovyClassLoader compileClasspathClassLoader = new GroovyClassLoader(classPathLoader, null);
GroovySystemLoader compileClasspathLoader = groovySystemLoaderFactory.forClassLoader(classPathLoader);
FilteringClassLoader.Spec groovyCompilerClassLoaderSpec = new FilteringClassLoader.Spec();
groovyCompilerClassLoaderSpec.allowPackage("org.codehaus.groovy");
groovyCompilerClassLoaderSpec.allowPackage("groovy");
// Disallow classes from Groovy Jar that reference external classes. Such classes must be loaded from astTransformClassLoader,
// or a NoClassDefFoundError will occur. Essentially this is drawing a line between the Groovy compiler and the Groovy
// library, albeit only for selected classes that run a high risk of being statically referenced from a transform.
groovyCompilerClassLoaderSpec.disallowClass("groovy.util.GroovyTestCase");
groovyCompilerClassLoaderSpec.disallowPackage("groovy.servlet");
FilteringClassLoader groovyCompilerClassLoader = new FilteringClassLoader(GroovyClassLoader.class.getClassLoader(), groovyCompilerClassLoaderSpec);
// AST transforms need their own class loader that shares compiler classes with the compiler itself
final GroovyClassLoader astTransformClassLoader = new GroovyClassLoader(groovyCompilerClassLoader, null);
// where the transform class is loaded from)
for (File file : spec.getCompileClasspath()) {
astTransformClassLoader.addClasspath(file.getPath());
}
JavaAwareCompilationUnit unit = new JavaAwareCompilationUnit(configuration, compileClasspathClassLoader) {
@Override
public GroovyClassLoader getTransformLoader() {
return astTransformClassLoader;
}
};
final boolean shouldProcessAnnotations = shouldProcessAnnotations(spec);
if (shouldProcessAnnotations) {
// If an annotation processor is detected, we need to force Java stub generation, so the we can process annotations on Groovy classes
// We are forcing stub generation by tricking the groovy compiler into thinking there are java files to compile.
// All java files are just passed to the compile method of the JavaCompiler and aren't processed internally by the Groovy Compiler.
// Since we're maintaining our own list of Java files independent of what's passed by the Groovy compiler, adding a non-existent java file
// to the sources won't cause any issues.
unit.addSources(new File[] { new File("ForceStubGeneration.java") });
}
// Sort source files to work around https://issues.apache.org/jira/browse/GROOVY-7966
File[] sortedSourceFiles = Iterables.toArray(spec.getSource(), File.class);
Arrays.sort(sortedSourceFiles);
unit.addSources(sortedSourceFiles);
unit.setCompilerFactory(new JavaCompilerFactory() {
public JavaCompiler createCompiler(final CompilerConfiguration config) {
return new JavaCompiler() {
public void compile(List<String> files, CompilationUnit cu) {
if (shouldProcessAnnotations) {
// In order for the Groovy stubs to have annotation processors invoked against them, they must be compiled as source.
// Classes compiled as a result of being on the -sourcepath do not have the annotation processor run against them
spec.setSource(spec.getSource().plus(new SimpleFileCollection(stubDir).getAsFileTree()));
} else {
// When annotation processing isn't required, it's better to add the Groovy stubs as part of the source path.
// This allows compilations to complete faster, because only the Groovy stubs that are needed by the java source are compiled.
ImmutableList.Builder<File> sourcepathBuilder = ImmutableList.builder();
sourcepathBuilder.add(stubDir);
if (spec.getCompileOptions().getSourcepath() != null) {
sourcepathBuilder.addAll(spec.getCompileOptions().getSourcepath());
}
spec.getCompileOptions().setSourcepath(sourcepathBuilder.build());
}
spec.setSource(spec.getSource().filter(new Spec<File>() {
public boolean isSatisfiedBy(File file) {
return hasExtension(file, ".java");
}
}));
try {
javaCompiler.execute(spec);
} catch (CompilationFailedException e) {
cu.getErrorCollector().addFatalError(new SimpleMessage(e.getMessage(), cu));
}
}
};
}
});
try {
unit.compile();
} catch (org.codehaus.groovy.control.CompilationFailedException e) {
System.err.println(e.getMessage());
// Explicit flush, System.err is an auto-flushing PrintWriter unless it is replaced.
System.err.flush();
throw new CompilationFailedException();
} finally {
// Remove compile and AST types from the Groovy loader
compilerGroovyLoader.discardTypesFrom(classPathLoader);
compilerGroovyLoader.discardTypesFrom(astTransformClassLoader);
// Discard the compile loader
compileClasspathLoader.shutdown();
}
return WorkResults.didWork(true);
}
use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy-core by groovy.
the class BindableASTTransformation method needsPropertyChangeSupport.
/**
* Snoops through the declaring class and all parents looking for methods
* <code>void addPropertyChangeListener(PropertyChangeListener)</code>,
* <code>void removePropertyChangeListener(PropertyChangeListener)</code>, and
* <code>void firePropertyChange(String, Object, Object)</code>. If any are defined all
* must be defined or a compilation error results.
*
* @param declaringClass the class to search
* @param sourceUnit the source unit, for error reporting. {@code @NotNull}.
* @return true if property change support should be added
*/
protected boolean needsPropertyChangeSupport(ClassNode declaringClass, SourceUnit sourceUnit) {
boolean foundAdd = false, foundRemove = false, foundFire = false;
ClassNode consideredClass = declaringClass;
while (consideredClass != null) {
for (MethodNode method : consideredClass.getMethods()) {
// just check length, MOP will match it up
foundAdd = foundAdd || method.getName().equals("addPropertyChangeListener") && method.getParameters().length == 1;
foundRemove = foundRemove || method.getName().equals("removePropertyChangeListener") && method.getParameters().length == 1;
foundFire = foundFire || method.getName().equals("firePropertyChange") && method.getParameters().length == 3;
if (foundAdd && foundRemove && foundFire) {
return false;
}
}
consideredClass = consideredClass.getSuperClass();
}
// check if a super class has @Bindable annotations
consideredClass = declaringClass.getSuperClass();
while (consideredClass != null) {
if (hasBindableAnnotation(consideredClass))
return false;
for (FieldNode field : consideredClass.getFields()) {
if (hasBindableAnnotation(field))
return false;
}
consideredClass = consideredClass.getSuperClass();
}
if (foundAdd || foundRemove || foundFire) {
sourceUnit.getErrorCollector().addErrorAndContinue(new SimpleMessage("@Bindable cannot be processed on " + declaringClass.getName() + " because some but not all of addPropertyChangeListener, removePropertyChange, and firePropertyChange were declared in the current or super classes.", sourceUnit));
return false;
}
return true;
}
use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy-core by groovy.
the class ASTTransformationVisitor method addPhaseOperationsForGlobalTransforms.
private static void addPhaseOperationsForGlobalTransforms(CompilationUnit compilationUnit, Map<String, URL> transformNames, boolean isFirstScan) {
GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
try {
Class gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
// no inspection unchecked
GroovyASTTransformation transformAnnotation = (GroovyASTTransformation) gTransClass.getAnnotation(GroovyASTTransformation.class);
if (transformAnnotation == null) {
compilationUnit.getErrorCollector().addWarning(new WarningMessage(WarningMessage.POSSIBLE_ERRORS, "Transform Class " + entry.getKey() + " is specified as a global transform in " + entry.getValue().toExternalForm() + " but it is not annotated by " + GroovyASTTransformation.class.getName() + " the global transform associated with it may fail and cause the compilation to fail.", null, null));
continue;
}
if (ASTTransformation.class.isAssignableFrom(gTransClass)) {
final ASTTransformation instance = (ASTTransformation) gTransClass.newInstance();
if (instance instanceof CompilationUnitAware) {
((CompilationUnitAware) instance).setCompilationUnit(compilationUnit);
}
CompilationUnit.SourceUnitOperation suOp = new CompilationUnit.SourceUnitOperation() {
public void call(SourceUnit source) throws CompilationFailedException {
instance.visit(new ASTNode[] { source.getAST() }, source);
}
};
if (isFirstScan) {
compilationUnit.addPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
} else {
compilationUnit.addNewPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
}
} else {
compilationUnit.getErrorCollector().addError(new SimpleMessage("Transform Class " + entry.getKey() + " specified at " + entry.getValue().toExternalForm() + " is not an ASTTransformation.", null));
}
} catch (Exception e) {
compilationUnit.getErrorCollector().addError(new SimpleMessage("Could not instantiate global transform class " + entry.getKey() + " specified at " + entry.getValue().toExternalForm() + " because of exception " + e.toString(), null));
}
}
}
use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy-core by groovy.
the class GroovyTypeCheckingExtensionSupport method setup.
@Override
public void setup() {
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass("org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport.TypeCheckingDSL");
ImportCustomizer ic = new ImportCustomizer();
ic.addStarImports("org.codehaus.groovy.ast.expr");
ic.addStaticStars("org.codehaus.groovy.ast.ClassHelper");
ic.addStaticStars("org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport");
config.addCompilationCustomizers(ic);
final GroovyClassLoader transformLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : typeCheckingVisitor.getSourceUnit().getClassLoader();
// since Groovy 2.2, it is possible to use FQCN for type checking extension scripts
TypeCheckingDSL script = null;
try {
Class<?> clazz = transformLoader.loadClass(scriptPath, false, true);
if (TypeCheckingDSL.class.isAssignableFrom(clazz)) {
script = (TypeCheckingDSL) clazz.newInstance();
} else if (TypeCheckingExtension.class.isAssignableFrom(clazz)) {
// since 2.4, we can also register precompiled type checking extensions which are not scripts
try {
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(StaticTypeCheckingVisitor.class);
TypeCheckingExtension extension = (TypeCheckingExtension) declaredConstructor.newInstance(typeCheckingVisitor);
typeCheckingVisitor.addTypeCheckingExtension(extension);
extension.setup();
return;
} catch (InstantiationException e) {
addLoadingError(config);
} catch (IllegalAccessException e) {
addLoadingError(config);
} catch (NoSuchMethodException e) {
context.getErrorCollector().addFatalError(new SimpleMessage("Static type checking extension '" + scriptPath + "' could not be loaded because it doesn't have a constructor accepting StaticTypeCheckingVisitor.", config.getDebug(), typeCheckingVisitor.getSourceUnit()));
} catch (InvocationTargetException e) {
addLoadingError(config);
}
}
} catch (ClassNotFoundException e) {
// silent
} catch (InstantiationException e) {
addLoadingError(config);
} catch (IllegalAccessException e) {
addLoadingError(config);
}
if (script == null) {
ClassLoader cl = typeCheckingVisitor.getSourceUnit().getClassLoader();
// cast to prevent incorrect @since 1.7 warning
InputStream is = ((ClassLoader) transformLoader).getResourceAsStream(scriptPath);
if (is == null) {
// fallback to the source unit classloader
is = cl.getResourceAsStream(scriptPath);
}
if (is == null) {
// fallback to the compiler classloader
cl = GroovyTypeCheckingExtensionSupport.class.getClassLoader();
is = cl.getResourceAsStream(scriptPath);
}
if (is == null) {
// if the input stream is still null, we've not found the extension
context.getErrorCollector().addFatalError(new SimpleMessage("Static type checking extension '" + scriptPath + "' was not found on the classpath.", config.getDebug(), typeCheckingVisitor.getSourceUnit()));
}
try {
GroovyShell shell = new GroovyShell(transformLoader, new Binding(), config);
script = (TypeCheckingDSL) shell.parse(new InputStreamReader(is, typeCheckingVisitor.getSourceUnit().getConfiguration().getSourceEncoding()));
} catch (CompilationFailedException e) {
throw new GroovyBugError("An unexpected error was thrown during custom type checking", e);
} catch (UnsupportedEncodingException e) {
throw new GroovyBugError("Unsupported encoding found in compiler configuration", e);
}
}
if (script != null) {
script.extension = this;
script.run();
List<Closure> list = eventHandlers.get("setup");
if (list != null) {
for (Closure closure : list) {
safeCall(closure);
}
}
}
}
Aggregations