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