package org.gradle.test;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.messages.SimpleMessage;
import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.util.ReleaseInfo;
import java.util.List;
/**
* Searches through all classes to be compiled for a field named
* "groovycVersion". If such a field is found, a field initializer is added
* and the search ends. The initializer sets the field to a String containing
* the groovyc version detected (currently "1.6"). Any existing initializer
* is overriden. If the field's type is not compatible with String, a compile-
* time or runtime error will occur.
* Because transforms have only been introduced in Groovy 1.6, this transform
* will have no effect on classes compiled with earlier Groovy versions.
*/
@SuppressWarnings("unchecked")
@GroovyASTTransformation(phase = CompilePhase.CONVERSION)
public class DetectorTransform implements ASTTransformation {
private static final String VERSION_FIELD_NAME = "groovycVersion";
public void visit(ASTNode[] nodes, SourceUnit source) {
if (nodes.length == 0 || !(nodes[0] instanceof ModuleNode)) {
source.getErrorCollector().addError(new SimpleMessage(
"internal error in DetectorTransform", source));
return;
}
ModuleNode module = (ModuleNode)nodes[0];
for (ClassNode clazz : (List<ClassNode>)module.getClasses()) {
FieldNode field = clazz.getField(VERSION_FIELD_NAME);
if (field != null) {
field.setInitialValueExpression(new ConstantExpression(ReleaseInfo.getVersion()));
break;
}
}
}
}