JCodeModel - Как связать методы вызова
Я пытаюсь выяснить, как использовать цикл для создания JExpression
что я могу использовать в .assign()
вызов. Я знаю, что вы можете сделать что-то вроде JExpr.invoke("methodA").invoke("methodB")
с JCodeMode, но я хочу иметь возможность добавлять каждый .invoke()
метод основан на списке имен методов. Кто-нибудь знает как это сделать?
Пример моего кода Generator [предполагается, что я изменил метод ArrayList.add() для возвращения ArrayList]:
JDefinedClass newClass = jCodeModel._class("com.me.GeneratedClass");
JClass refObject = jCodeModel.ref(Object.class);
JClass refArrayList = jCodeModel.ref(ArrayList.class);
JFieldVar objectList = newClass.field(refArrayList, "objects");
JBlock methodBody = newClass.method(JMod.PUBLIC, refArrayList, "getNewObjectList");
String[] methodsToInvoke = {"add", "add", "add"};
JExpression rhsAssignmentExpression = JExpr._new(refArrayList).narrow(refObject);
for(String methodName : methodsToInvoke) {
rhsAssignmentExpression.invoke(methodName).arg(JExpr._new(refObject));
}
methodBody.assign(objectList, rhsAssignmentExpression);
methodBody._return(objectList);
Пример того, что я пытаюсь сгенерировать:
class GeneratedClass {
ArrayList<Object> objects;
public ArrayList<Object> getNewObjectList()
{
objects = new ArrayList<Object>().add(new Object()).add(new Object()).add(new Object());
return objects;
}
}
Моя проблема в том, что этот метод не связывает методы invoke, а заменяет их так, что сгенерированный код выглядит так:
class GeneratedClass {
ArrayList<Object> objects;
public ArrayList<Object> getNewObjectList()
{
objects = new ArrayList<Object>().add(new Object());
return objects;
}
}
2 ответа
Вам нужно будет сохранить промежуточное значение для каждого вызова JExpression invoke ():
JExpression rhsAssignmentExpression = JExpr._new(refArrayList);
for(String methodName : methodsToInvoke) {
rhsAssignmentExpression = rhsAssignmentExpression.invoke(methodName).arg(JExpr._new(refObject));
}
Это позволяет избежать повторного определения вызова каждый раз и эффективно объединяет вызовы. Результат следующий:
public class GeneratedClass {
public ArrayList objects;
public ArrayList getNewObjectList() {
objects = new ArrayList().add(new Object()).add(new Object()).add(new Object());
return objects;
}
}
Это также можно сделать, используя JCodeModel для печати необработанных строк вместо объявления объектов JCode. Для этой конкретной проблемы не нужно генерировать java-импорт, так что это можно сделать с помощью directStatement().
StringBuilder expression = new StringBuilder();
expression.append (“objects = new ArrayList<Object>()”);
if ((methodsToInvoke != null) && (methodsToInvoke.length > 0))
{
for(String methodName : methodsToInvoke)
{
expression.append(“.add(new Object())”);
}
}
expression.append(“;”);
methodBoby.directStatement(expression.toString());