Skip to content

Instantly share code, notes, and snippets.

@c089
Created December 4, 2011 20:23
Show Gist options
  • Save c089/1431174 to your computer and use it in GitHub Desktop.
Save c089/1431174 to your computer and use it in GitHub Desktop.
Playing around with local transformations
package name.neuroth.playground
import java.lang.annotation.Retention
import java.lang.annotation.Target
import org.codehaus.groovy.transform.GroovyASTTransformationClass
import java.lang.annotation.ElementType
import java.lang.annotation.RetentionPolicy
@Retention(RetentionPolicy.SOURCE)
@Target([ElementType.TYPE])
@GroovyASTTransformationClass(["name.neuroth.playground.ClassWithLoggingASTTransformation"])
public @interface ClassWithLogging {
}
package name.neuroth.playground
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.stmt.Statement
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
public class ClassWithLoggingASTTransformation implements ASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
List methods = sourceUnit.getAST()?.getClasses().first().getMethods()
// find all methods annotated with @WithLogging
methods.findAll { MethodNode method ->
method.getAnnotations(new ClassNode(WithLogging))
}.each { MethodNode method ->
Statement startMessage = createPrintlnAst("Starting $method.name")
Statement endMessage = createPrintlnAst("Ending $method.name")
List existingStatements = method.getCode().getStatements()
existingStatements.add(0, startMessage)
existingStatements.add(endMessage)
}
}
private Statement createPrintlnAst(String message) {
return new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new ConstantExpression(message)
)
)
)
}
}
package name.neuroth.playground
import java.lang.annotation.Retention
import java.lang.annotation.Target
import org.codehaus.groovy.transform.GroovyASTTransformationClass
import java.lang.annotation.ElementType
import java.lang.annotation.RetentionPolicy
@Retention(RetentionPolicy.SOURCE)
@Target([ElementType.METHOD])
@GroovyASTTransformationClass(["name.neuroth.playground.LoggingASTTransformation"])
public @interface WithLogging {
}
package name.neuroth.playground
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.stmt.Statement
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
public class LoggingASTTransformation implements ASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
List methods = sourceUnit.getAST()?.getMethods()
// find all methods annotated with @WithLogging
methods.findAll { MethodNode method ->
method.getAnnotations(new ClassNode(WithLogging))
}.each { MethodNode method ->
Statement startMessage = createPrintlnAst("Starting $method.name")
Statement endMessage = createPrintlnAst("Ending $method.name")
List existingStatements = method.getCode().getStatements()
existingStatements.add(0, startMessage)
existingStatements.add(endMessage)
}
}
private Statement createPrintlnAst(String message) {
return new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new ConstantExpression(message)
)
)
)
}
}
package name.neuroth.playground
@WithLogging
def foo() {
println 'x'
}
foo()
package name.neuroth.playground
@ClassWithLogging
class PlaygroundClass {
@WithLogging
def x() {
println 'x'
}
public static void main(String[] args) {
new PlaygroundClass().x()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment