Search in sources :

Example 1 with CompilationUnitAware

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);
        }
    }
}
Also used : Set(java.util.Set) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) ASTNode(org.codehaus.groovy.ast.ASTNode) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) CompilationUnitAware(groovy.transform.CompilationUnitAware) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) InvocationTargetException(java.lang.reflect.InvocationTargetException) Tuple2(groovy.lang.Tuple2) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 2 with CompilationUnitAware

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));
        }
    }
}
Also used : CompilationUnit(org.codehaus.groovy.control.CompilationUnit) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) CompilePhase(org.codehaus.groovy.control.CompilePhase) Enumeration(java.util.Enumeration) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) ASTTransformationsContext(org.codehaus.groovy.control.ASTTransformationsContext) URLStreams(org.codehaus.groovy.util.URLStreams) HashMap(java.util.HashMap) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Tuple2(groovy.lang.Tuple2) Tuple3(groovy.lang.Tuple3) CompilationUnit(org.codehaus.groovy.control.CompilationUnit) Map(java.util.Map) ClassCodeVisitorSupport(org.codehaus.groovy.ast.ClassCodeVisitorSupport) Expression(org.codehaus.groovy.ast.expr.Expression) LinkedList(java.util.LinkedList) PropertyNode(org.codehaus.groovy.ast.PropertyNode) GeneratorContext(org.codehaus.groovy.classgen.GeneratorContext) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) CompilationUnitAware(groovy.transform.CompilationUnitAware) SourceUnit(org.codehaus.groovy.control.SourceUnit) ClassNode(org.codehaus.groovy.ast.ClassNode) Set(java.util.Set) IOException(java.io.IOException) InputStreamReader(java.io.InputStreamReader) StandardCharsets(java.nio.charset.StandardCharsets) InvocationTargetException(java.lang.reflect.InvocationTargetException) ASTNode(org.codehaus.groovy.ast.ASTNode) Phases(org.codehaus.groovy.control.Phases) List(java.util.List) GroovyClassVisitor(org.codehaus.groovy.ast.GroovyClassVisitor) WarningMessage(org.codehaus.groovy.control.messages.WarningMessage) Tuple(groovy.lang.Tuple) BufferedReader(java.io.BufferedReader) Comparator(java.util.Comparator) GroovyClassLoader(groovy.lang.GroovyClassLoader) Collections(java.util.Collections) WarningMessage(org.codehaus.groovy.control.messages.WarningMessage) CompilationUnitAware(groovy.transform.CompilationUnitAware) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException) GroovyClassLoader(groovy.lang.GroovyClassLoader) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 3 with CompilationUnitAware

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));
        }
    }
}
Also used : WarningMessage(org.codehaus.groovy.control.messages.WarningMessage) CompilationUnitAware(groovy.transform.CompilationUnitAware) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) URL(java.net.URL) IOException(java.io.IOException) GroovyClassLoader(groovy.lang.GroovyClassLoader)

Example 4 with CompilationUnitAware

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);
}
Also used : CompilationUnitAware(groovy.transform.CompilationUnitAware) GrailsArtefactClassInjector(grails.compiler.ast.GrailsArtefactClassInjector) GlobalClassInjector(grails.compiler.ast.GlobalClassInjector) ClassInjector(grails.compiler.ast.ClassInjector) AllArtefactClassInjector(grails.compiler.ast.AllArtefactClassInjector)

Aggregations

CompilationUnitAware (groovy.transform.CompilationUnitAware)4 SimpleMessage (org.codehaus.groovy.control.messages.SimpleMessage)3 GroovyClassLoader (groovy.lang.GroovyClassLoader)2 Tuple2 (groovy.lang.Tuple2)2 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 URL (java.net.URL)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 Map (java.util.Map)2 Set (java.util.Set)2 ASTNode (org.codehaus.groovy.ast.ASTNode)2 WarningMessage (org.codehaus.groovy.control.messages.WarningMessage)2 AllArtefactClassInjector (grails.compiler.ast.AllArtefactClassInjector)1 ClassInjector (grails.compiler.ast.ClassInjector)1 GlobalClassInjector (grails.compiler.ast.GlobalClassInjector)1 GrailsArtefactClassInjector (grails.compiler.ast.GrailsArtefactClassInjector)1