in litho-processor/src/main/java/com/facebook/litho/specmodels/generator/DelegateMethodGenerator.java [106:233]
private static MethodSpec generateDelegate(
SpecModel specModel,
DelegateMethodDescription methodDescription,
SpecMethodModel<DelegateMethod, Void> delegateMethod,
EnumSet<RunMode> runMode) {
final MethodSpec.Builder methodSpec =
MethodSpec.methodBuilder(methodDescription.name)
.addModifiers(methodDescription.accessType)
.returns(methodDescription.returnType);
for (AnnotationSpec annotation : methodDescription.annotations) {
methodSpec.addAnnotation(annotation);
}
final ImmutableList<LifecycleMethodArgumentType> lifecycleArgs =
methodDescription.lifecycleMethodArgumentTypes;
final ImmutableList<MethodParamModel> delegateArgs = delegateMethod.methodParams;
String contextParamName = null;
String interStagePropsParamName = null;
for (int i = 0, size = lifecycleArgs.size(); i < size; i++) {
final TypeName lifecycleArg = lifecycleArgs.get(i).type;
final TypeName delegateArg =
delegateArgs.size() > i ? delegateArgs.get(i).getTypeName() : null;
final String name;
if (!lifecycleArg.equals(ClassNames.OBJECT) && !lifecycleArg.equals(delegateArg)) {
name = "_" + i; // Use the counter to generate a placeholder name.
} else {
name = delegateArgs.get(i).getName(); // Use the name from the delegate method if its used.
}
// Cache the name of spec context argument.
if (lifecycleArgs.get(i).type == specModel.getContextClass() && contextParamName == null) {
contextParamName = name;
}
// Cache the name of spec context argument.
if (lifecycleArgs.get(i).type == ClassNames.INTER_STAGE_PROPS_CONTAINER
&& interStagePropsParamName == null) {
interStagePropsParamName = name;
}
methodSpec.addParameter(lifecycleArgs.get(i).type, name);
}
final boolean methodUsesDiffs =
methodDescription.optionalParameterTypes.contains(DIFF_PROP)
|| methodDescription.optionalParameterTypes.contains(DIFF_STATE);
final String componentName = specModel.getComponentName();
for (TypeName exception : methodDescription.exceptions) {
methodSpec.addException(exception);
}
if (methodUsesDiffs) {
if (methodDescription.name.equals("shouldUpdate") && specModel instanceof HasPureRender) {
methodSpec.addParameter(specModel.getComponentClass(), "_prevAbstractImpl");
methodSpec.addParameter(specModel.getStateContainerClass(), "_prevStateContainer");
methodSpec.addParameter(specModel.getComponentClass(), "_nextAbstractImpl");
methodSpec.addParameter(specModel.getStateContainerClass(), "_nextStateContainer");
methodSpec.beginControlFlow("if (!isPureRender())");
methodSpec.addStatement("return true");
methodSpec.endControlFlow();
} else {
methodSpec.addParameter(specModel.getContextClass(), "_prevScopedContext");
methodSpec.addParameter(specModel.getComponentClass(), "_prevAbstractImpl");
methodSpec.addParameter(specModel.getContextClass(), "_nextScopedContext");
methodSpec.addParameter(specModel.getComponentClass(), "_nextAbstractImpl");
}
methodSpec.addStatement(
"$L _prevImpl = ($L) _prevAbstractImpl", componentName, componentName);
methodSpec.addStatement(
"$L _nextImpl = ($L) _nextAbstractImpl", componentName, componentName);
}
if (!methodDescription.returnType.equals(TypeName.VOID)) {
methodSpec.addStatement("$T _result", methodDescription.returnType);
}
methodSpec.addCode(
getDelegationCode(
specModel,
delegateMethod,
methodDescription,
contextParamName,
interStagePropsParamName,
runMode));
if (delegateMethod.name.toString().equals("onCreateLayout")
|| delegateMethod.name.toString().equals("onPrepare")) {
SpecMethodModel<EventMethod, Void> registerRangesModel =
specModel.getWorkingRangeRegisterMethod();
if (registerRangesModel != null) {
CodeBlock.Builder registerDelegation =
CodeBlock.builder()
.add(
"$L.$L(\n",
SpecModelUtils.getSpecAccessor(specModel),
registerRangesModel.name);
registerDelegation.indent();
for (int i = 0, size = registerRangesModel.methodParams.size(); i < size; i++) {
final MethodParamModel methodParamModel = registerRangesModel.methodParams.get(i);
registerDelegation.add(
"($T) $L",
methodParamModel.getTypeName(),
getImplAccessor(specModel, methodDescription, methodParamModel, contextParamName));
registerDelegation.add(
(i < registerRangesModel.methodParams.size() - 1) ? ",\n" : ");\n");
}
registerDelegation.unindent();
methodSpec.addCode(registerDelegation.build());
}
}
if (!methodDescription.returnType.equals(TypeName.VOID)) {
methodSpec.addStatement("return _result");
}
return methodSpec.build();
}