buildDeclarationsForClass method

  1. @override
FutureOr<void> buildDeclarationsForClass(
  1. ClassDeclaration clazz,
  2. MemberDeclarationBuilder builder
)

Implementation

@override
FutureOr<void> buildDeclarationsForClass(
  ClassDeclaration clazz,
  MemberDeclarationBuilder builder,
) async {
  final constructors = await builder.constructorsOf(clazz);
  final targetConstructor = constructors.firstWhereOrNull(
    (e) => e.identifier.name == (constructor ?? ''),
  );

  final fields = <_FreezedField>[];

  if (targetConstructor == null) {
    for (final field in await builder.fieldsOf(clazz)) {
      if (field.hasInitializer) continue;

      fields.add(
        _FreezedField(
          type: field.type,
          isNamed: true,
          name: field.identifier.name,
          isRequired: true,
          isInherited: false,
          needsDeclaration: false,
        ),
      );
    }

    // TODO once augmentation libraries work properly, automatically add fields coming from Freezed interfaces.
  } else {
    if (superCtor != null) {
      builder.report(
        Diagnostic(
          DiagnosticMessage(
            'Do not specify `superCtor` '
            'when defining a constructor',
          ),
          Severity.warning,
        ),
      );
    }

    for (final field in targetConstructor.parameters) {
      fields.add(
        _FreezedField(
          type: field.type,
          name: field.identifier.name,
          isNamed: field.isNamed,
          isRequired: field.isRequired,
          isInherited: false,
          needsDeclaration: true,
        ),
      );
    }
  }

  final targetSuperCtor = await _computeSuperCtor(clazz, builder);

  if (targetSuperCtor != null) {
    for (final field in targetSuperCtor.parameters) {
      fields.add(
        _FreezedField(
          type: field.type,
          name: field.identifier.name,
          isNamed: field.isNamed,
          isRequired: field.isRequired,
          isInherited: true,
          needsDeclaration: false,
        ),
      );
    }
  }

  builder.declareInLibrary(
    DeclarationCode.fromParts([
      'augment ',
      if (clazz.hasSealed) 'sealed ',
      'class ${clazz.identifier.name}',
      if (clazz.superclass case final superClass?) ...[
        ' extends ',
        superClass.code,
      ],
      ' {',
    ]),
  );

  await _generateConstructor(
    fields,
    builder,
    clazz,
    hasConstructor: targetConstructor != null,
    targetSuperCtor: targetSuperCtor,
  );
  await _generateFields(fields, builder, clazz);
  await _generateCopyWith(fields, builder, clazz);
  await _generateToString(fields, builder, clazz);

  if (!clazz.hasSealed) {
    // TODO generate equal/hash only if fields are final: https://github.com/dart-lang/sdk/issues/55764
    await _generateEqual(fields, builder, clazz);
    await _generateHash(fields, builder, clazz);
  }

  builder.declareInLibrary(
    DeclarationCode.fromParts([
      '}',
    ]),
  );
}