Beispiel #1
0
  private void genConstructor(
      Refs r,
      JDefinedClass clazz,
      Collection<Ref> refs,
      Map<Ref, JFieldVar> fieldVarMap,
      JFieldVar holderListener,
      Map<Listener.Type, ListenerType> listenerTypeMap) {
    // private MyLayoutViewModel(View view) {
    JMethod constructor = clazz.constructor(PUBLIC);
    JVar viewVar = constructor.param(r.viewClass, "view");
    JBlock body = constructor.body();

    // super(view);
    body.invoke("super").arg(viewVar);

    // myLinearLayout = (LinearLayout) view.findViewById(R.id.my_linear_layout);
    // myTextView = (TextView) myLinearLayout.findViewById(R.id.my_text_view);
    genInitFields(r, fieldVarMap, viewVar, refs, body);

    // myButton.setOnClickListener((view) -> { if (_holderListener != null)
    // _holderListener.onMyButtonClick(myButton); });
    genListeners(r, fieldVarMap, holderListener, refs, body, listenerTypeMap);

    JDocComment doc = constructor.javadoc();
    doc.append(
        "Constructs a new {@link me.tatarka.holdr.Holdr} for {@link "
            + r.packageName
            + ".R.layout#"
            + r.layoutName
            + "}.");
    doc.addParam(viewVar).append("The root view to search for the holdr's views.");
  }
Beispiel #2
0
  private void addHashCode(JDefinedClass jclass) {
    Map<String, JFieldVar> fields = jclass.fields();
    if (fields.isEmpty()) {
      return;
    }

    JMethod hashCode = jclass.method(JMod.PUBLIC, int.class, "hashCode");

    Class<?> hashCodeBuilder =
        ruleFactory.getGenerationConfig().isUseCommonsLang3()
            ? org.apache.commons.lang3.builder.HashCodeBuilder.class
            : org.apache.commons.lang.builder.HashCodeBuilder.class;

    JBlock body = hashCode.body();
    JClass hashCodeBuilderClass = jclass.owner().ref(hashCodeBuilder);
    JInvocation hashCodeBuilderInvocation = JExpr._new(hashCodeBuilderClass);

    if (!jclass._extends().name().equals("Object")) {
      hashCodeBuilderInvocation =
          hashCodeBuilderInvocation.invoke("appendSuper").arg(JExpr._super().invoke("hashCode"));
    }

    for (JFieldVar fieldVar : fields.values()) {
      hashCodeBuilderInvocation = hashCodeBuilderInvocation.invoke("append").arg(fieldVar);
    }

    body._return(hashCodeBuilderInvocation.invoke("toHashCode"));

    hashCode.annotate(Override.class);
  }
  private void addActionToIntentBuilder(
      EIntentServiceHolder holder,
      ExecutableElement executableElement,
      String methodName,
      JFieldVar actionKeyField) {
    JMethod method =
        holder.getIntentBuilderClass().method(PUBLIC, holder.getIntentBuilderClass(), methodName);
    JBlock body = method.body();

    // setAction
    body.invoke("action").arg(actionKeyField);

    // For each method params, we get put value into extras
    List<? extends VariableElement> methodParameters = executableElement.getParameters();
    if (methodParameters.size() > 0) {

      // Extras params
      for (VariableElement param : methodParameters) {
        String paramName = param.getSimpleName().toString();
        JClass parameterClass = codeModelHelper.typeMirrorToJClass(param.asType(), holder);

        JFieldVar paramVar = getStaticExtraField(holder, paramName);
        JVar methodParam = method.param(parameterClass, paramName);

        JMethod putExtraMethod =
            holder.getIntentBuilder().getPutExtraMethod(param.asType(), paramName, paramVar);
        body.invoke(putExtraMethod).arg(methodParam);
      }
    }
    body._return(JExpr._this());
  }
Beispiel #4
0
  @Override
  public void generate(JDefinedClass cls, GenerationContext context) {
    if (classSpec.getFields().isEmpty()) {
      return; // No equals needed.
    }

    // Import the objects class, for hash coding.
    JClass objects = context.getTypeManager().getClassDirect("java.util.Objects");

    // Create the equals method.
    JMethod hashMethod = cls.method(JMod.PUBLIC, int.class, "hashCode");
    hashMethod.annotate(Override.class);
    JBlock body = hashMethod.body();

    // Check if the object is null.
    JVar hash = body.decl(JType.parse(context.getCodeModel(), "int"), "hash", JExpr.lit(3));

    // Do check for each field.
    for (DataFieldSpecification fieldSpec : classSpec.getFields()) {
      List<String> parts = NameFormat.namesToList(fieldSpec.getFieldName());
      String camelCaseFieldName = NameFormat.camelCase(parts, false);
      // Get the field value.
      JExpression thisField = JExpr.refthis(camelCaseFieldName);
      // Accumulate the hash code.
      JExpression fieldHashCode = objects.staticInvoke("hashCode").arg(thisField);

      body.assign(hash, JExpr.lit(79).mul(hash).plus(fieldHashCode));
    }

    // Return the processed hash value.
    body._return(hash);
  }
  private void createConstructorAndBuilder() {
    List<ExecutableElement> constructors = new ArrayList<ExecutableElement>();
    for (Element e : annotatedElement.getEnclosedElements()) {
      if (e.getKind() == CONSTRUCTOR) {
        constructors.add((ExecutableElement) e);
      }
    }

    for (ExecutableElement userConstructor : constructors) {
      JMethod copyConstructor = generatedClass.constructor(PUBLIC);
      JMethod staticHelper =
          generatedClass.method(PUBLIC | STATIC, generatedClass._extends(), "build");

      codeModelHelper.generifyStaticHelper(this, staticHelper, getAnnotatedElement());

      JBlock body = copyConstructor.body();
      JInvocation superCall = body.invoke("super");
      JInvocation newInvocation = JExpr._new(generatedClass);
      for (VariableElement param : userConstructor.getParameters()) {
        String paramName = param.getSimpleName().toString();
        JClass paramType = codeModelHelper.typeMirrorToJClass(param.asType(), this);
        copyConstructor.param(paramType, paramName);
        staticHelper.param(paramType, paramName);
        superCall.arg(JExpr.ref(paramName));
        newInvocation.arg(JExpr.ref(paramName));
      }

      JVar newCall = staticHelper.body().decl(generatedClass, "instance", newInvocation);
      staticHelper.body().invoke(newCall, getOnFinishInflate());
      staticHelper.body()._return(newCall);
      body.invoke(getInit());
    }
  }
