public void build() {
    declareMethod();

    ExceptionWrapper mainTryBlock = new ExceptionWrapper(codeModel, method.body(), context);
    for (Integer arity : primitive.getArity()) {
      JInvocation invocation = invoke("doApply").arg(context).arg(environment);

      for (int i = 0; i < arity; ++i) {
        invocation.arg(args.component(lit(i)));
      }
      mainTryBlock
          .body()
          ._if(JExpr.direct("args.length").eq(JExpr.lit(arity)))
          ._then()
          ._return(invocation);
    }

    mainTryBlock.catchEvalExceptions();
    mainTryBlock.catchRuntimeExceptions();
    mainTryBlock.catchExceptions();

    method
        .body()
        ._throw(
            JExpr._new(codeModel.ref(EvalException.class))
                .arg(lit(primitive.getName() + ": max arity is " + primitive.getMaxArity())));
  }
Esempio n. 2
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));
        }
      }
    }
  }
  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();
  }
  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"));
  }
  public void buildVarArgs() {
    declareMethod();

    ExceptionWrapper mainTryBlock = new ExceptionWrapper(codeModel, method.body(), context);

    JvmMethod overload = primitive.getOverloads().get(0);
    VarArgParser parser = new VarArgParser(this, mainTryBlock.body(), overload);

    // convert the positional arguments
    convertArguments(parser.getArgumentProcessingBlock(), parser);

    // finally invoke the underlying function
    JInvocation invocation =
        classRef(overload.getDeclaringClass()).staticInvoke(overload.getName());
    for (JExpression argument : parser.getArguments()) {
      invocation.arg(argument);
    }

    CodeModelUtils.returnSexp(codeModel, mainTryBlock.body(), overload, invocation);

    mainTryBlock.catchEvalExceptions();
    mainTryBlock.catchRuntimeExceptions();
    mainTryBlock.catchExceptions();
  }
Esempio n. 6
0
  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);
  }
Esempio n. 7
0
  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);
    }
  }
Esempio n. 8
0
  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));
    }
  }