我想转换
x.foo(a, b);
到
x.foo(a).bar(b);
我可以很容易地匹配acme.X foo(acme.A, acme.B)
,但我如何构建一个JavaTemplate,可以为我做的替代?
运行
@Override
protected TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<>() {
private final JavaTemplate template = JavaTemplate.builder(this::getCursor,
"foo(#{any(java.lang.String)}).bar(#{any(java.lang.String)})")
.build();
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
J.MethodInvocation m = super.visitMethodInvocation(method, executionContext);
if (....matches(method)) {
List<Expression> arguments = m.getArguments();
m = m.withTemplate(template, m.getCoordinates().replace(), arguments.get(0), arguments.get(1));
}
return m;
}
};
}
我foo(a).bar(b);
不是x.foo(a).bar(b);
这对我很有效(感谢Patrick Way on slack):
private static final MethodMatcher MATCHER =
new MethodMatcher("org.optaplanner.core.api.score.stream.ConstraintStream " +
"penalize(java.lang.String, org.optaplanner.core.api.score.Score)");
@Override
protected TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<>() {
private final JavaTemplate template = JavaTemplate.builder(() -> getCursor().getParentOrThrow(),
"#{any(org.optaplanner.core.api.score.stream.ConstraintStream)}" +
".penalize(#{any(org.optaplanner.core.api.score.Score)})" +
".asConstraint(#{any(java.lang.String)})"
).build();
@Override
public Expression visitExpression(Expression expression, ExecutionContext executionContext) {
Expression e = super.visitExpression(expression, executionContext);
if (MATCHER.matches(e)){
J.MethodInvocation mi = (J.MethodInvocation) e;
e = e.withTemplate(template,
e.getCoordinates().replace(), mi.getSelect(),
mi.getArguments().get(1), mi.getArguments().get(0));
}
return e;
}
};
}