Beispiel #6
0
  private void addConstructors(JDefinedClass jclass, List<String> properties) {

    // no properties to put in the constructor => default constructor is good enough.
    if (properties.isEmpty()) {
      return;
    }

    // add a no-args constructor for serialization purposes
    JMethod noargsConstructor = jclass.constructor(JMod.PUBLIC);
    noargsConstructor.javadoc().add("No args constructor for use in serialization");

    // add the public constructor with property parameters
    JMethod fieldsConstructor = jclass.constructor(JMod.PUBLIC);
    JBlock constructorBody = fieldsConstructor.body();

    Map<String, JFieldVar> fields = jclass.fields();

    for (String property : properties) {
      JFieldVar field = fields.get(property);

      if (field == null) {
        throw new IllegalStateException(
            "Property "
                + property
                + " hasn't been added to JDefinedClass before calling addConstructors");
      }

      fieldsConstructor.javadoc().addParam(property);
      JVar param = fieldsConstructor.param(field.type(), field.name());
      constructorBody.assign(JExpr._this().ref(field), param);
    }
  }
Beispiel #7
0
  private void getter(JDefinedClass clazz, JFieldVar field, String fieldName, String remarks) {
    // getter
    JMethod getter = clazz.method(JMod.PUBLIC, field.type(), "get" + fieldName);

    /* Addign java doc for method */
    JDocComment jDoc = addMethodDoc(getter, remarks + "取得");
    JCommentPart rtn = jDoc.addReturn();
    rtn.add(remarks);

    JBlock block = getter.body();
    block._return(field);
  }
  protected void setOnFinishInflate() {
    onFinishInflate = generatedClass.method(PUBLIC, codeModel().VOID, "onFinishInflate");
    onFinishInflate.annotate(Override.class);
    onFinishInflate.javadoc().append(ALREADY_INFLATED_COMMENT);

    JBlock ifNotInflated = onFinishInflate.body()._if(getAlreadyInflated().not())._then();
    ifNotInflated.assign(getAlreadyInflated(), JExpr.TRUE);

    getInit();
    viewNotifierHelper.invokeViewChanged(ifNotInflated);

    onFinishInflate.body().invoke(JExpr._super(), "onFinishInflate");
  }
Beispiel #9
0
 private void genInitFields(
     Refs r, Map<Ref, JFieldVar> fieldVarMap, JVar viewVar, Collection<Ref> refs, JBlock body) {
   for (Ref ref : refs) {
     JFieldVar fieldVar = fieldVarMap.get(ref);
     JFieldRef idVar = (ref.isAndroidId ? r.androidRClass : r.rClass).staticRef("id").ref(ref.id);
     if (ref instanceof View) {
       JClass viewType = r.ref(((View) ref).type);
       body.assign(fieldVar, cast(viewType, viewVar.invoke("findViewById").arg(idVar)));
     } else if (ref instanceof Include) {
       JClass includeType = r.ref(getClassName(((Include) ref).layout));
       body.assign(fieldVar, _new(includeType).arg(viewVar));
     }
   }
 }
 private JMethod addIterableWither(
     Filter filter, JDefinedClass bldrCls, JVar paramBuilder, JFieldVar field, JClass paramType)
     throws JClassAlreadyExistsException {
   JMethod method = createWitherMethod(filter, bldrCls);
   if (filter.getTitle() != null) {
     method.javadoc().add(String.format("<p>%s</p>", filter.getTitle()));
   }
   JVar param = addParam(filter, method, iterable(paramType));
   JBlock mthdBody = method.body();
   mthdBody.add(
       paramBuilder.invoke("put").arg(field).arg(immutableList.staticInvoke("copyOf").arg(param)));
   mthdBody._return(JExpr._this());
   return method;
 }
 public void run(Set<ClassOutline> sorted, JDefinedClass transformer) {
   for (ClassOutline classOutline : sorted) {
     // skip over abstract classes
     if (!classOutline.target.isAbstract()) {
       // add the accept method to the bean
       JDefinedClass beanImpl = classOutline.implClass;
       JMethod acceptMethod = beanImpl.method(JMod.PUBLIC, Object.class, "accept");
       JTypeVar genericType = acceptMethod.generify("T");
       acceptMethod.type(genericType);
       JVar vizParam = acceptMethod.param(transformer.narrow(genericType), "aTransformer");
       JBlock block = acceptMethod.body();
       block._return(vizParam.invoke("transform").arg(JExpr._this()));
     }
   }
 }
