groovy - 无法访问 groovy 闭包中的局部变量
问题描述
我正在使用 java 使用反射修改一些 groovy 代码。
原始的 groovy 代码形式如下:
void method() {
A(processId);
B();
}
我需要修改它以注入 processId:
void callMethod() {
int processId = rand();
invokeMethod(
{->
A(processId);
B();
}, processId);
}
void invokeMethod(Closure closure, int processId) {
doSomething(processId);
closure.call();
}
注意:invokeMethod() 是现有方法,没有注入。
当我修改上面的原始代码时,我收到了这个错误:“groovy.lang.MissingPropertyException: No such property: processId”
我尝试将“callMethod”方法的 variableScope 设置为将“processId”变量包含为 DeclaredVariable。
作为参考,这是我用来执行此操作的代码:
private void wrapMethod(@NonNull MethodNode node)
{
VariableExpression var = new VariableExpression("processId", new ClassNode(Integer.class));
var.setClosureSharedVariable(true);
//Generate a statement that creates a processId
Statement statement = GeneralUtils.declS(var, GeneralUtils.callThisX("getUUID"));
ClosureExpression methodClosure = createMethodClosure(node);
ArgumentListExpression args = createArgumentListExpression(methodClosure,
varX("processId"));
MethodCallExpression method = GeneralUtils.callThisX("invokeMethod", args);
BlockStatement newMethodCode = GeneralUtils.block(statement, GeneralUtils.stmt(method));
newMethodCode.setVariableScope(methodClosure.getVariableScope().copy());
//Just to be safe, modifying the scope of the node as well.
VariableScope newScope = node.getVariableScope().copy();
newScope.putDeclaredVariable(var);
node.setCode(newMethodCode);
node.setVariableScope(newScope);
}
private ClosureExpression createMethodClosure(MethodNode node) {
//Get code from within node to dump into a closure.
BlockStatement block = (BlockStatement) node.getCode();
//Setting closureScope and adding processId
VariableScope closureScope = block.getVariableScope().copy();
closureScope.getReferencedLocalVariablesIterator()
.forEachRemaining(x -> x.setClosureSharedVariable(true));
Variable var = new VariableExpression("processId", new ClassNode(Integer.class));
var.setClosureSharedVariable(true);
closureScope.putDeclaredVariable(var);
ClosureExpression methodClosure = GeneralUtils.closureX(block);
methodClosure.setVariableScope(closureScope);
return methodClosure;
}
我已经验证了代码以检查在 invokeMethod() 块中是否可以访问“processId”,并且注入的结果代码是否符合预期。
关于为什么这不起作用的任何想法?
解决方案
推荐阅读
- javascript - 用于外部事件的 Fullcalendar V4 JSON 数据
- angular - 使用 Firebase 和 Angular 进行身份验证。用户登录后如何导航到其他组件?
- count - Ocaml - 返回表达式的数量
- python - Python中的轮廓
- python - 为什么我的多进程队列可能“丢失”项目?
- reactjs - 打印时强制展开ExpansionPanel
- c# - 如何在 AbsoluteLayout 中正确居中?
- computer-vision - skimage.feature.greycomatrix 只产生对角线值
- authentication - 通过使用 2FA 的 Okta 进行身份验证
- python - 具有两个输入的递归函数