private void verifyCompilePhase(AnnotationNode annotation, Class<?> klass) { GroovyASTTransformation transformationClass = klass.getAnnotation(GroovyASTTransformation.class); if (transformationClass != null) { CompilePhase specifiedCompilePhase = transformationClass.phase(); if (specifiedCompilePhase.getPhaseNumber() < CompilePhase.SEMANTIC_ANALYSIS.getPhaseNumber()) { source .getErrorCollector() .addError( new SimpleMessage( annotation.getClassNode().getName() + " is defined to be run in compile phase " + specifiedCompilePhase + ". Local AST transformations must run in " + CompilePhase.SEMANTIC_ANALYSIS + " or later!", source)); } } else { source .getErrorCollector() .addError( new SimpleMessage( "AST transformation implementation classes must be annotated with " + GroovyASTTransformation.class.getName() + ". " + klass.getName() + " lacks this annotation.", source)); } }
private Map<CompilePhase, Map<Class<? extends ASTTransformation>, Set<ASTNode>>> getTransformInstances() { if (transformInstances == null) { transformInstances = new EnumMap<CompilePhase, Map<Class<? extends ASTTransformation>, Set<ASTNode>>>( CompilePhase.class); for (CompilePhase phase : CompilePhase.values()) { transformInstances.put( phase, new HashMap<Class<? extends ASTTransformation>, Set<ASTNode>>()); } } return transformInstances; }
public static void addPhaseOperations(final CompilationUnit compilationUnit) { final ASTTransformationsContext context = compilationUnit.getASTTransformationsContext(); addGlobalTransforms(context); compilationUnit.addPhaseOperation( new CompilationUnit.PrimaryClassNodeOperation() { public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { ASTTransformationCollectorCodeVisitor collector = new ASTTransformationCollectorCodeVisitor( source, compilationUnit.getTransformLoader()); collector.visitClass(classNode); } }, Phases.SEMANTIC_ANALYSIS); for (CompilePhase phase : CompilePhase.values()) { final ASTTransformationVisitor visitor = new ASTTransformationVisitor(phase, context); switch (phase) { case INITIALIZATION: case PARSING: case CONVERSION: // with transform detection alone these phases are inaccessible, so don't add it break; default: compilationUnit.addPhaseOperation( new CompilationUnit.PrimaryClassNodeOperation() { public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { visitor.source = source; visitor.visitClass(classNode); } }, phase.getPhaseNumber()); break; } } }