最初的问题已删除,然后我才能对其作进一步回答,因此我将问题与答案一起重新发布:
由于无法确定修改后如何执行以前的方法语句,因此无法使用AST Transformation修改方法。我从方法中提取语句,将其保存在一些临时变量中,但是稍后,在修改后,当我尝试执行它时,我得到MissingPropertyException:无此类属性:类代码:计算器,就像我尝试使用属性一样从我的类,而不是我的方法的前一个代码块。有什么想法我做错了吗?
child: new ListView(
children: <Widget>[
new HorizontalList(list1),
new HorizontalList(list2),
new HorizontalList(list3),
new HorizontalList(list4),
]
)
该问题的代码超出了实际需要的代码。重要的部分是方法的修改。预先感谢。
从我的角度来看,我不知道AST中的代码是否真的有用,或者仅仅是为了使示例工作,学习AST转换...
答案 0 :(得分:0)
所以我的原始答案是:
在AST转换方面很难获得帮助。尽管这是一个猜测,但我认为这可能与可变范围有关。有一个VariableScopeVisitor在AST流程的早期运行,设置变量的作用域,但是从AST的描述中,您正在添加要稍后访问的代码。因此,您可能必须再次运行VariableScopeVisitor进行修复,以使现有代码可以访问您注入的代码。
我今年在GR8Conf.US上做了一个AST简介,它有很多资源:
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控制台查看转换的作用。