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()))); }
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(); }
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(); }
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)); } }