Registers step definitions and hooks.

@param javaBackend   the backend where stepdefs and hooks will be registered.
@param method        a candidate for being a stepdef or hook.
@param glueCodeClass the class where the method is declared.
196690
public void scan(JavaBackend javaBackend, Method method, Class<?> glueCodeClass) {
        Annotation[] methodAnnotations = method.getAnnotations();
        for (Annotation annotation : methodAnnotations) {
            if (isHookAnnotation(annotation)) {
                validateMethod(method, glueCodeClass);
                javaBackend.addHook(annotation, method);
            } else if (isStepdefAnnotation(annotation)) {
                validateMethod(method, glueCodeClass);
                javaBackend.addStepDefinition(annotation, method);
            }
        }
    }
1067089
private void addProxyMethods(TypeSpec.Builder classBuilder, Element member, int methodIndex) {
        ExecutableElement executableElement = (ExecutableElement) member;
        String methodName = executableElement.getSimpleName().toString();
        boolean isOnewayAnnotated = member.getAnnotation(Oneway.class) != null;
        boolean isOneWay = executableElement.getReturnType().getKind() == TypeKind.VOID
                && isOnewayAnnotated;

        if (!isOneWay && isOnewayAnnotated) {
            logWarning("@Oneway is expected only for methods with void return. Ignoring it for " + member.getSimpleName());
        }


        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName)
                .addModifiers(Modifier.PUBLIC)
                .addAnnotation(Override.class)
                .returns(TypeName.get(executableElement.getReturnType()));

        //add Exceptions
        for (TypeMirror exceptions : executableElement.getThrownTypes()) {
            methodBuilder.addException(ClassName.bestGuess(exceptions.toString()));
        }

        //add parameters
        int paramIndex = 0;
        for (VariableElement params : executableElement.getParameters()) {
            methodBuilder.addParameter(TypeName.get(params.asType()), params.getSimpleName().toString() + "_" + paramIndex);
            paramIndex++;
        }

        methodBuilder
                .addStatement("__checkProxy()");
        //add statements
        methodBuilder
                .addStatement("android.os.Parcel data = android.os.Parcel.obtain()");

        if (!isOneWay) {
            methodBuilder.addStatement("android.os.Parcel reply = android.os.Parcel.obtain()");
        }

        //add return if any
        if (executableElement.getReturnType().getKind() != TypeKind.VOID) {
            TypeElement genericParceler = getBindingManager().getGenericType(executableElement.getReturnType());
            if (genericParceler != null) {
                methodBuilder.addStatement("$T<$T> result", List.class, genericParceler);
            } else {
                methodBuilder.addStatement(executableElement.getReturnType().toString() + " result");
            }
        }

        //start main body block
        methodBuilder.beginControlFlow("try");

        //write the descriptor
        methodBuilder.addStatement("data.writeInterfaceToken(DESCRIPTOR)");

        List<VariableElement> outParams = new ArrayList<>();

        //pass parameters
        paramIndex = 0;
        for (VariableElement param : executableElement.getParameters()) {
            ParamBuilder.ParamType paramType = param.getAnnotation(ParamIn.class) != null ? ParamBuilder.ParamType.IN
                    : param.getAnnotation(ParamOut.class) != null ? ParamBuilder.ParamType.OUT : ParamBuilder.ParamType.IN_OUT;

            VariableElement wrappedParam = new VariableElementWrapper(param, paramIndex);
            if (paramType != ParamBuilder.ParamType.IN) {
                outParams.add(wrappedParam);
            }
            ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(param.asType());
            if (paramBuilder != null) {
                paramBuilder.writeParamsToProxy(wrappedParam, paramType, methodBuilder);
            } else {
                logError("Parameter cannot be marshalled " + param.getSimpleName());
            }
            paramIndex ++;
        }

        //send remote command
        if (isOneWay) {
            methodBuilder.addStatement("mRemote.transact(TRANSACTION_" + methodName + "_" + methodIndex + ", data, null, android.os.IBinder.FLAG_ONEWAY)");
        } else {
            methodBuilder.addStatement("mRemote.transact(TRANSACTION_" + methodName + "_" + methodIndex + ", data, reply, 0)");
            //read exception if any
            methodBuilder.addStatement("Throwable exception = checkException(reply)");
            methodBuilder.beginControlFlow("if(exception != null)");

            for (TypeMirror exceptions : executableElement.getThrownTypes()) {
                ClassName exceptionCName = ClassName.bestGuess(exceptions.toString());
                methodBuilder.beginControlFlow("if(exception instanceof $T)", exceptionCName);
                methodBuilder.addStatement("throw ($T)exception", exceptionCName);
                methodBuilder.endControlFlow();
            }
            methodBuilder.addStatement("throw ($T)exception", RuntimeException.class);
            methodBuilder.endControlFlow();

            //read result
            if (executableElement.getReturnType().getKind() != TypeKind.VOID) {
                ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(executableElement.getReturnType());
                if (paramBuilder != null) {
                    paramBuilder.readResultsFromProxy(executableElement.getReturnType(), methodBuilder);
                } else {
                    logError("Unmarshellable return type " + executableElement.getReturnType());
                    methodBuilder.addStatement("result = null");
                }
            }

            for (VariableElement param : outParams) {
                ParamBuilder.ParamType paramType = param.getAnnotation(ParamIn.class) != null ? ParamBuilder.ParamType.IN
                        : param.getAnnotation(ParamOut.class) != null ? ParamBuilder.ParamType.OUT : ParamBuilder.ParamType.IN_OUT;
                ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(param.asType());
                if (paramBuilder != null) {
                    paramBuilder.readOutParamsFromProxy(param, paramType, methodBuilder);
                }
            }
        }

        //end of try
        methodBuilder.endControlFlow();


        //catch rethrow
        methodBuilder.beginControlFlow("catch ($T re)", ClassName.get("android.os", "RemoteException"));
        methodBuilder.addStatement("throw new $T(re)", RuntimeException.class);
        methodBuilder.endControlFlow();


        //finally block
        methodBuilder.beginControlFlow("finally");
        if (!isOneWay) {
            methodBuilder.addStatement("reply.recycle()");
        }
        methodBuilder.addStatement("data.recycle()");
        methodBuilder.endControlFlow();
        if (executableElement.getReturnType().getKind() != TypeKind.VOID) {
            methodBuilder.addStatement("return result");
        }

        classBuilder.addMethod(methodBuilder.build());
    }
