Итак, мой первоначальный ответ был:
Может быть трудно получить помощь, когда дело доходит до преобразований AST.Хотя это предположение, я думаю, что это может иметь отношение к переменной области.Существует VariableScopeVisitor, который запускается на ранних этапах процесса AST и задает область видимости переменных, однако из описания вашего AST вы добавляете код, к которому вы хотите обращаться позже.Поэтому вам, возможно, придется снова запустить VariableScopeVisitor, чтобы исправить его так, чтобы существующий код имел доступ к введенному вами коду.
В этом году я провел вступительный доклад AST на GR8Conf.US, в котором много ресурсов.:
https://docs.google.com/presentation/d/1D4B0YQd0_0HYxK2FOt3xILM9XIymh-G-jh1TbQldbVA/edit?usp=sharing
Я бы взглянул на эту статью, в которой говорится о переменной области действия:
Однако реальный ответ таков:
Преобразования AST могут быть трудными, и использование AstBuilder, хотя это может быть удобно, может вызвать проблемы, поэтому я часто использую API напрямую.Как только я изучу макросы и методы макросов, впервые появившиеся в Groovy 2.5, мне, возможно, не придется слишком часто использовать API, но до этого я переписывал часть кода с помощью API, например:
//modification of method "add"
def addMethods = myClass.getMethods("add")
for(m in addMethods){
def code = m.getCode().statements
//statement
//AstBuilder abc = new AstBuilder()
Statement s1 = new ExpressionStatement(
new BinaryExpression(
new VariableExpression('timeOfInstantiation'),
Token.newSymbol(org.codehaus.groovy.syntax.Types.EQUAL,0,0),
new MethodCallExpression(
new ClassExpression(new ClassNode(java.lang.System)),
'currentTimeMillis',
ArgumentListExpression.EMPTY_ARGUMENTS
)
)
)
// List<ASTNode> statement1 = abc.buildFromString('timeOfInstantiation = System.currentTimeMillis()')
// List<ASTNode> statement1 = abc.buildFromCode {
// timeOfInstantiation = System.currentTimeMillis()
// for(c in code){
// c.expression
// }
// }
code.add(0,s1)
//m.setCode(statement1[0])
}
Этот код можетбыть немного убранным, но это должно работать.Мне также пришлось изменить timeOfInstantiation на private, а не final, чтобы код назначения работал следующим образом:
FieldNode field = new FieldNode("timeOfInstantiation", FieldNode.ACC_PRIVATE, longClass, myClass, new ConstantExpression(System.currentTimeMillis()))
Я бы также посмотрел ссылку на тестовое приложение в своей презентации, так как это будетразрешить отладку преобразований AST и использование консоли Groovy, чтобы увидеть, что делают преобразования.