JCodeModel - Как связать методы вызова

Я пытаюсь понять, как использовать цикл для создания JExpression, который я могу использовать в вызове .assign(). Я знаю, что вы можете сделать что-то вроде JExpr.invoke("methodA").invoke("methodB") с JCodeModel, но я хочу иметь возможность добавлять каждый метод .invoke() на основе списка имен методов. Кто-нибудь знает как это сделать?

Пример кода моего генератора [предполагается, что я изменил метод 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;
   }
}

Моя проблема в том, что этот метод не связывает методы вызова, а заменяет их, поэтому сгенерированный код выглядит так:

class GeneratedClass {

   ArrayList<Object> objects;

   public ArrayList<Object> getNewObjectList()
   {
      objects = new ArrayList<Object>().add(new Object());
      return objects;
   }
}

person kriegh13    schedule 20.03.2014    source источник


Ответы (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;
    }

}
person John Ericksen    schedule 21.03.2014

Это также можно сделать, заставив 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());
person Mark    schedule 20.03.2014