Bug: Build Runner Generates Incorrect .mapper File With Nullable Generics
Opened this issue · 0 comments
gabrielmcreynolds commented
When there is nullable generics the build runner is generating a .mapper
file that contains an error. Below is a minimally reproducable example:
// nullable_generics.dart
import 'package:dart_mappable/dart_mappable.dart';
part 'nullable_generics.mapper.dart';
@MappableClass()
// in real-world it is T extends AnotherClass but using the default Object for simplicity here
class NullableGenerics<T extends Object> with NullableGenericsMappable<T> {
final T? value;
const NullableGenerics({required this.value});
}
nullable_generics.mapper.dart
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
part of 'nullable_generics.dart';
class NullableGenericsMapper extends ClassMapperBase<NullableGenerics> {
NullableGenericsMapper._();
static NullableGenericsMapper? _instance;
static NullableGenericsMapper ensureInitialized() {
if (_instance == null) {
MapperBase.addType<Object>();
MapperContainer.globals.use(_instance = NullableGenericsMapper._());
}
return _instance!;
}
@override
final String id = 'NullableGenerics';
@override
Function get typeFactory => <T extends Object>(f) => f<NullableGenerics<T>>();
static Object _$value(NullableGenerics v) => v.value;
static dynamic _arg$value<T extends Object>(f) => f<T>();
static const Field<NullableGenerics, Object> _f$value =
Field('value', _$value, arg: _arg$value);
@override
final MappableFields<NullableGenerics> fields = const {
#value: _f$value,
};
static NullableGenerics<T> _instantiate<T extends Object>(DecodingData data) {
return NullableGenerics(value: data.dec(_f$value));
}
@override
final Function instantiate = _instantiate;
static NullableGenerics<T> fromMap<T extends Object>(
Map<String, dynamic> map) {
return ensureInitialized().decodeMap<NullableGenerics<T>>(map);
}
static NullableGenerics<T> fromJson<T extends Object>(String json) {
return ensureInitialized().decodeJson<NullableGenerics<T>>(json);
}
}
mixin NullableGenericsMappable<T extends Object> {
String toJson() {
return NullableGenericsMapper.ensureInitialized()
.encodeJson<NullableGenerics<T>>(this as NullableGenerics<T>);
}
Map<String, dynamic> toMap() {
return NullableGenericsMapper.ensureInitialized()
.encodeMap<NullableGenerics<T>>(this as NullableGenerics<T>);
}
NullableGenericsCopyWith<NullableGenerics<T>, NullableGenerics<T>,
NullableGenerics<T>, T>
get copyWith => _NullableGenericsCopyWithImpl(
this as NullableGenerics<T>, $identity, $identity);
@override
String toString() {
return NullableGenericsMapper.ensureInitialized()
.stringifyValue(this as NullableGenerics<T>);
}
@override
bool operator ==(Object other) {
return NullableGenericsMapper.ensureInitialized()
.equalsValue(this as NullableGenerics<T>, other);
}
@override
int get hashCode {
return NullableGenericsMapper.ensureInitialized()
.hashValue(this as NullableGenerics<T>);
}
}
extension NullableGenericsValueCopy<$R, $Out, T extends Object>
on ObjectCopyWith<$R, NullableGenerics<T>, $Out> {
NullableGenericsCopyWith<$R, NullableGenerics<T>, $Out, T>
get $asNullableGenerics =>
$base.as((v, t, t2) => _NullableGenericsCopyWithImpl(v, t, t2));
}
abstract class NullableGenericsCopyWith<$R, $In extends NullableGenerics<T>,
$Out, T extends Object> implements ClassCopyWith<$R, $In, $Out> {
$R call({T? value});
NullableGenericsCopyWith<$R2, $In, $Out2, T> $chain<$R2, $Out2>(
Then<$Out2, $R2> t);
}
class _NullableGenericsCopyWithImpl<$R, $Out, T extends Object>
extends ClassCopyWithBase<$R, NullableGenerics<T>, $Out>
implements NullableGenericsCopyWith<$R, NullableGenerics<T>, $Out, T> {
_NullableGenericsCopyWithImpl(super.value, super.then, super.then2);
@override
late final ClassMapperBase<NullableGenerics> $mapper =
NullableGenericsMapper.ensureInitialized();
@override
$R call({Object? value = $none}) =>
$apply(FieldCopyWithData({if (value != $none) #value: value}));
@override
NullableGenerics<T> $make(CopyWithData data) =>
NullableGenerics(value: data.get(#value, or: $value.value));
@override
NullableGenericsCopyWith<$R2, NullableGenerics<T>, $Out2, T>
$chain<$R2, $Out2>(Then<$Out2, $R2> t) =>
_NullableGenericsCopyWithImpl($value, $cast, t);
}
The error being thrown is
A value of type 'Object?' can't be returned from the method '_$value' because it has a return type of 'Object'.
I'm assuming this is coming from the T extends Object
line and it is just not checking if the generic type is nullable.