Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classes not being generated with new Dart 3 classes modifiers #1262

Open
yisusparkr opened this issue Aug 18, 2023 · 2 comments
Open

Classes not being generated with new Dart 3 classes modifiers #1262

yisusparkr opened this issue Aug 18, 2023 · 2 comments
Assignees

Comments

@yisusparkr
Copy link

Hi @davidmorgan, hope you are doing pretty well!

The generated code is not respecting the classes modifiers in case we mark our class with one, example:

Entity

abstract interface class CreateVehiclePayload {
  int get year;
  String get make;
  String get model;
  double get initialMileage;
  String? get plate;
  String? get plateState;
  String? get vin;

  String toJson();
}

Model

library create_vehicle_payload_model;

part 'create_vehicle_payload_model.g.dart';

abstract final class CreateVehiclePayloadModel
    implements CreateVehiclePayload, Built<CreateVehiclePayloadModel, CreateVehiclePayloadModelBuilder> {
  const CreateVehiclePayloadModel._();

  factory CreateVehiclePayloadModel({
    required int year,
    required String model,
    required String make,
    required double initialMileage,
    String? plate,
    String? plateState,
    String? vin,
  }) =>
      _$CreateVehiclePayloadModel(
        (b) => b
          ..year = year
          ..model = model
          ..make = make
          ..initialMileage = initialMileage
          ..plate = plate
          ..vin = vin
          ..plateState = plateState,
      );

  @override
  String toJson() {
    return jsonEncode(coreSerializers.serializeWith(CreateVehiclePayloadModel.serializer, this));
  }

  static Serializer<CreateVehiclePayloadModel> get serializer => _$createVehiclePayloadModelSerializer;
}

Then, if I run the command flutter pub run build_runner build --delete-conflicting-outputs, I get the following generated file:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'create_vehicle_payload_model.dart';

// **************************************************************************
// BuiltValueGenerator
// **************************************************************************

Serializer<CreateVehiclePayloadModel> _$createVehiclePayloadModelSerializer =
    new _$CreateVehiclePayloadModelSerializer();

class _$CreateVehiclePayloadModelSerializer
    implements StructuredSerializer<CreateVehiclePayloadModel> {
  @override
  final Iterable<Type> types = const [
    CreateVehiclePayloadModel,
    _$CreateVehiclePayloadModel
  ];
  @override
  final String wireName = 'CreateVehiclePayloadModel';

  @override
  Iterable<Object?> serialize(
      Serializers serializers, CreateVehiclePayloadModel object,
      {FullType specifiedType = FullType.unspecified}) {
    final result = <Object?>[
      'year',
      serializers.serialize(object.year, specifiedType: const FullType(int)),
      'make',
      serializers.serialize(object.make, specifiedType: const FullType(String)),
      'model',
      serializers.serialize(object.model,
          specifiedType: const FullType(String)),
      'initialMileage',
      serializers.serialize(object.initialMileage,
          specifiedType: const FullType(double)),
    ];
    Object? value;
    value = object.plate;
    if (value != null) {
      result
        ..add('plate')
        ..add(serializers.serialize(value,
            specifiedType: const FullType(String)));
    }
    value = object.plateState;
    if (value != null) {
      result
        ..add('plateState')
        ..add(serializers.serialize(value,
            specifiedType: const FullType(String)));
    }
    value = object.vin;
    if (value != null) {
      result
        ..add('vin')
        ..add(serializers.serialize(value,
            specifiedType: const FullType(String)));
    }
    return result;
  }

  @override
  CreateVehiclePayloadModel deserialize(
      Serializers serializers, Iterable<Object?> serialized,
      {FullType specifiedType = FullType.unspecified}) {
    final result = new CreateVehiclePayloadModelBuilder();

    final iterator = serialized.iterator;
    while (iterator.moveNext()) {
      final key = iterator.current! as String;
      iterator.moveNext();
      final Object? value = iterator.current;
      switch (key) {
        case 'year':
          result.year = serializers.deserialize(value,
              specifiedType: const FullType(int))! as int;
          break;
        case 'make':
          result.make = serializers.deserialize(value,
              specifiedType: const FullType(String))! as String;
          break;
        case 'model':
          result.model = serializers.deserialize(value,
              specifiedType: const FullType(String))! as String;
          break;
        case 'initialMileage':
          result.initialMileage = serializers.deserialize(value,
              specifiedType: const FullType(double))! as double;
          break;
        case 'plate':
          result.plate = serializers.deserialize(value,
              specifiedType: const FullType(String)) as String?;
          break;
        case 'plateState':
          result.plateState = serializers.deserialize(value,
              specifiedType: const FullType(String)) as String?;
          break;
        case 'vin':
          result.vin = serializers.deserialize(value,
              specifiedType: const FullType(String)) as String?;
          break;
      }
    }

    return result.build();
  }
}

class _$CreateVehiclePayloadModel extends CreateVehiclePayloadModel {
  @override
  final int year;
  @override
  final String make;
  @override
  final String model;
  @override
  final double initialMileage;
  @override
  final String? plate;
  @override
  final String? plateState;
  @override
  final String? vin;

  factory _$CreateVehiclePayloadModel(
          [void Function(CreateVehiclePayloadModelBuilder)? updates]) =>
      (new CreateVehiclePayloadModelBuilder()..update(updates))._build();

  _$CreateVehiclePayloadModel._(
      {required this.year,
      required this.make,
      required this.model,
      required this.initialMileage,
      this.plate,
      this.plateState,
      this.vin})
      : super._() {
    BuiltValueNullFieldError.checkNotNull(
        year, r'CreateVehiclePayloadModel', 'year');
    BuiltValueNullFieldError.checkNotNull(
        make, r'CreateVehiclePayloadModel', 'make');
    BuiltValueNullFieldError.checkNotNull(
        model, r'CreateVehiclePayloadModel', 'model');
    BuiltValueNullFieldError.checkNotNull(
        initialMileage, r'CreateVehiclePayloadModel', 'initialMileage');
  }

