generate method

Future<String> generate()

Implementation

Future<String> generate() async {
  final name = element.name;
  final annotation = vibeAnnotation.firstAnnotationOf(element)!;
  final autoDispose =
      annotation.getField('autoDispose')!.toBoolValue() ?? true;

  final collectionSetup = collections.map((c) {
    return '''
if ($c is VibeCollection) {
($c as VibeCollection).notify = () => ${c.subjectName}.add(${c.subjectName}.value);
}
''';
  }).join('\n');

  final initSilent = silentField.map((f) {
    final name = f.name;
    return '''
$name = \$src.$name;
''';
  }).join('\n');

  final disposeSubjects = subjects.map((s) {
    return '${s.subjectName}.close();';
  }).join('\n');

  classBuilder
    ..name = name.observableClassName
    ..extend = Reference(name)
    ..mixins.add(Reference('VibeObservable'))
    ..constructors.add(
      Constructor(
        (builder) => builder
          ..requiredParameters.add(
            Parameter(
              (builder) => builder
                ..toThis = true
                ..name = '\$src',
            ),
          )
          ..requiredParameters.add(
            Parameter(
              (builder) => builder
                ..toThis = true
                ..name = '\$onDispose',
            ),
          )
          ..body =
              collectionSetup.isEmpty && initSilent.isEmpty ? null : Code('''
$collectionSetup
$initSilent
'''),
      ),
    )
    ..fields.add(
      Field(
        (builder) => builder
          ..modifier = FieldModifier.final$
          ..type = Reference('void Function()?')
          ..name = '\$onDispose',
      ),
    )
    ..fields.add(
      Field(
        (builder) => builder
          ..modifier = FieldModifier.final$
          ..type = Reference(name)
          ..name = '\$src',
      ),
    )
    ..methods.add(
      Method(
        (builder) => builder
          ..annotations.add(Reference('override'))
          ..returns = Reference('bool')
          ..type = MethodType.getter
          ..name = '\$autoDispose'
          ..body = Code('return $autoDispose;'),
      ),
    )
    ..methods.add(
      Method(
        (builder) => builder
          ..annotations.add(Reference('override'))
          ..name = 'dispose'
          ..body = Code('''
$disposeSubjects
\$onDispose?.call();
super.dispose();
'''),
      ),
    );
  String code = classBuilder.build().accept(_emitter).toString();
  return DartFormatter().format(code);
}