Beispiel #12
0
  @SuppressWarnings("deprecation")
  protected void generateOperationMethod(
      JDefinedClass serviceCls,
      String operationName,
      List<ElementType> inputTypes,
      Integer overloadCount)
      throws GenerationException {

    ElementType outputType1 = this.serviceDefinition.getOutputType(operationName);
    ElementType outputType = getAdjustedOutputType(outputType1);

    JType outputJType = getAdjustedJType(outputType);

    Map<String, JType> inputJTypeMap = new LinkedHashMap<String, JType>();
    JMethod method = serviceCls.method(JMod.PUBLIC, outputJType, operationName);
    for (ElementType inputType : inputTypes) {
      JType paramJType = getJType(inputType);
      String paramName = inputType.getName();
      method.param(paramJType, paramName);
      inputJTypeMap.put(paramName, paramJType);
    }

    addAdditionalInputParams(method, operationName);

    JBlock body = method.body();

    JTryBlock tryBlock = null;

    if (this.useNDCLogging) {
      tryBlock = body._try();
      body = tryBlock.body();
      body.staticInvoke(this.codeModel.ref(NDC.class), NDC_PUSH)
          .arg(getClassName() + "." + operationName);
    }

    generateOperationMethodBody(
        method,
        body,
        operationName,
        inputJTypeMap,
        outputType,
        outputJType,
        overloadCount); // salesforce

    if (this.useNDCLogging) {
      tryBlock._finally().block().staticInvoke(this.codeModel.ref(NDC.class), NDC_POP);
    }
  }
  /**
   * Add the pre-check to see if we are already in the UI thread.
   *
   * @param delegatingMethod
   * @param holder
   * @throws JClassAlreadyExistsException
   */
  private void addUIThreadCheck(
      JMethod delegatingMethod, JBlock previousBody, EComponentHolder holder)
      throws JClassAlreadyExistsException {
    // Get the Thread and Looper class.
    JClass tClass = holder.classes().THREAD;
    JClass lClass = holder.classes().LOOPER;

    // invoke the methods.
    JExpression lhs = tClass.staticInvoke(METHOD_CUR_THREAD);
    JExpression rhs = lClass.staticInvoke(METHOD_MAIN_LOOPER).invoke(METHOD_GET_THREAD);

    // create the conditional and the block.
    JConditional con = delegatingMethod.body()._if(JOp.eq(lhs, rhs));
    JBlock thenBlock = con._then().add(previousBody);
    thenBlock._return();
  }
Beispiel #14
0
  private void setter(
      JCodeModel codeModel,
      JDefinedClass clazz,
      JFieldVar field,
      String fieldName,
      String remarks) {
    // setter
    JMethod setter = clazz.method(JMod.PUBLIC, codeModel.VOID, "set" + fieldName);
    JVar param = setter.param(field.type(), toFirstCharLower(fieldName)); // メソッド引数

    /* Addign java doc for method */
    addMethodDoc(setter, remarks + "設定", param);

    JBlock block2 = setter.body();
    block2.assign(JExpr._this().ref(field), param); // ローカル変数からインスタンス変数へセット
  }
Beispiel #15
0
  private void addToString(JDefinedClass jclass) {
    JMethod toString = jclass.method(JMod.PUBLIC, String.class, "toString");

    Class<?> toStringBuilder =
        ruleFactory.getGenerationConfig().isUseCommonsLang3()
            ? org.apache.commons.lang3.builder.ToStringBuilder.class
            : org.apache.commons.lang.builder.ToStringBuilder.class;

    JBlock body = toString.body();
    JInvocation reflectionToString =
        jclass.owner().ref(toStringBuilder).staticInvoke("reflectionToString");
    reflectionToString.arg(JExpr._this());
    body._return(reflectionToString);

    toString.annotate(Override.class);
  }
  private JDefinedClass addBuilderCls(Feed feed, JDefinedClass cls)
      throws JClassAlreadyExistsException, ClassNotFoundException {
    JDefinedClass bldrCls = cls._class(JMod.PUBLIC | JMod.STATIC | JMod.FINAL, "Builder");
    JVar paramBuilder =
        bldrCls
            .field(JMod.PRIVATE | JMod.FINAL, immutableMapBldr, "params")
            .init(immutableMap.staticInvoke("builder"));

    for (Filter filter : feed.getFilters().getFilter()) {
      if (!Boolean.TRUE.equals(filter.isDeprecated())) {
        addWithersFor(filter, bldrCls, paramBuilder);
      }
    }

    if (feed.getMixins() != null && feed.getMixins().getMixin() != null) {
      JDefinedClass mixinEnum = getMixinEnum(feed);
      for (Mixin mixin : feed.getMixins().getMixin()) {
        String mixinName = mixin.getName().toUpperCase().replace(' ', '_');
        JEnumConstant mixinCnst = mixinEnum.enumConstant(mixinName);
        mixinCnst.arg(JExpr.lit(mixin.getName().replace(' ', '+')));
      }
      JFieldVar field = cls.field(privateStaticFinal, String.class, "MIXIN");
      field.init(JExpr.lit("mixin"));
      JMethod iterWither = bldrCls.method(JMod.PUBLIC, bldrCls, "withMixins");
      JVar param = iterWither.param(iterable(mixinEnum), "mixins");
      JBlock mthdBody = iterWither.body();
      mthdBody.add(
          paramBuilder
              .invoke("put")
              .arg(field)
              .arg(immutableList.staticInvoke("copyOf").arg(param)));
      mthdBody._return(JExpr._this());
      JMethod varArgWither = bldrCls.method(JMod.PUBLIC, bldrCls, "withMixins");
      param = varArgWither.varParam(mixinEnum, "mixins");
      varArgWither
          .body()
          ._return(JExpr.invoke(iterWither).arg(immutableList.staticInvoke("copyOf").arg(param)));
    }

    JMethod bldMthd = bldrCls.method(JMod.PUBLIC, cls, "build");
    bldMthd.body()._return(JExpr._new(cls).arg(paramBuilder.invoke("build")));

    // TODO: add sorts
    return bldrCls;
  }
