Groovy AST Transformation - replace method

2019-05-31 23:00发布

问题:

I am trying to replace a method of a class using AST transformations.

I first check to see if the method exists and then remove it (based on this).

MethodNode methodNode = parentClass.getMethod(methodName, Parameter.EMPTY_ARRAY)
if (methodNode != null) {
     parentClass.getMethods().remove(methodNode)
} 

I see the size change on the collection, but the method is still accessible on the class node.

After removing the method I would then like to add a new one of the same name:

parentClass.addMethod(newMethodNode)

However, this causes the following error:

 Repetitive method name/signature for method 'grails.plugin.Bar getBar()' in class 'grails.plugin.Foo'.

What is the correct way to do this?

Update: Since all I was intending to do was replace existing functionality of the method, I instead created a new block statement and set this on the existing method using methodNode.setCode(statement).

回答1:

Sounds like what you're trying to do is to wrap a method with some other stuff? Here's an example of wrapping a method in a try/finally.

import org.codehaus.groovy.ast.*
import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.ast.stmt.*

methodNode.setCode(methodThatCreatesAst(methodNode.getCode()))

def methodThatCreatesAst(Statement statementToWrap) {
  BlockStatement methodBody = new BlockStatement()

  methodBody.addStatement(new TryCatchStatement(
    // try
    statementToWrap,
    // finally
    new ExpressionStatement(
      new MethodCallExpression(
        "myVar", "myMethod", new ArgumentListExpression()
      )
    )
  ))

  return methodBody
}

Other than that I'm not able to help since I've never actually attempted to remove a method before :)