908361
public void setMethod(String method) {
	method = method.toLowerCase();
	if (method.equals("loop")) this.method = MODE_LOOP;
	else if (method.equals("exittag")) this.method = MODE_EXIT_TAG;
	else if (method.equals("exittemplate")) this.method = MODE_EXIT_TEMPLATE;
    }
1058778
public void addMethodLine(String className, String methodName, String methodSignature, SourceLineRange range) {
        methodLineMap.put(new MethodDescriptor(className, methodName, methodSignature), range);
    }
1371370
protected void addConstructedGuardToMethodBody(final ClassMethod classMethod, String className) {
        if (!useConstructedFlag()) {
            return;
        }
        // now create the conditional
        final CodeAttribute cond = classMethod.getCodeAttribute();
        cond.aload(0);
        cond.getfield(classMethod.getClassFile().getName(), CONSTRUCTED_FLAG_NAME, BytecodeUtils.BOOLEAN_CLASS_DESCRIPTOR);

        // jump if the proxy constructor has finished
        BranchEnd jumpMarker = cond.ifne();
        // generate the invokespecial call to the super class method
        // this is run when the proxy is being constructed
        cond.aload(0);
        cond.loadMethodParameters();
        cond.invokespecial(className, classMethod.getName(), classMethod.getDescriptor());
        cond.returnInstruction();
        cond.branchEnd(jumpMarker);
    }
622159
@Override
   protected String resolveMethod(Method method)
   {
      final String fallBackName = convertToBeanName(method.getName()); 
      final String resourceName = method.getAnnotation(Resource.class).name();

      return getName(resourceName, fallBackName);
   }
591394
public static boolean checkMethodSignature(final Method method, final List<WaveItem<?>> wParams) {
        boolean isCompliant = false;

        final Type[] mParams = method.getGenericParameterTypes();

        if (wParams.isEmpty() && Wave.class.isAssignableFrom(ClassUtility.getClassFromType(mParams[0]))) {
            isCompliant = true;
        } else if (mParams.length - 1 == wParams.size()) {

            // Flag used to skip a method not compliant
            boolean skipMethod = false;
            // Check each parameter
            for (int i = 0; !skipMethod && i < mParams.length - 1 && !isCompliant; i++) {
                if (!ClassUtility.getClassFromType(mParams[i]).isAssignableFrom(ClassUtility.getClassFromType(wParams.get(i).type()))) {
                    // This method has not the right parameters
                    skipMethod = true;
                }
                if (i == mParams.length - 2
                        && Wave.class.isAssignableFrom(ClassUtility.getClassFromType(mParams[i + 1]))) {
                    // This method is compliant with wave type
                    isCompliant = true;
                }
            }
        }
        return isCompliant;
    }
68983
public final void entry(Class sourceClass, String methodName)
    {
        entry(null, sourceClass, methodName, (Object[]) null);
    }
