google / google/built_value.dart
Confusing error from built_value generator
- Dominant language
- Dart
- Stars
- 886
- Forks
- 195
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 4
Description
Hi there! First of all, thanks for maintaining this package. It's been a big part of my workflow for years now!
I'm afraid I hit a snag. I have a class like this:
```dart
abstract class Inventory implements Built {
static Serializer get serializer => _$inventorySerializer;
factory Inventory([void updates(InventoryBuilder b)]) = _$Inventory;
Inventory._();
BuiltList get items;
// ...
}
```
and a custom builder class like this:
```dart
abstract class InventoryBuilder
implements Builder {
ListBuilder items;
factory InventoryBuilder() = _$InventoryBuilder;
InventoryBuilder._();
// ...
}
```
This worked just fine before null safety. After upgrading to null safety using the migration tool (naive approach?), the classes look like this:
```dart
abstract class Inventory implements Built {
static Serializer get serializer => _$inventorySerializer;
factory Inventory([void updates(InventoryBuilder b)]) = _$Inventory;
Inventory._();
BuiltList get items; // <-- no change
// ...
}
```
and the builder class:
```dart
abstract class InventoryBuilder
implements Builder {
ListBuilder? items; // <-- added "or null" here
factory InventoryBuilder() = _$InventoryBuilder;
InventoryBuilder._();
// ...
}
```
Now, the generator does not work, and spits out this error message:
```
Error in BuiltValueGenerator for abstract class Inventory implements Built.
Please make the following changes to use BuiltValue:
1. Make builder field items have type: BuiltList? (or, if applicable, builder)
```
It took me a while to understand that the "if applicable, builder" part means `ListBuilder?`. Then I was confused, because that's what I already have there.
So I changed [the code in `built_value_generator`'s `value_source_field.dart`](https://github.com/google/built_value.dart/blob/master/built_value_generator/lib/src/value_source_field.dart#L294-L303) to tell me more:
```dart
result.add(GeneratorError((b) => b
..message = 'Make builder field $name have type: '
'$type$orNull (or, if applicable, builder: ${_toBuilderType(element.type, type)}) -- current type: ${builderElementTypeOrNull}'));
```
And this was the output:
```
Please make the following changes to use BuiltValue:
1. Make builder field items have type: BuiltList? (or, if applicable, builder: ListBuilder) -- current type: ListBuilder?
```
So, either the check is incorrect (and nullable `BuiltList?` should be permitted), or the error message should be expanded.
What worked for me is this:
```dart
abstract class InventoryBuilder
implements Builder {
ListBuilder items = ListBuilder();
factory InventoryBuilder() = _$InventoryBuilder;
InventoryBuilder._();
// ...
}
```
Now the source generation works and tests pass.
Contributor guide
Assessment
This issue has not been assessed yet.