Skip to content

Instantly share code, notes, and snippets.

@shamoh
Created December 2, 2012 22:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shamoh/4191464 to your computer and use it in GitHub Desktop.
Save shamoh/4191464 to your computer and use it in GitHub Desktop.
Correct way to make Groovy LoggingASTTransformation - http://groovy.codehaus.org/Local+AST+Transformations
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.stmt.Statement
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.transform.GroovyASTTransformation
/**
* Example of Groovy Local AST Transformations, http://groovy.codehaus.org/Local+AST+Transformations
* <p>
* What is wrong on mentioned example in original URL?
* <li>It works just with Groovy script - not Groovy class!</li>
* <li>It duplicates logging if there is more methods in a script/class</li>
*/
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
class LoggingASTTransformation implements ASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
// IF section was refactored - working with last from nodes instead of sourceUnit (that can be shared by more methods)
def lastNode = nodes.last()
if ( lastNode instanceof MethodNode ) {
def method = (MethodNode) lastNode
if ( method.getAnnotations(new ClassNode(WithLogging)) ) {
// following lines are same as original
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)
)
)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment