Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions built_value_generator/lib/src/value_source_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,10 @@ abstract class ValueSourceClass
result.writeln('bool operator==(Object other) {');
result.writeln(' if (identical(other, this)) return true;');

if (comparedFunctionFields.isNotEmpty) {
var needsDynamic =
comparedFunctionFields.isNotEmpty && genericParameters.isNotEmpty;

if (needsDynamic) {
result.writeln(' final dynamic _\$dynamicOther = other;');
}
result.writeln(' return other is $name${forBuilder ? 'Builder' : ''}');
Expand All @@ -1364,7 +1367,7 @@ abstract class ValueSourceClass
comparedFields.map((field) {
var nameOrThisDotName =
field.name == 'other' ? 'this.other' : field.name;
return field.isFunctionType
return needsDynamic && field.isFunctionType
? '$nameOrThisDotName == _\$dynamicOther.${field.name}'
: '$nameOrThisDotName == other.${field.name}';
}).join('&&'),
Expand Down
31 changes: 31 additions & 0 deletions built_value_generator/test/built_value_generator_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,37 @@ abstract class NestedValue implements Built<NestedValue, NestedValueBuilder> {
'1. Make builder field nestedValue have `nestedBuilder: false` in order to use `comparableBuilders: true`.'));
});

test('uses dynamic for equality check on function fields with generics',
() async {
expect(
await generate('''library value;
import 'package:built_value/built_value.dart';
part 'value.g.dart';
abstract class Value<T> implements Built<Value<T>, ValueBuilder<T>> {
Value._();
factory Value([void Function(ValueBuilder<T>) updates]) = _\$Value<T>;
void Function(T) get callback;
}
'''),
contains(r'final dynamic _$dynamicOther = other;'));
});

test(
'does not use dynamic for equality check on function fields without generics',
() async {
expect(
await generate('''library value;
import 'package:built_value/built_value.dart';
part 'value.g.dart';
abstract class Value implements Built<Value, ValueBuilder> {
Value._();
factory Value([void Function(ValueBuilder) updates]) = _\$Value;
void Function(int) get callback;
}
'''),
isNot(contains(r'dynamicOther')));
});

test('cleans generated class names for private classes', () async {
expect(
await generate('''library value;
Expand Down
3 changes: 1 addition & 2 deletions end_to_end_test/lib/mixins.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 15 additions & 18 deletions end_to_end_test/lib/records.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 12 additions & 17 deletions end_to_end_test/lib/values.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.