I want to convert
x.foo(a, b);
into
x.foo(a).bar(b);
I can easily match for acme.X foo(acme.A, acme.B)
, but how do I build a JavaTemplate that can do that replacement for me?
When I run
@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;
}
};
}
I get
foo(a).bar(b);
instead of
x.foo(a).bar(b);
This worked for me (credit to 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;
}
};
}