File classesDir, final Transformer transformer) {
logger.info("Compiling {} using {}.", source.getDisplayName(), transformer != null ? transformer.getClass().getSimpleName() : "no transformer");
final EmptyScriptDetector emptyScriptDetector = new EmptyScriptDetector();
final PackageStatementDetector packageDetector = new PackageStatementDetector();
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader, configuration, false) {
@Override
protected CompilationUnit createCompilationUnit(CompilerConfiguration compilerConfiguration,
CodeSource codeSource) {
CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration, codeSource, this) {
// This creepy bit of code is here to put the full source path of the script into the debug info for
// the class. This makes it possible for a debugger to find the source file for the class. By default
// Groovy will only put the filename into the class, but that does not help a debugger for Gradle
// because it does not know where Gradle scripts might live.
@Override
protected groovyjarjarasm.asm.ClassVisitor createClassVisitor() {
return new ClassWriter(ClassWriter.COMPUTE_MAXS) {
// ignore the sourcePath that is given by Groovy (this is only the filename) and instead
// insert the full path if our script source has a source file
@Override
public void visitSource(String sourcePath, String debugInfo) {
super.visitSource(source.getFileName(), debugInfo);
}
};
}
};
if (transformer != null) {
transformer.register(compilationUnit);
}
compilationUnit.addPhaseOperation(packageDetector, Phases.CANONICALIZATION);
compilationUnit.addPhaseOperation(emptyScriptDetector, Phases.CANONICALIZATION);
return compilationUnit;
}
};
String scriptText = source.getResource().getText();
String scriptName = source.getClassName();
GroovyCodeSource codeSource = new GroovyCodeSource(scriptText == null ? "" : scriptText, scriptName, "/groovy/script");
try {
groovyClassLoader.parseClass(codeSource, false);
} catch (MultipleCompilationErrorsException e) {
SyntaxException syntaxError = e.getErrorCollector().getSyntaxError(0);
Integer lineNumber = syntaxError == null ? null : syntaxError.getLine();
throw new ScriptCompilationException(String.format("Could not compile %s.", source.getDisplayName()), e, source,
lineNumber);