package com.mycode.compiler import groovy.lang.GroovyClassLoader import groovy.transform.CompileStatic import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassCodeVisitorSupport import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer import org.codehaus.groovy.transform.ASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformationClass import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import java.io.File @TestInstance(TestInstance.Lifecycle.PER_CLASS) class TestPopper { class MyTestClass { var map: String? = null } class MyPrinter(private val sourceUnit: SourceUnit) : ClassCodeVisitorSupport() { override fun getSourceUnit(): SourceUnit = sourceUnit override fun visitConstantExpression(expression: ConstantExpression) { println("Visiting constant ${expression.value} ${expression.lineNumber} ${expression.columnNumber}") super.visitConstantExpression(expression) } } /** * Annotation to run before static analysis */ @MustBeDocumented @Retention(AnnotationRetention.SOURCE) @Target(AnnotationTarget.TYPE) @GroovyASTTransformationClass("com.mycode.compiler.TestPopper\$MyAnalysisTransformation") annotation class MyAnalysis @GroovyASTTransformation(phase = CompilePhase.INSTRUCTION_SELECTION) class MyAnalysisTransformation : ASTTransformation { /** Visits all AST Nodes */ override fun visit(nodes: Array?, source: SourceUnit) { val node: ClassNode? = nodes!![1] as? ClassNode MyPrinter(source).visitClass(node) } } @Test fun testPop() { val configuration = CompilerConfiguration().also { it.addCompilationCustomizers(ASTTransformationCustomizer(CompileStatic::class.java)) it.addCompilationCustomizers(ASTTransformationCustomizer(MyAnalysis::class.java)) } val compiler = GroovyClassLoader(javaClass.classLoader, configuration) compiler.parseClass(File("/tmp/Test.flow")) } }