  @override
  CreateVehiclePayloadModel rebuild(
          void Function(CreateVehiclePayloadModelBuilder) updates) =>
      (toBuilder()..update(updates)).build();

  @override
  CreateVehiclePayloadModelBuilder toBuilder() =>
      new CreateVehiclePayloadModelBuilder()..replace(this);

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    return other is CreateVehiclePayloadModel &&
        year == other.year &&
        make == other.make &&
        model == other.model &&
        initialMileage == other.initialMileage &&
        plate == other.plate &&
        plateState == other.plateState &&
        vin == other.vin;
  }

  @override
  int get hashCode {
    var _$hash = 0;
    _$hash = $jc(_$hash, year.hashCode);
    _$hash = $jc(_$hash, make.hashCode);
    _$hash = $jc(_$hash, model.hashCode);
    _$hash = $jc(_$hash, initialMileage.hashCode);
    _$hash = $jc(_$hash, plate.hashCode);
    _$hash = $jc(_$hash, plateState.hashCode);
    _$hash = $jc(_$hash, vin.hashCode);
    _$hash = $jf(_$hash);
    return _$hash;
  }

  @override
  String toString() {
    return (newBuiltValueToStringHelper(r'CreateVehiclePayloadModel')
          ..add('year', year)
          ..add('make', make)
          ..add('model', model)
          ..add('initialMileage', initialMileage)
          ..add('plate', plate)
          ..add('plateState', plateState)
          ..add('vin', vin))
        .toString();
  }
}

class CreateVehiclePayloadModelBuilder
    implements
        Builder<CreateVehiclePayloadModel, CreateVehiclePayloadModelBuilder> {
  _$CreateVehiclePayloadModel? _$v;

  int? _year;
  int? get year => _$this._year;
  set year(int? year) => _$this._year = year;

  String? _make;
  String? get make => _$this._make;
  set make(String? make) => _$this._make = make;

  String? _model;
  String? get model => _$this._model;
  set model(String? model) => _$this._model = model;

  double? _initialMileage;
  double? get initialMileage => _$this._initialMileage;
  set initialMileage(double? initialMileage) =>
      _$this._initialMileage = initialMileage;

  String? _plate;
  String? get plate => _$this._plate;
  set plate(String? plate) => _$this._plate = plate;

  String? _plateState;
  String? get plateState => _$this._plateState;
  set plateState(String? plateState) => _$this._plateState = plateState;

  String? _vin;
  String? get vin => _$this._vin;
  set vin(String? vin) => _$this._vin = vin;

  CreateVehiclePayloadModelBuilder();

  CreateVehiclePayloadModelBuilder get _$this {
    final $v = _$v;
    if ($v != null) {
      _year = $v.year;
      _make = $v.make;
      _model = $v.model;
      _initialMileage = $v.initialMileage;
      _plate = $v.plate;
      _plateState = $v.plateState;
      _vin = $v.vin;
      _$v = null;
    }
    return this;
  }

  @override
  void replace(CreateVehiclePayloadModel other) {
    ArgumentError.checkNotNull(other, 'other');
    _$v = other as _$CreateVehiclePayloadModel;
  }

  @override
  void update(void Function(CreateVehiclePayloadModelBuilder)? updates) {
    if (updates != null) updates(this);
  }

  @override
  CreateVehiclePayloadModel build() => _build();

  _$CreateVehiclePayloadModel _build() {
    final _$result = _$v ??
        new _$CreateVehiclePayloadModel._(
            year: BuiltValueNullFieldError.checkNotNull(
                year, r'CreateVehiclePayloadModel', 'year'),
            make: BuiltValueNullFieldError.checkNotNull(
                make, r'CreateVehiclePayloadModel', 'make'),
            model: BuiltValueNullFieldError.checkNotNull(
                model, r'CreateVehiclePayloadModel', 'model'),
            initialMileage: BuiltValueNullFieldError.checkNotNull(
                initialMileage, r'CreateVehiclePayloadModel', 'initialMileage'),
            plate: plate,
            plateState: plateState,
            vin: vin);
    replace(_$result);
    return _$result;
  }
}

// ignore_for_file: deprecated_member_use_from_same_package,type=lint

Then I get the following error -> The type '_$CreateVehiclePayloadModel' must be 'base', 'final' or 'sealed' because the supertype 'CreateVehiclePayloadModel' is 'final'.. In order to make it work, I have to manually add any of the mentioned modifiers, but I think it is not ideal, adding modifiers manually for each generated class is painful.

@davidmorgan
Copy link
Collaborator

davidmorgan commented Aug 24, 2023

Thanks!

Yes, I didn't add any support for the new modifiers yet.

What modifiers are interesting for built_value classes?

I was mostly thinking "final" to prevent subclassing so the compiler knows the generate implementation is the only one.

@yisusparkr
Copy link
Author

yisusparkr commented Aug 25, 2023

I agree, I think final modifier would be great to have due to the benefits it provides, like preventing subclassing.

I think creating a built_value class with sealed modifier would not provide much value, at the end of the day if I will use that modifier I have to create its own subclass abstract interface class extending from the sealed class and then the abstract final built_value class implementing the created subclass, so there is no need of having the generated class marked as sealed. For the base modifier I have a similar thought.

This is just my POV and just providing the example following the good practices, also taking into account some complex models with generic types, but I don't know if someone could fall in the need of generating a built_value class with the sealed, base or another modifier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants