static MethodSpec generateEventMethod()

in litho-processor/src/main/java/com/facebook/litho/specmodels/generator/EventGenerator.java [201:335]


  static MethodSpec generateEventMethod(
      SpecModel specModel, SpecMethodModel<EventMethod, EventDeclarationModel> eventMethodModel) {
    final String componentName = specModel.getComponentName();
    final MethodSpec.Builder methodSpec =
        MethodSpec.methodBuilder(eventMethodModel.name.toString())
            .addModifiers(Modifier.PRIVATE)
            .returns(eventMethodModel.returnType)
            .addTypeVariables(eventMethodModel.typeVariables)
            .addParameter(ClassNames.HAS_EVENT_DISPATCHER_CLASSNAME, ABSTRACT_PARAM_NAME)
            .addStatement(
                "$L $L = ($L) $L",
                componentName,
                REF_VARIABLE_NAME,
                componentName,
                ABSTRACT_PARAM_NAME);

    final String contextParamName = getContextParamName(specModel, eventMethodModel);
    final boolean hasLazyStateParams = SpecMethodModelUtils.hasLazyStateParams(eventMethodModel);

    if (hasLazyStateParams) {
      methodSpec.addStatement(
          "$L $L = getStateContainerWithLazyStateUpdatesApplied(c, $L)",
          StateContainerGenerator.getStateContainerClassName(specModel),
          LOCAL_STATE_CONTAINER_NAME,
          REF_VARIABLE_NAME);
    } else if (eventMethodModel.methodParams.stream().anyMatch(PREDICATE_NEEDS_STATE)) {
      methodSpec.addStatement(
          "$L $L = $L",
          StateContainerGenerator.getStateContainerClassName(specModel),
          LOCAL_STATE_CONTAINER_NAME,
          STATE_CONTAINER_IMPL_GETTER + "(" + contextParamName + ")");
    }

    final CodeBlock.Builder delegation = CodeBlock.builder();

    // Create a local variable for interstage props if they created or used.
    if (ComponentBodyGenerator.requiresInterStatePropContainer(
        eventMethodModel.methodParams, null)) {
      delegation.addStatement(
          "$L $L = $L",
          ClassNames.INTER_STAGE_PROPS_CONTAINER,
          ComponentBodyGenerator.LOCAL_INTER_STAGE_PROPS_CONTAINER_NAME,
          "null");
    }

    final String sourceDelegateAccessor = SpecModelUtils.getSpecAccessor(specModel);
    final boolean isErrorDelegation =
        eventMethodModel.name.toString().equals(EventCaseGenerator.INTERNAL_ON_ERROR_HANDLER_NAME);

    if (isErrorDelegation) {
      delegation.add("$L(\n", "onError");
    } else if (eventMethodModel.returnType.equals(TypeName.VOID)) {
      delegation.add("$L.$L(\n", sourceDelegateAccessor, eventMethodModel.name);
    } else {
      delegation.add(
          "$T _result = ($T) $L.$L(\n",
          eventMethodModel.returnType,
          eventMethodModel.returnType,
          sourceDelegateAccessor,
          eventMethodModel.name);
    }

    delegation.indent();

    for (int i = 0, size = eventMethodModel.methodParams.size(); i < size; i++) {
      final MethodParamModel methodParamModel = eventMethodModel.methodParams.get(i);

      final boolean hasParamAnnotation = isAnnotatedWith(methodParamModel, Param.class);
      if (hasParamAnnotation
          || isAnnotatedWith(methodParamModel, FromEvent.class)
          || methodParamModel.getTypeName().equals(specModel.getContextClass())) {

        TypeName type = methodParamModel.getTypeName();

        methodSpec.addParameter(
            parameter(
                type,
                methodParamModel.getName(),
                hasParamAnnotation
                    ? methodParamModel.getExternalAnnotations()
                    : Collections.emptyList()));
        delegation.add(methodParamModel.getName());

      } else if (methodParamModel instanceof TreePropModel) {
        if (specModel.isStateful()) {
          delegation.add(
              "(($T) $L.$L)",
              methodParamModel.getTypeName(),
              REF_VARIABLE_NAME,
              methodParamModel.getName());
        } else {
          delegation.add(
              "(($T) $L)",
              methodParamModel.getTypeName(),
              contextParamName
                  + ".getParentTreeProp("
                  + TreePropGenerator.findTypeByTypeName(methodParamModel.getTypeName())
                  + ".class)");
        }
      } else if (methodParamModel instanceof StateParamModel) {
        delegation.add(
            "($T) $L",
            methodParamModel.getTypeName(),
            getImplAccessorFromContainer(
                eventMethodModel.name.toString(),
                specModel,
                methodParamModel,
                contextParamName,
                LOCAL_STATE_CONTAINER_NAME));
      } else {
        delegation.add(
            "($T) $L.$L",
            methodParamModel.getTypeName(),
            REF_VARIABLE_NAME,
            getImplAccessor(
                eventMethodModel.name.toString(), specModel, methodParamModel, contextParamName));
      }

      if (i < size - 1) {
        delegation.add(",\n");
      } else {
        delegation.add(");\n");
      }
    }

    delegation.unindent();

    methodSpec.addCode(delegation.build());

    if (!eventMethodModel.returnType.equals(TypeName.VOID)) {
      methodSpec.addStatement("return _result");
    }

    return methodSpec.build();
  }