252054
private void validateMethod(Method method, CallbackType callbackType) {
    int modifiers = method.getModifiers();
    if (!Modifier.isPublic(modifiers)) {
      String message = String.format("Method %s in class %s must be public", method.getName(),
          method.getDeclaringClass().getName());
      throw new EntityManagerException(message);
    }
    if (Modifier.isStatic(modifiers)) {
      String message = String.format("Method %s in class %s must not be static", method.getName(),
          method.getDeclaringClass().getName());
      throw new EntityManagerException(message);
    }
    if (Modifier.isAbstract(modifiers)) {
      String message = String.format("Method %s in class %s must not be abstract", method.getName(),
          method.getDeclaringClass().getName());
      throw new EntityManagerException(message);
    }
    Class<?>[] parameters = method.getParameterTypes();
    if (parameters.length != 0) {
      String pattern = "Method %s in class %s is not a valid %s callback method. Method must not "
          + "have any parameters. ";
      String message = String.format(pattern, method.getName(),
          method.getDeclaringClass().getName(), callbackType);
      throw new EntityManagerException(message);
    }
    if (method.getReturnType() != void.class) {
      String message = String.format("Method %s in class %s must have a return type of %s",
          method.getName(), method.getDeclaringClass().getName(), void.class.getName());
      throw new EntityManagerException(message);
    }
  }
1117426
public static MethodNode addGeneratedMethod(ClassNode cNode, String name,
                                int modifiers,
                                ClassNode returnType,
                                Parameter[] parameters,
                                ClassNode[] exceptions,
                                Statement code) {
        MethodNode result = cNode.addMethod(name, modifiers, returnType, parameters, exceptions, code);
        markAsGenerated(cNode, result);
        return result;
    }
653995
public static void addGeneratedMethod(ClassNode cNode, MethodNode mNode) {
        cNode.addMethod(mNode);
        markAsGenerated(cNode, mNode);
    }
954570
private void processMethods(Set<ExecutableElement> hookMethodsFromInterfaces) {
    List<ExecutableElement> templateMethods = ElementFilter
        .methodsIn(component.getEnclosedElements())
        .stream()
        .filter(ComponentGeneratorsUtil::isMethodVisibleInTemplate)
        .filter(method -> !isHookMethod(component, method, hookMethodsFromInterfaces))
        .collect(Collectors.toList());

    templateMethods.forEach(method -> {
      String methodName = method.getSimpleName().toString();
      String exposedMethodName = exposeExistingJavaMethodToJs(method);
      optionsBuilder.addStatement("options.addMethod($S, p.$L)", methodName, exposedMethodName);
    });
  }
187384
@SuppressWarnings("unchecked")
  private void registerVoidMethod(Class type, Method method) {
    executor.register(type, wrapVoidMethod(method));
  }
215249
private void validateExternalCallback(Method method, CallbackType callbackType) {
    Class<?>[] parameters = method.getParameterTypes();
    if (!parameters[0].isAssignableFrom(entityClass)) {
      String message = String.format("Method %s in class %s is not valid for entity %s",
          method.getName(), method.getDeclaringClass().getName(), entityClass.getName());
      throw new EntityManagerException(message);
    }
    CallbackMetadata callbackMetadata = new CallbackMetadata(EntityListenerType.EXTERNAL,
        callbackType, method);
    metadata.put(callbackType, callbackMetadata);
  }
1047684
private static void setAction(Method method, Object handlerBean) {
        Class<?>[] paramTypes = method.getParameterTypes();
        Class<?> returnType = method.getReturnType();
        Condition condition = Condition.newInstance(paramTypes[0], returnType);

        Handler existHandler = ACTION_MAP.get(condition);
        if (Objects.nonNull(existHandler)) {
            String message = "\n{method：" + method.getDeclaringClass().getName() + "." + method.getName()
                    + "}\n{method：" + existHandler.getMethod().getDeclaringClass().getName() + "."
                    + existHandler.getMethod().getName() + "} convert source and target is the same ";
            throw NonUniqueConverterException.of(message);
        }

        log.info("Mapped \"{sourceClass = {},targetClass = {}}\" onto {}", condition.getSourceClass(), returnType,
                method);
        Handler handler = Handler.newInstance(handlerBean, method);
        ACTION_MAP.put(condition, handler);
    }
1258780
int resolveMethodIndex(ExecutableElement method)
    {
         int size = 0;
        int index = 0;
        constantReadLock.lock();
        TypeElement declaringClass = (TypeElement) method.getEnclosingElement();
        String declaringClassname = declaringClass.getQualifiedName().toString();
        String descriptor = Descriptor.getDesriptor(method);
        String name = method.getSimpleName().toString();
        try
        {
            size = getConstantPoolSize();
            index = getRefIndex(Methodref.class, declaringClassname, name, descriptor);
        }
        finally
        {
            constantReadLock.unlock();
        }
        if (index == -1)
        {
            // add entry to constant pool
            int ci = resolveClassIndex(declaringClass);
            int nati = resolveNameAndTypeIndex(name, descriptor);
            index = addConstantInfo(new Methodref(ci, nati), size);
        }
        addIndexedElement(index, method);
        return index;
    }
399373
public void addNewInstanceMethod(Method method) {
        final CachedMethod cachedMethod = CachedMethod.find(method);
        NewInstanceMetaMethod newMethod = new NewInstanceMetaMethod(cachedMethod);
        final CachedClass declaringClass = newMethod.getDeclaringClass();
        addNewInstanceMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
    }