generateReactiveData function

String generateReactiveData(
  1. ClassElement c
)

Implementation

String generateReactiveData(ClassElement c) {
  final name = c.displayName;

  final params = c.defaultConstructor.parameters;
  final getters = c.publicGetters.map((g) {
    return '''
@override
${g.type} get ${g.displayName} => \$source.${g.displayName};
''';
  }).join('\n');

  final setters = c.publicSetters.map((s) {
    return '''
@override
set ${s.displayName}(${s.type} v) {
  \$source.${s.displayName} = v;
  final snapshot = \$snapshot();
  for (final actor in effects.whereType<${c.effectClassName}>()) {
    Future(() {
      actor.${generateSetterActionName(c, s)}(snapshot, v);
    });
  }
  _update();
}''';
  }).join('\n');

  final methods = c.publicMethods.map((m) {
    final params = m.parameters.toArguments();

    return '''
@override
${m.declaration} {
  ${m.returnType is VoidType ? '' : 'final ret = '}\$source.${m.displayName}($params);
  final snapshot = \$snapshot();
  for (final actor in effects.whereType<${c.effectClassName}>()) {
    Future(() {
      actor.${generateMethodActionName(c, m)}(snapshot, ${m.parameters.toArguments()});
    });
  }
  ${hypenIgnoreNotification.hasAnnotationOf(m) ? '' : m.returnType.isDartAsyncFuture ? '''
  ret.then((_) {
    _update();
  });
''' : '_update();'}
  ${m.returnType is VoidType ? '' : 'return ret;'}
}
''';
  }).join('\n');

  final superInitializer = _generateSupeInitializers(c);

  final initLateGetters =
      c.publicGetters.where((e) => e.isLate || e.setter == null).map((g) {
    return '''
\$source.${g.displayName};
''';
  }).join('\n');

  return '''
class ${c.reactiveDataName}
  extends $name
  with
    ${c.hypenGeneratedName},
    ${c.proxyName} {
  ${c.reactiveDataConstructor}(
    ${params.isNotEmpty ? 'this.params' : ''}
  )$superInitializer;

  ${params.isNotEmpty ? '''
@override
final ${c.parameterClassName} params;
''' : ''}

  ${params.isEmpty ? '' : '''
@override
Object? get actionKey => ${c.reactiveDataName};
'''}

  $getters
  $setters
  $methods

  @override
  FutureOr<${c.displayName}>? load(covariant ${params.isEmpty ? 'Null' : c.parameterClassName} params) {
    final loaders = effects.whereType<${c.loaderClassName}>().toList();
    assert(
      loaders.isEmpty || loaders.length == 1,
      'You can not have more than 1 loaders for [${c.displayName}]',
    );
    if (loaders.isEmpty) {
      return null;
    }
    final load = loaders.first;
    return load.load(this, ${params.isEmpty ? '' : params.toParamsArguments()});
  }

  @override
  void \$init() {
    $initLateGetters

    final snapshot = \$snapshot();
    effects
      .whereType<${c.effectClassName}>()
      .forEach(
        (a) => Future(() => a.${c.initActionMethodName}(snapshot))
      );
  }

  @override
  void \$update() {
    final snapshot = \$snapshot();
    effects.whereType<${c.effectClassName}>()
      .forEach((a) =>
        Future(() => a.${c.updateActionMethodName}(snapshot))
      );
  }

  @override
  void dispose() {
    final snapshot = \$snapshot();
    effects.whereType<${c.effectClassName}>()
      .forEach(
        (a) => Future(() => a.${c.disposeActionMethodName}(snapshot))
      );
    super.dispose();
  }

  @override
  void \$refresh() {
    final snapshot = \$snapshot();

    \$rawSource?.dispose();

    effects.whereType<${c.effectClassName}>()
      .forEach(
        (a) => Future(() => a.${c.disposeActionMethodName}(snapshot))
      );

    super.\$refresh();
  }

  void _update() {
    super.\$notify();
    Future(() {
      \$update();
    });
  }

  @override
  $name \$build() => $name(${params.isEmpty ? '' : params.toParamsArguments()});

  @override
  ${c.snapshotName} \$snapshot() => ${c.snapshotName}._(this, ${params.isEmpty ? '' : 'params'});
}
''';
}