Future buildDeclarationsForClass()

in working/macros/example/data_class.dart [40:114]


  Future<void> buildDeclarationsForClass(
      ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
    var constructors = await builder.constructorsOf(clazz);
    if (constructors.any((c) => c.identifier.name == '')) {
      throw ArgumentError(
          'Cannot generate an unnamed constructor because one already exists');
    }

    var parts = <Object>[clazz.identifier.name, '({'];
    // Add all the fields of `declaration` as named parameters.
    var fields = await builder.fieldsOf(clazz);
    for (var field in fields) {
      var requiredKeyword = field.type.isNullable ? '' : 'required ';
      parts.addAll(['\n${requiredKeyword}this.', field.identifier.name, ',']);
    }

    // Add all super constructor parameters as named parameters.
    var superclass = (await builder.superclassOf(clazz))!;
    MethodDeclaration? superconstructor;
    // TODO: Compare against Object identifier once we can get it.
    if (superclass.identifier.name != 'Object') {
      var superconstructor = (await builder.constructorsOf(superclass))
          .firstWhereOrNull((c) => c.identifier.name == '');
      if (superconstructor == null) {
        throw ArgumentError(
            'Super class $superclass of $clazz does not have an unnamed '
            'constructor');
      }
      // We convert positional parameters in the super constructor to named
      // parameters in this constructor.
      for (var param in superconstructor.positionalParameters) {
        var requiredKeyword = param.isRequired ? 'required' : '';
        var defaultValue = param.defaultValue == null
            ? ''
            : Code.fromParts([' = ', param.defaultValue!]);
        parts.addAll([
          '\n$requiredKeyword',
          param.type.code,
          ' ${param.identifier.name},',
          defaultValue,
          ',',
        ]);
      }
      for (var param in superconstructor.namedParameters) {
        var requiredKeyword = param.isRequired ? '' : 'required ';
        var defaultValue = param.defaultValue == null
            ? ''
            : Code.fromParts([' = ', param.defaultValue!]);
        parts.addAll([
          '\n$requiredKeyword',
          param.type.code,
          ' ${param.identifier.name}',
          defaultValue,
          ',',
        ]);
      }
    }
    parts.add('\n})');
    if (superconstructor != null) {
      parts.add(' : super(');
      for (var param in superconstructor.positionalParameters) {
        parts.add('\n${param.identifier.name},');
      }
      if (superconstructor.namedParameters.isNotEmpty) {
        parts.add('{');
        for (var param in superconstructor.namedParameters) {
          parts.add('\n${param.identifier.name}: ${param.identifier.name},');
        }
        parts.add('\n}');
      }
      parts.add(')');
    }
    parts.add(';');
    builder.declareInClass(DeclarationCode.fromParts(parts));
  }