Open jlambright opened 8 months ago
The trigger for codegen is supposed to be implementing Built
.
Could you please give an example of a class that triggers codegen that you expect to not trigger codegen?
Thanks :)
Below you'll see one of the sub-classes. When I run dart run build_runner build
(as I do have some codegen in this project), it throws the following errors.
[SEVERE] built_value_generator:built_value on lib/data/wrappers/wrappers.dart:
Error in BuiltValueGenerator for /dsk360_command/lib/data/wrappers/wrappers.dart.
Please make the following changes to use built_value serialization:
<I'm skipping a bunch of errors since they're almost all the same.>
10. Declare TicketWrapper.serializer as: static Serializer<TicketWrapper> get serializer => _$ticketWrapperSerializer; got @override Serializer<TicketModel> get serializer => _$ticketWrapperSerializer;
part of 'wrappers.dart';
TicketWrapper ticketFromJson(String str) => TicketWrapper.fromJsonString(str);
TicketModel? ticketToModel(TicketWrapper data) => data.toModel();
String ticketToJson(TicketWrapper data) => standardSerializers
.toJson<TicketModel>(TicketModel.serializer, data.toModel());
List<TicketWrapper> ticketsFromModelList(List<TicketModel>? tickets) {
if (tickets == null) {
return [];
} else {
return tickets
.asMap()
.entries
.map((entry) => TicketWrapper.fromModel(
ticketModel: entry.value, number: entry.key))
.toList();
}
}
Map<String, TicketWrapper> ticketsMapFromTicketModelList(
List<TicketModel>? tickets) {
if (tickets == null) {
return <String, TicketWrapper>{};
} else {
return Map.fromEntries(
tickets.map<MapEntry<String, TicketWrapper>>((ticketModel) {
final TicketWrapper ticket =
TicketWrapper.fromModel(ticketModel: ticketModel);
return MapEntry(ticket.uuid, ticket);
}));
}
}
Map<String, TicketWrapper> ticketsMapFromList(List<TicketWrapper>? tickets) =>
{for (TicketWrapper ticket in tickets ?? []) ticket.uuid: ticket};
List<TicketModel?> ticketWrapperListToModel(
List<TicketWrapper> ticketWrappers) {
return ticketWrappers
.map((ticketWrapper) => ticketWrapper.toModel())
.toList();
}
List<Map<String, dynamic>> toJsonMapTicketList(List<TicketWrapper> tickets) =>
tickets.map((ticket) => ticket.toJsonMap()).toList();
class TicketWrapper
extends BuiltJsonSerializable<TicketModel, TicketModelBuilder> {
@override
Serializer<TicketModel> get serializer => TicketModel.serializer;
late final int dataHash;
late final String uuid;
late final DateTime lastModified;
late final ContactWrapper contact;
late final TicketStatusEnum status;
late final Map<String, NoteWrapper> notes;
List<NoteWrapper> get notesList => notes.values.toList();
List<String> get notesUuids => notes.keys.toList();
late final Map<String, TagWrapper> tags;
List<TagWrapper> get tagList => tags.values.toList();
List<String> get tagUuids => tags.keys.toList();
List<String> get tagNames => [for (TagWrapper tag in tagList) tag.name];
bool hasTagByUuid(String tagUuid) => tagUuids.contains(tagUuid);
bool get isMaintenance => tagNames.contains("Maintenance");
bool get isSecurity => tagNames.contains("Security");
bool get hasImageUrls => contact.hasLatestUrls;
String? get latestImageUrl => contact.latestImageUrl;
List<String>? get latestImageUrls => contact.latestImageUrls;
BoundingSphereWrapper get boundingSphere => contact.boundingSphere;
@override
int get hashCode => toJsonString().hashCode;
TicketWrapper(
{required this.uuid,
required this.contact,
DateTime? lastModified,
this.status = TicketStatusEnum.unknown,
this.notes = const {},
this.tags = const {}})
: lastModified = lastModified ?? epochTime;
TicketWrapper.fromModel({TicketModel? ticketModel, int? number}) {
uuid = ticketModel?.uuid ?? _uuid.v4();
lastModified = ticketModel?.lastModified ?? epochTime;
contact = ContactWrapper.fromModel(ticketModel?.contact);
status = TicketStatusEnum.fromDkpQualityEnum(ticketModel?.status);
tags = fromTagModelList(ticketModel?.tags.toList());
notes = fromNoteModelList(ticketModel?.notes?.toList());
}
TicketWrapper.createEmptyWrapper() {
uuid = _uuid.v4();
lastModified = epochTime;
contact = ContactWrapper.createEmptyWrapper();
status = TicketStatusEnum.unknown;
tags = {};
notes = {};
}
TicketWrapper.fromJsonString(String serialized) {
try {
TicketModel? ticketModel =
standardSerializers.fromJson<TicketModel>(serializer, serialized);
TicketWrapper.fromModel(ticketModel: ticketModel);
} on AssertionError {
throw ArgumentError.notNull(serialized);
}
}
@override
Map<String, dynamic> toJsonMap() => jsonDecode(toJsonString());
@override
TicketModel? toModel() {
return modelFromJsonString(jsonEncode({
"uuid": uuid,
"lastModified": lastModified,
"contact": contact.toModel(),
"status": status == TicketStatusEnum.unknown ? "Open" : status.value,
"notes": noteWrapperListToModel(notesList),
"tags": tagWrapperListToModel(tagList)
}));
}
@override
bool operator ==(Object other) {
return super.hashCode == other.hashCode;
}
}
Oh, I see the problem.
The serializer codegen triggers for a class if any of its supertypes starts with Built
, and there is a field called serializer
.
I have no idea why it's like this, the value type generation only triggers if the interface is exactly Built
.
That looks like it should just be fixed, until then you can work around by renaming your class to anything that doesn't start with Built
or renaming serializer
. (Whoops).
Given the abstract class (as well as a mixin version of the code) any sub-classes seem to trigger code generation attempts. However, I'm creating a wrapper class that consumes Built generated classes. This seems like buggy behavior. Either that, or it highlights the need for some kind of
@built_ignore()
annotation.