Beispiel #17
0
  private void genListeners(
      Refs r,
      Map<Ref, JFieldVar> fieldVarMap,
      JFieldVar holdrListener,
      Collection<Ref> refs,
      JBlock body,
      Map<Listener.Type, ListenerType> listenerTypeMap) {
    if (holdrListener == null) return;

    for (Ref ref : refs) {
      if (ref instanceof View) {
        JFieldVar fieldVar = fieldVarMap.get(ref);
        View view = (View) ref;

        if (view.isNullable) {
          body = body._if(fieldVar.ne(_null()))._then();
        }

        for (Listener listener : view.listeners) {
          ListenerType listenerType = listenerTypeMap.get(listener.type);

          JDefinedClass listenerClass = r.m.anonymousClass(listenerType.classType);

          JMethod method =
              listenerClass.method(PUBLIC, listenerType.methodReturn, listenerType.methodName);

          List<JVar> params = new ArrayList<JVar>();
          for (Pair<JType, String> arg : listenerType.methodParams) {
            JVar param = method.param(arg.first, arg.second);
            params.add(arg.second.equals("view") ? fieldVar : param);
          }

          method.annotate(r.overrideAnnotation);
          JBlock innerBody = method.body();
          JBlock innerIf = innerBody._if(holdrListener.ne(_null()))._then();

          JInvocation invokeHoldrListener;
          if (listenerType.defaultReturn == null) {
            invokeHoldrListener = innerIf.invoke(holdrListener, listener.name);
          } else {
            invokeHoldrListener = holdrListener.invoke(listener.name);
            innerIf._return(invokeHoldrListener);
            innerBody._return(listenerType.defaultReturn);
          }

          for (JVar param : params) {
            invokeHoldrListener.arg(param);
          }

          body.invoke(fieldVar, listenerType.setter).arg(_new(listenerClass));
        }
      }
    }
  }
Beispiel #18
0
  private void addEquals(JDefinedClass jclass) {
    Map<String, JFieldVar> fields = jclass.fields();
    if (fields.isEmpty()) {
      return;
    }

    JMethod equals = jclass.method(JMod.PUBLIC, boolean.class, "equals");
    JVar otherObject = equals.param(Object.class, "other");

    Class<?> equalsBuilder =
        ruleFactory.getGenerationConfig().isUseCommonsLang3()
            ? org.apache.commons.lang3.builder.EqualsBuilder.class
            : org.apache.commons.lang.builder.EqualsBuilder.class;

    JBlock body = equals.body();

    body._if(otherObject.eq(JExpr._this()))._then()._return(JExpr.TRUE);
    body._if(otherObject._instanceof(jclass).eq(JExpr.FALSE))._then()._return(JExpr.FALSE);

    JVar rhsVar = body.decl(jclass, "rhs").init(JExpr.cast(jclass, otherObject));
    JClass equalsBuilderClass = jclass.owner().ref(equalsBuilder);
    JInvocation equalsBuilderInvocation = JExpr._new(equalsBuilderClass);

    if (!jclass._extends().name().equals("Object")) {
      equalsBuilderInvocation =
          equalsBuilderInvocation
              .invoke("appendSuper")
              .arg(JExpr._super().invoke("equals").arg(otherObject));
    }

    for (JFieldVar fieldVar : fields.values()) {
      equalsBuilderInvocation =
          equalsBuilderInvocation.invoke("append").arg(fieldVar).arg(rhsVar.ref(fieldVar.name()));
    }

    JInvocation reflectionEquals =
        jclass.owner().ref(equalsBuilder).staticInvoke("reflectionEquals");
    reflectionEquals.arg(JExpr._this());
    reflectionEquals.arg(otherObject);

    body._return(equalsBuilderInvocation.invoke("isEquals"));

    equals.annotate(Override.class);
  }
  @Override
  public void generate(ASTType descriptor) {

    if (descriptor.isConcreteClass()) {
      throw new TransfuseAnalysisException("Unable to build injector from concrete class");
    }

    try {
      JDefinedClass implClass =
          codeModel._class(JMod.PUBLIC, descriptor.getName() + IMPL_EXT, ClassType.CLASS);
      JClass interfaceClass = codeModel.ref(descriptor.getName());

      implClass._implements(interfaceClass);

      for (ASTMethod interfaceMethod : descriptor.getMethods()) {
        MirroredMethodGenerator mirroredMethodGenerator =
            componentBuilderFactory.buildMirroredMethodGenerator(interfaceMethod, false);
        MethodDescriptor methodDescriptor = mirroredMethodGenerator.buildMethod(implClass);
        JBlock block = methodDescriptor.getMethod().body();

        AnalysisContext context =
            analysisContextFactory.buildAnalysisContext(injectionNodeBuilderRepository);
        InjectionNodeFactory injectionNodeFactory =
            componentBuilderFactory.buildInjectionNodeFactory(
                interfaceMethod.getReturnType(), context);

        // Injections
        InjectionNode returnType = injectionNodeFactory.buildInjectionNode(methodDescriptor);
        Map<InjectionNode, TypedExpression> expressionMap =
            injectionFragmentGenerator.buildFragment(block, implClass, returnType);

        block._return(expressionMap.get(returnType).getExpression());
      }

      injectorRepositoryGenerator.generateInjectorRepository(interfaceClass, implClass);

    } catch (JClassAlreadyExistsException e) {
      throw new TransfuseAnalysisException(
          "Class already exists for generated type " + descriptor.getName(), e);
    } catch (ClassNotFoundException e) {
      throw new TransfuseAnalysisException("Target class not found", e);
    }
  }
  @Override
  public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
    Classes classes = holder.classes();

    String fieldName = element.getSimpleName().toString();

    Res resInnerClass = androidValue.getRInnerClass();

    JFieldRef idRef =
        annotationHelper.extractOneAnnotationFieldRef(holder, element, resInnerClass, true);

    JBlock methodBody = holder.init.body();

    TypeMirror fieldTypeMirror = element.asType();
    String fieldType = fieldTypeMirror.toString();

    // Special case for loading animations
    if (CanonicalNameConstants.ANIMATION.equals(fieldType)) {
      methodBody.assign(
          ref(fieldName),
          classes.ANIMATION_UTILS.staticInvoke("loadAnimation").arg(holder.contextRef).arg(idRef));
    } else {
      if (holder.resources == null) {
        holder.resources =
            methodBody.decl(
                classes.RESOURCES, "resources_", holder.contextRef.invoke("getResources"));
      }

      String resourceMethodName = androidValue.getResourceMethodName();

      // Special case for @HtmlRes
      if (element.getAnnotation(HtmlRes.class) != null) {
        methodBody.assign(
            ref(fieldName),
            classes
                .HTML
                .staticInvoke("fromHtml")
                .arg(invoke(holder.resources, resourceMethodName).arg(idRef)));
      } else {
        methodBody.assign(ref(fieldName), invoke(holder.resources, resourceMethodName).arg(idRef));
      }
    }
  }
  private void convertArguments(JBlock parent, VarArgParser parser) {
    int index = 0;
    for (VarArgParser.PositionalArg posArg : parser.getPositionalArguments()) {
      parent.assign(
          posArg.getVariable(), convert(posArg.getFormal(), args.component(lit(index++))));
    }

    JForLoop forLoop = parent._for();
    JVar loopCounter =
        forLoop.init(codeModel._ref(int.class), "i", lit(parser.getPositionalArguments().size()));
    forLoop.test(loopCounter.lt(JExpr.direct("args.length")));
    forLoop.update(loopCounter.incr());

    forLoop
        .body()
        .invoke(parser.getVarArgBuilder(), "add")
        .arg(argNames.component(loopCounter))
        .arg(args.component(loopCounter));
  }
  private static void processToString(JDefinedClass packetClass, JCodeModel codeModel) {
    JClass string = codeModel.ref(String.class);
    JClass stringBuilder = codeModel.ref(StringBuilder.class);
    JClass arrays = codeModel.ref(Arrays.class);

    JMethod toStringMeth = packetClass.method(JMod.PUBLIC, String.class, "toString");
    toStringMeth.annotate(Override.class);
    JBlock body = toStringMeth.body();

    JVar stringBuilderVar = body.decl(stringBuilder, "sb");
    stringBuilderVar =
        stringBuilderVar.init(JExpr._new(stringBuilder).arg(packetClass.name() + "["));

    JInvocation appendChain = null;

    for (JFieldVar fieldVar : packetClass.fields().values()) {
      if (appendChain != null) {
        // a comma is needed
        appendChain = appendChain.invoke("append").arg("," + fieldVar.name() + "=");
      } else {
        appendChain = stringBuilderVar.invoke("append").arg(fieldVar.name() + "=");
      }

      // now add the field to the toString output
      JExpression expression =
          fieldVar.type().isArray()
              ? arrays.staticInvoke("toString").arg(JExpr._this().ref(fieldVar.name()))
              : fieldVar.type().isReference()
                  ? JExpr._this().ref(fieldVar.name()).invoke("toString")
                  : JExpr._this().ref(fieldVar.name());

      appendChain = appendChain.invoke("append").arg(expression);
    }

    if (appendChain != null) {
      appendChain = appendChain.invoke("append").arg("]");
    } else {
      appendChain = stringBuilderVar.invoke("append").arg("]");
    }

    body.add(appendChain);
    body._return(stringBuilderVar.invoke("toString"));
  }
  private void addActionInOnHandleIntent(
      EIntentServiceHolder holder,
      ExecutableElement executableElement,
      String methodName,
      JFieldVar actionKeyField) {
    // If action match, call the method
    JInvocation actionCondition =
        actionKeyField.invoke("equals").arg(holder.getOnHandleIntentIntentAction());
    JBlock callActionBlock = holder.getOnHandleIntentBody()._if(actionCondition)._then();
    JInvocation callActionInvocation = JExpr._super().invoke(methodName);

    // For each method params, we get back value from extras and put it
    // in super calls
    List<? extends VariableElement> methodParameters = executableElement.getParameters();
    if (methodParameters.size() > 0) {
      // Extras
      JVar extras = callActionBlock.decl(classes().BUNDLE, "extras");
      extras.init(holder.getOnHandleIntentIntent().invoke("getExtras"));
      JBlock extrasNotNullBlock = callActionBlock._if(extras.ne(_null()))._then();

      // Extras params
      for (VariableElement param : methodParameters) {
        String paramName = param.getSimpleName().toString();
        String extraParamName = paramName + "Extra";
        JFieldVar paramVar = getStaticExtraField(holder, paramName);
        JClass extraParamClass = codeModelHelper.typeMirrorToJClass(param.asType(), holder);
        BundleHelper bundleHelper = new BundleHelper(annotationHelper, param);

        JExpression getExtraExpression =
            JExpr.invoke(extras, bundleHelper.getMethodNameToRestore()).arg(paramVar);
        if (bundleHelper.restoreCallNeedCastStatement()) {
          getExtraExpression = JExpr.cast(extraParamClass, getExtraExpression);

          if (bundleHelper.restoreCallNeedsSuppressWarning()) {
            JMethod onHandleIntentMethod = holder.getOnHandleIntentMethod();
            if (onHandleIntentMethod.annotations().size() == 0) {
              onHandleIntentMethod.annotate(SuppressWarnings.class).param("value", "unchecked");
            }
          }
        }

        JVar extraField =
            extrasNotNullBlock.decl(extraParamClass, extraParamName, getExtraExpression);
        callActionInvocation.arg(extraField);
      }
      extrasNotNullBlock.add(callActionInvocation);
    } else {
      callActionBlock.add(callActionInvocation);
    }
    callActionBlock._return();
  }
  @Override
  public void process(Element element, HasInstanceState holder) {
    String fieldName = element.getSimpleName().toString();

    JBlock saveStateBody = holder.getSaveStateMethodBody();
    JVar saveStateBundleParam = holder.getSaveStateBundleParam();
    JMethod restoreStateMethod = holder.getRestoreStateMethod();
    JBlock restoreStateBody = restoreStateMethod.body();
    JVar restoreStateBundleParam = holder.getRestoreStateBundleParam();

    AnnotationHelper annotationHelper = new AnnotationHelper(processingEnv);
    BundleHelper bundleHelper = new BundleHelper(annotationHelper, element);
    APTCodeModelHelper codeModelHelper = new APTCodeModelHelper();

    JFieldRef ref = ref(fieldName);
    saveStateBody
        .invoke(saveStateBundleParam, bundleHelper.getMethodNameToSave())
        .arg(fieldName)
        .arg(ref);

    JInvocation restoreMethodCall =
        JExpr.invoke(restoreStateBundleParam, bundleHelper.getMethodNameToRestore()).arg(fieldName);
    if (bundleHelper.restoreCallNeedCastStatement()) {

      JClass jclass = codeModelHelper.typeMirrorToJClass(element.asType(), holder);
      JExpression castStatement = JExpr.cast(jclass, restoreMethodCall);
      restoreStateBody.assign(ref, castStatement);

      if (bundleHelper.restoreCallNeedsSuppressWarning()) {
        if (restoreStateMethod.annotations().size() == 0) {
          restoreStateMethod.annotate(SuppressWarnings.class).param("value", "unchecked");
        }
      }

    } else {
      restoreStateBody.assign(ref, restoreMethodCall);
    }
  }
  protected HoldingContainer generateEvalBody(
      ClassGenerator<?> g, HoldingContainer[] inputVariables, String body, JVar[] workspaceJVars) {

    // g.getBlock().directStatement(String.format("//---- start of eval portion of %s function.
    // ----//", functionName));

    JBlock sub = new JBlock(true, true);
    JBlock topSub = sub;
    HoldingContainer out = null;
    MajorType returnValueType = returnValue.type;

    // add outside null handling if it is defined.
    if (nullHandling == NullHandling.NULL_IF_NULL) {
      JExpression e = null;
      for (HoldingContainer v : inputVariables) {
        if (v.isOptional()) {
          if (e == null) {
            e = v.getIsSet();
          } else {
            e = e.mul(v.getIsSet());
          }
        }
      }

      if (e != null) {
        // if at least one expression must be checked, set up the conditional.
        returnValueType = returnValue.type.toBuilder().setMode(DataMode.OPTIONAL).build();
        out = g.declare(returnValueType);
        e = e.eq(JExpr.lit(0));
        JConditional jc = sub._if(e);
        jc._then().assign(out.getIsSet(), JExpr.lit(0));
        sub = jc._else();
      }
    }

    if (out == null) out = g.declare(returnValueType);

    // add the subblock after the out declaration.
    g.getEvalBlock().add(topSub);

    JVar internalOutput =
        sub.decl(
            JMod.FINAL,
            g.getHolderType(returnValueType),
            returnValue.name,
            JExpr._new(g.getHolderType(returnValueType)));
    addProtectedBlock(g, sub, body, inputVariables, workspaceJVars, false);
    if (sub != topSub)
      sub.assign(internalOutput.ref("isSet"), JExpr.lit(1)); // Assign null if NULL_IF_NULL mode
    sub.assign(out.getHolder(), internalOutput);
    if (sub != topSub)
      sub.assign(internalOutput.ref("isSet"), JExpr.lit(1)); // Assign null if NULL_IF_NULL mode
    return out;
  }
  @Override
  public void buildLayoutCall(JDefinedClass definedClass, JBlock block) {

    try {
      Map<InjectionNode, TypedExpression> expressionMap =
          injectionFragmentGenerator.buildFragment(block, definedClass, layoutHandlerInjectionNode);

      // LayoutHandlerDelegate.invokeLayout()
      JExpression layoutHandlerDelegate =
          expressionMap.get(layoutHandlerInjectionNode).getExpression();

      block.add(layoutHandlerDelegate.invoke(LayoutHandlerDelegate.INVOKE_LAYOUT_METHOD));

    } catch (ClassNotFoundException e) {
      logger.error("ClassNotFoundException while trying to generate LayoutHandler", e);
    } catch (JClassAlreadyExistsException e) {
      logger.error("JClassAlreadyExistsException while trying to generate LayoutHandler", e);
    }
  }
 private void addWither(
     Filter filter, JDefinedClass bldrCls, JVar paramBuilder, JFieldVar field, JClass paramType)
     throws JClassAlreadyExistsException {
   JMethod method = createWitherMethod(filter, bldrCls);
   if (filter.getTitle() != null) {
     method.javadoc().add(String.format("<p>%s</p>", filter.getTitle()));
   }
   JVar param = addParam(filter, method, paramType);
   JBlock mthdBody = method.body();
   boolean needsNullCheck = true;
   if (filter.getMinValue() != null) {
     mthdBody.add(precs.staticInvoke("checkNotNull").arg(param));
     needsNullCheck = false;
     int min = filter.getMinValue().intValue();
     mthdBody.add(
         precs
             .staticInvoke("checkArgument")
             .arg(JExpr.lit(min).lte(param))
             .arg(JExpr.lit(param.name() + ": %s < " + min))
             .arg(param));
   }
   if (filter.getMaxValue() != null) {
     if (needsNullCheck) {
       mthdBody.add(precs.staticInvoke("checkNotNull").arg(param));
       needsNullCheck = false;
     }
     int max = filter.getMaxValue().intValue();
     mthdBody.add(
         precs
             .staticInvoke("checkArgument")
             .arg(JExpr.lit(max).gte(param))
             .arg(JExpr.lit(param.name() + ": %s > " + max))
             .arg(param));
   }
   JInvocation putIntoMap = paramBuilder.invoke("put").arg(field);
   if (needsNullCheck) {
     putIntoMap.arg(precs.staticInvoke("checkNotNull").arg(param));
   } else {
     putIntoMap.arg(param);
   }
   mthdBody.add(putIntoMap);
   mthdBody._return(JExpr._this());
 }
  private InjectionNode innerGenerateProxyCode(InjectionNode injectionNode) {
    AOPProxyAspect aopProxyAspect = injectionNode.getAspect(AOPProxyAspect.class);
    JDefinedClass definedClass;
    String proxyClassName = injectionNode.getClassName() + "_AOPProxy";
    ASTInjectionAspect injectionAspect = injectionNode.getAspect(ASTInjectionAspect.class);
    ConstructorInjectionPoint constructorInjectionPoint =
        injectionAspect.getConstructorInjectionPoint();
    ConstructorInjectionPoint proxyConstructorInjectionPoint =
        new ConstructorInjectionPoint(ASTAccessModifier.PUBLIC);

    try {

      definedClass = codeModel._class(JMod.PUBLIC, proxyClassName, ClassType.CLASS);

      annotateGeneratedClass(definedClass);

      // extending injectionNode
      definedClass._extends(codeModel.ref(injectionNode.getClassName()));

      // copy constructor elements and add aop interceptors
      JMethod constructor = definedClass.constructor(JMod.PUBLIC);

      // converting exceptions into runtime exceptions
      proxyConstructorInjectionPoint.addThrows(constructorInjectionPoint.getThrowsTypes());
      for (ASTType throwType : constructorInjectionPoint.getThrowsTypes()) {
        constructor._throws(codeModel.ref(throwType.getName()));
      }

      JBlock constructorBody = constructor.body();

      List<JVar> superArguments = new ArrayList<JVar>();
      for (InjectionNode node : constructorInjectionPoint.getInjectionNodes()) {
        String paramName = namer.generateName(node);
        JVar param = constructor.param(codeModel.ref(node.getClassName()), paramName);
        superArguments.add(param);
        proxyConstructorInjectionPoint.addInjectionNode(node);
      }

      // super construction
      JInvocation constructorInvocation = constructorBody.invoke(SUPER_REF);
      for (JVar paramArgument : superArguments) {
        constructorInvocation.arg(paramArgument);
      }

      // method interceptors
      Map<ASTMethod, Map<InjectionNode, JFieldVar>> interceptorFields =
          new HashMap<ASTMethod, Map<InjectionNode, JFieldVar>>();
      for (Map.Entry<ASTMethod, Set<InjectionNode>> methodInterceptorEntry :
          aopProxyAspect.getMethodInterceptors().entrySet()) {

        buildMethodInterceptor(
            definedClass,
            proxyConstructorInjectionPoint,
            constructor,
            constructorBody,
            interceptorFields,
            methodInterceptorEntry);
      }

    } catch (JClassAlreadyExistsException e) {
      logger.error("JClassAlreadyExistsException while building AOP Proxy", e);
    } catch (ClassNotFoundException e) {
      logger.error("ClassNotFoundException while building AOP Proxy", e);
    }

    return buildProxyInjectionNode(
        injectionNode, proxyClassName, injectionAspect, proxyConstructorInjectionPoint);
  }
  private JExpression buildInterceptorChain(
      JDefinedClass definedClass,
      ASTMethod method,
      Map<ASTParameter, JVar> parameterMap,
      Set<InjectionNode> interceptors,
      Map<InjectionNode, JFieldVar> interceptorNameMap) {

    try {
      JDefinedClass methodExecutionClass =
          definedClass._class(
              JMod.PRIVATE | JMod.FINAL,
              namer.generateClassName(MethodInterceptorChain.MethodExecution.class));
      methodExecutionClass._implements(MethodInterceptorChain.MethodExecution.class);

      // setup constructor with needed parameters
      JMethod constructor = methodExecutionClass.constructor(JMod.PUBLIC);
      JBlock constructorbody = constructor.body();
      List<JExpression> methodParameters = new ArrayList<JExpression>();
      for (ASTParameter parameter : method.getParameters()) {
        JType parameterType = parameterMap.get(parameter).type();
        JVar param = constructor.param(parameterType, namer.generateName(parameterType));
        JFieldVar field =
            methodExecutionClass.field(
                JMod.PRIVATE, parameterType, namer.generateName(parameterType));
        constructorbody.assign(field, param);
        methodParameters.add(field);
      }

      // getMethod()
      JMethod getMethod =
          methodExecutionClass.method(
              JMod.PUBLIC, Method.class, MethodInterceptorChain.MethodExecution.GET_METHOD);

      JInvocation getMethodInvocation =
          definedClass.dotclass().invoke(CLASS_GET_METHOD).arg(method.getName());
      getMethod.body()._return(getMethodInvocation);
      getMethod._throws(NoSuchMethodException.class);

      for (ASTParameter astParameter : method.getParameters()) {
        getMethodInvocation.arg(codeModel.ref(astParameter.getASTType().getName()).dotclass());
      }

      // invoke()
      JMethod invokeMethod =
          methodExecutionClass.method(
              JMod.PUBLIC, Object.class, MethodInterceptorChain.MethodExecution.INVOKE);

      // add all throws of contained method
      for (ASTType throwable : method.getThrowsTypes()) {
        invokeMethod._throws(codeModel.ref(throwable.getName()));
      }

      JInvocation superCall = definedClass.staticRef(SUPER_REF).invoke(method.getName());

      for (JExpression methodParam : methodParameters) {
        superCall.arg(methodParam);
      }

      if (method.getReturnType().equals(ASTVoidType.VOID)) {
        invokeMethod.body().add(superCall);
        invokeMethod.body()._return(JExpr._null());
      } else {
        invokeMethod.body()._return(superCall);
      }

      JInvocation methodExecutionInvocation = JExpr._new(methodExecutionClass);

      for (ASTParameter astParameter : method.getParameters()) {
        methodExecutionInvocation.arg(parameterMap.get(astParameter));
      }

      JInvocation newInterceptorInvocation =
          JExpr._new(codeModel.ref(MethodInterceptorChain.class))
              .arg(methodExecutionInvocation)
              .arg(JExpr._this());

      for (InjectionNode interceptor : interceptors) {
        newInterceptorInvocation.arg(interceptorNameMap.get(interceptor));
      }

      return newInterceptorInvocation;
    } catch (JClassAlreadyExistsException e) {
      throw new TransfuseAnalysisException("Class already defined while generating inner class", e);
    }
  }
  private void buildMethodInterceptor(
      JDefinedClass definedClass,
      ConstructorInjectionPoint proxyConstructorInjectionPoint,
      JMethod constructor,
      JBlock constructorBody,
      Map<ASTMethod, Map<InjectionNode, JFieldVar>> interceptorFields,
      Map.Entry<ASTMethod, Set<InjectionNode>> methodInterceptorEntry)
      throws ClassNotFoundException {
    ASTMethod method = methodInterceptorEntry.getKey();

    if (method.getAccessModifier().equals(ASTAccessModifier.PRIVATE)) {
      throw new TransfuseAnalysisException("Unable to provide AOP on private methods");
    }

    if (!interceptorFields.containsKey(methodInterceptorEntry.getKey())) {
      interceptorFields.put(
          methodInterceptorEntry.getKey(), new HashMap<InjectionNode, JFieldVar>());
    }
    Map<InjectionNode, JFieldVar> injectionNodeInstanceNameMap =
        interceptorFields.get(methodInterceptorEntry.getKey());

    // setup interceptor fields
    for (InjectionNode interceptorInjectionNode : methodInterceptorEntry.getValue()) {
      String interceptorInstanceName = namer.generateName(interceptorInjectionNode);

      JFieldVar interceptorField =
          definedClass.field(
              JMod.PRIVATE,
              codeModel.ref(interceptorInjectionNode.getClassName()),
              interceptorInstanceName);

      injectionNodeInstanceNameMap.put(interceptorInjectionNode, interceptorField);

      JVar interceptorParam =
          constructor.param(
              codeModel.ref(interceptorInjectionNode.getClassName()),
              namer.generateName(interceptorInjectionNode));

      constructorBody.assign(interceptorField, interceptorParam);

      proxyConstructorInjectionPoint.addInjectionNode(interceptorInjectionNode);
    }

    JType returnType = codeModel.parseType(method.getReturnType().getName());

    JMethod methodDeclaration =
        definedClass.method(
            method.getAccessModifier().getCodeModelJMod(), returnType, method.getName());
    JBlock body = methodDeclaration.body();

    // define method parameter
    Map<ASTParameter, JVar> parameterMap = new HashMap<ASTParameter, JVar>();
    for (ASTParameter parameter : method.getParameters()) {
      parameterMap.put(
          parameter,
          methodDeclaration.param(
              JMod.FINAL,
              codeModel.ref(parameter.getASTType().getName()),
              namer.generateName(parameter.getASTType())));
    }

    // aop interceptor
    Map<InjectionNode, JFieldVar> interceptorNameMap =
        interceptorFields.get(methodInterceptorEntry.getKey());

    JArray paramArray = JExpr.newArray(codeModel.ref(Object.class));

    for (ASTParameter astParameter : method.getParameters()) {
      paramArray.add(parameterMap.get(astParameter));
    }

    JInvocation interceptorInvocation =
        buildInterceptorChain(
                definedClass,
                method,
                parameterMap,
                methodInterceptorEntry.getValue(),
                interceptorNameMap)
            .invoke("invoke");
    interceptorInvocation.arg(paramArray);

    if (method.getReturnType().equals(ASTVoidType.VOID)) {
      body.add(interceptorInvocation);
    } else {
      body._return(JExpr.cast(returnType.boxify(), interceptorInvocation));
    }
  }