use of groovy.transform.CompilationUnitAware in project groovy by apache.
the class ASTTransformationVisitor method visitClass.
/**
* Main loop entry.
* <p>
* First, it delegates to the super visitClass so we can collect the
* relevant annotations in an AST tree walk.
* <p>
* Second, it calls the visit method on the transformation for each relevant
* annotation found.
*
* @param classNode the class to visit
*/
@Override
public void visitClass(ClassNode classNode) {
// only descend if we have annotations to look for
Map<Class<? extends ASTTransformation>, Set<ASTNode>> baseTransforms = classNode.getTransforms(phase);
if (!baseTransforms.isEmpty()) {
final Map<Class<? extends ASTTransformation>, ASTTransformation> transformInstances = new HashMap<Class<? extends ASTTransformation>, ASTTransformation>();
for (Class<? extends ASTTransformation> transformClass : baseTransforms.keySet()) {
try {
transformInstances.put(transformClass, transformClass.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
source.getErrorCollector().addError(new SimpleMessage("Could not instantiate Transformation Processor " + transformClass, // + " declared by " + annotation.getClassNode().getName(),
source));
}
}
// invert the map, is now one to many
transforms = new HashMap<ASTNode, List<ASTTransformation>>();
for (Map.Entry<Class<? extends ASTTransformation>, Set<ASTNode>> entry : baseTransforms.entrySet()) {
for (ASTNode node : entry.getValue()) {
List<ASTTransformation> list = transforms.computeIfAbsent(node, k -> new ArrayList<>());
list.add(transformInstances.get(entry.getKey()));
}
}
targetNodes = new LinkedList<ASTNode[]>();
// first pass, collect nodes
super.visitClass(classNode);
// second pass, call visit on all of the collected nodes
List<Tuple2<ASTTransformation, ASTNode[]>> tuples = new ArrayList<>();
for (ASTNode[] node : targetNodes) {
for (ASTTransformation snt : transforms.get(node[0])) {
tuples.add(new Tuple2<>(snt, node));
}
}
tuples.sort(priorityComparator);
for (Tuple2<ASTTransformation, ASTNode[]> tuple : tuples) {
if (tuple.getV1() instanceof CompilationUnitAware) {
((CompilationUnitAware) tuple.getV1()).setCompilationUnit(context.getCompilationUnit());
}
tuple.getV1().visit(tuple.getV2(), source);
}
}
}
use of groovy.transform.CompilationUnitAware in project groovy by apache.
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);
GroovyASTTransformation transformAnnotation = 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)) {
ASTTransformation instance = (ASTTransformation) gTransClass.getDeclaredConstructor().newInstance();
if (instance instanceof CompilationUnitAware) {
((CompilationUnitAware) instance).setCompilationUnit(compilationUnit);
}
CompilationUnit.ISourceUnitOperation suOp = source -> 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) {
Throwable effectiveException = e instanceof InvocationTargetException ? e.getCause() : e;
compilationUnit.getErrorCollector().addError(new SimpleMessage("Could not instantiate global transform class " + entry.getKey() + " specified at " + entry.getValue().toExternalForm() + " because of exception " + effectiveException.toString(), null));
}
}
}
use of groovy.transform.CompilationUnitAware 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 groovy.transform.CompilationUnitAware in project grails-core by grails.
the class ArtefactTypeAstTransformation method performInjectionOnArtefactType.
public void performInjectionOnArtefactType(SourceUnit sourceUnit, ClassNode cNode, String artefactType) {
List<ClassInjector> injectors = findInjectors(artefactType, GrailsAwareInjectionOperation.getClassInjectors());
for (ClassInjector injector : injectors) {
if (injector instanceof CompilationUnitAware) {
((CompilationUnitAware) injector).setCompilationUnit(this.compilationUnit);
}
}
performInjection(sourceUnit, cNode, injectors);
}
Aggregations