diff --git a/CHANGELOG.md b/CHANGELOG.md index e5d5795e..f54cbc3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# 8.8.1 (unreleased) + +- Remove support for generating legacy (not null safe) code. + # 8.8.0 - Allow classes with record fields to be serialized if they use a typedef for diff --git a/benchmark/pubspec.yaml b/benchmark/pubspec.yaml index 9c325d56..a82b8a58 100644 --- a/benchmark/pubspec.yaml +++ b/benchmark/pubspec.yaml @@ -6,11 +6,11 @@ description: > homepage: https://github.com/google/built_value.dart environment: - sdk: '>=2.12.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: built_collection: ^5.0.0 - built_value: ^8.7.0 + built_value: ^8.8.0 dev_dependencies: build_runner: '>=1.0.0 <3.0.0' diff --git a/built_value/pubspec.yaml b/built_value/pubspec.yaml index ead79557..7f1a70a8 100644 --- a/built_value/pubspec.yaml +++ b/built_value/pubspec.yaml @@ -8,7 +8,7 @@ topics: - built-value environment: - sdk: '>=2.12.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: built_collection: ^5.0.0 diff --git a/built_value_generator/lib/src/serializer_source_class.dart b/built_value_generator/lib/src/serializer_source_class.dart index f35ec2d1..d806b2b5 100644 --- a/built_value_generator/lib/src/serializer_source_class.dart +++ b/built_value_generator/lib/src/serializer_source_class.dart @@ -78,15 +78,6 @@ abstract class SerializerSourceClass @memoized String get name => element.name; - @memoized - bool get isNonNullByDefault => element.library.isNonNullableByDefault; - - @memoized - String get orNull => isNonNullByDefault ? '?' : ''; - - @memoized - String get notNull => isNonNullByDefault ? '!' : ''; - @memoized String get wireName { if (isBuiltValue) { @@ -133,7 +124,7 @@ abstract class SerializerSourceClass ? '' : '<' + genericBounds - .map((bound) => bound.isEmpty ? 'Object$orNull' : bound) + .map((bound) => bound.isEmpty ? 'Object?' : bound) .join(', ') + '>'; @@ -328,18 +319,18 @@ class $serializerImplName implements StructuredSerializer<$genericName> { final String wireName = '${escapeString(wireName)}'; @override - Iterable serialize(Serializers serializers, $genericName object, + Iterable serialize(Serializers serializers, $genericName object, {FullType specifiedType = FullType.unspecified}) { - ${fields.isEmpty ? 'return [];' : ''' + ${fields.isEmpty ? 'return [];' : ''' ${_generateGenericsSerializerPreamble()} - final result = [${_generateRequiredFieldSerializers()}]; + final result = [${_generateRequiredFieldSerializers()}]; ${_generateNullableFieldSerializers()} return result; '''} } @override - $genericName deserialize(Serializers serializers, Iterable serialized, + $genericName deserialize(Serializers serializers, Iterable serialized, {FullType specifiedType = FullType.unspecified}) { ${_generateGenericsSerializerPreamble()} $maybeCastFn @@ -348,9 +339,9 @@ class $serializerImplName implements StructuredSerializer<$genericName> { final iterator = serialized.iterator; while (iterator.moveNext()) { - final key = iterator.current$notNull as String; + final key = iterator.current! as String; iterator.moveNext(); - final Object$orNull value = iterator.current; + final Object? value = iterator.current; switch (key) { ${_generateFieldDeserializers()} } @@ -490,7 +481,7 @@ class $serializerImplName implements PrimitiveSerializer<$genericName> { var nullableFields = fields.where((field) => field.isNullable).toList(); if (nullableFields.isEmpty) return ''; - return 'Object$orNull value;' + + return 'Object? value;' + nullableFields.map((field) { var serializeField = '''serializers.serialize( value, @@ -526,7 +517,7 @@ class $serializerImplName implements PrimitiveSerializer<$genericName> { compilationUnit, genericParameters.toBuiltSet()); final cast = field.generateCast(compilationUnit, _genericBoundsAsMap); // If cast exists and is not nullable. - var maybeNotNull = !field.isNullable && cast.isNotEmpty ? notNull : ''; + var maybeNotNull = !field.isNullable && cast.isNotEmpty ? '!' : ''; if (field.builderFieldUsesNestedBuilder) { if (hasBuilder && field.builderFieldIsNullable) { // The manually implemented builder might or might not return a @@ -536,7 +527,7 @@ class $serializerImplName implements PrimitiveSerializer<$genericName> { case '${escapeString(field.wireName)}': var maybeBuilder = result.${field.name}; var fieldValue = serializers.deserialize( - value, specifiedType: $fullType)$notNull $cast; + value, specifiedType: $fullType)! $cast; if (maybeBuilder == null) { result.${field.name} = \$cast(fieldValue.toBuilder()); } else { @@ -552,7 +543,7 @@ case '${escapeString(field.wireName)}': return ''' case '${escapeString(field.wireName)}': result.${field.name}.replace(serializers.deserialize( - value, specifiedType: $fullType)$notNull $looseCast); + value, specifiedType: $fullType)! $looseCast); break; '''; } else { @@ -565,7 +556,7 @@ case '${escapeString(field.wireName)}': } } else { // `cast` is empty if no cast is needed. - var maybeOrNull = field.isNullable && cast.isNotEmpty ? orNull : ''; + var maybeOrNull = field.isNullable && cast.isNotEmpty ? '?' : ''; return ''' case '${escapeString(field.wireName)}': result.${field.name} = serializers.deserialize( diff --git a/built_value_generator/lib/src/serializer_source_class.g.dart b/built_value_generator/lib/src/serializer_source_class.g.dart index b7b0e584..83d4f5ca 100644 --- a/built_value_generator/lib/src/serializer_source_class.g.dart +++ b/built_value_generator/lib/src/serializer_source_class.g.dart @@ -17,9 +17,6 @@ class _$SerializerSourceClass extends SerializerSourceClass { BuiltValueSerializer? __serializerSettings; BuiltValueEnum? __enumClassSettings; String? __name; - bool? __isNonNullByDefault; - String? __orNull; - String? __notNull; String? __wireName; String? __serializerDeclaration; BuiltList? __genericParameters; @@ -68,16 +65,6 @@ class _$SerializerSourceClass extends SerializerSourceClass { @override String get name => __name ??= super.name; - @override - bool get isNonNullByDefault => - __isNonNullByDefault ??= super.isNonNullByDefault; - - @override - String get orNull => __orNull ??= super.orNull; - - @override - String get notNull => __notNull ??= super.notNull; - @override String get wireName => __wireName ??= super.wireName; diff --git a/built_value_generator/lib/src/serializer_source_field.dart b/built_value_generator/lib/src/serializer_source_field.dart index a9148e40..2739f207 100644 --- a/built_value_generator/lib/src/serializer_source_field.dart +++ b/built_value_generator/lib/src/serializer_source_field.dart @@ -73,12 +73,6 @@ abstract class SerializerSourceField annotation.getField('autoCreateNestedBuilder')?.toBoolValue()); } - @memoized - bool get isNonNullByDefault => element.library.isNonNullableByDefault; - - @memoized - String get orNull => isNonNullByDefault ? '?' : ''; - @memoized bool get hasNullableAnnotation => element.getter!.metadata .any((metadata) => metadataToStringValue(metadata) == 'nullable'); @@ -168,7 +162,6 @@ abstract class SerializerSourceField @memoized bool get builderFieldIsNullable { - if (!isNonNullByDefault) return true; if (!builderFieldElementIsValid) return true; return fullBuildElementType == 'dynamic' || @@ -288,7 +281,7 @@ abstract class SerializerSourceField DartTypes.isBuiltCollectionTypeName(bareType) && builderFieldUsesNestedBuilder) { if (bareType == 'BuiltList' || bareType == 'BuiltSet') { - generics = 'Object$orNull'; + generics = 'Object?'; } else if (bareType == 'BuiltMap' || bareType == 'BuiltListMultimap' || bareType == 'BuiltSetMultimap') { diff --git a/built_value_generator/lib/src/serializer_source_field.g.dart b/built_value_generator/lib/src/serializer_source_field.g.dart index 745834af..eae7d0b0 100644 --- a/built_value_generator/lib/src/serializer_source_field.g.dart +++ b/built_value_generator/lib/src/serializer_source_field.g.dart @@ -17,8 +17,6 @@ class _$SerializerSourceField extends SerializerSourceField { final FieldElement? builderElement; bool? __isSerializable; BuiltValueField? __builtValueField; - bool? __isNonNullByDefault; - String? __orNull; bool? __hasNullableAnnotation; bool? __hasNullableType; bool? __isNullable; @@ -61,13 +59,6 @@ class _$SerializerSourceField extends SerializerSourceField { BuiltValueField get builtValueField => __builtValueField ??= super.builtValueField; - @override - bool get isNonNullByDefault => - __isNonNullByDefault ??= super.isNonNullByDefault; - - @override - String get orNull => __orNull ??= super.orNull; - @override bool get hasNullableAnnotation => __hasNullableAnnotation ??= super.hasNullableAnnotation; diff --git a/built_value_generator/lib/src/value_source_class.dart b/built_value_generator/lib/src/value_source_class.dart index 8930c144..eb82a18f 100644 --- a/built_value_generator/lib/src/value_source_class.dart +++ b/built_value_generator/lib/src/value_source_class.dart @@ -52,18 +52,6 @@ abstract class ValueSourceClass ? 'mixin class' : 'class'; - @memoized - bool get isNonNullByDefault => element.library.isNonNullableByDefault; - - @memoized - String get orNull => isNonNullByDefault ? '?' : ''; - - @memoized - String get notNull => isNonNullByDefault ? '!' : ''; - - @memoized - String get late => isNonNullByDefault ? 'late ' : ''; - /// Returns the class name for the generated implementation. If the manually /// maintained class is private then we ignore the underscore here, to avoid /// returning a class name starting `_$_`. @@ -623,7 +611,7 @@ abstract class ValueSourceClass if (!valueClassFactories.any( (factory) => factory.toSource().contains('$implName$_generics'))) { final exampleFactory = 'factory $name(' - '[void Function(${name}Builder$_generics)$orNull updates]) = ' + '[void Function(${name}Builder$_generics)? updates]) = ' '$implName$_generics;'; result.add(GeneratorError((b) => b ..message = @@ -757,12 +745,11 @@ abstract class ValueSourceClass for (var field in fields) { final type = field.typeInCompilationUnit(compilationUnit); result.writeln('@override'); - result.writeln( - 'final $type${field.isNullable ? orNull : ''} ${field.name};'); + result + .writeln('final $type${field.isNullable ? '?' : ''} ${field.name};'); } for (var memoizedGetter in memoizedGetters) { - result.writeln( - '${memoizedGetter.returnType}$orNull __${memoizedGetter.name};'); + result.writeln('${memoizedGetter.returnType}? __${memoizedGetter.name};'); if (memoizedGetter.isNullable) { // Nullable memoiozed getters needs a field to store whether they are // initialized. @@ -777,12 +764,12 @@ abstract class ValueSourceClass // to cast. if (hasBuilder) { result.writeln('factory $implName([' - 'void Function(${name}Builder$_generics)$orNull updates]) ' + 'void Function(${name}Builder$_generics)? updates]) ' '=> (new ${name}Builder$_generics()..update(updates)).build()' ' as $implName$_generics;'); } else { result.writeln('factory $implName([' - 'void Function(${name}Builder$_generics)$orNull updates]) ' + 'void Function(${name}Builder$_generics)? updates]) ' '=> (new ${name}Builder$_generics()..update(updates))._build();'); } @@ -793,8 +780,7 @@ abstract class ValueSourceClass } else { result.write('$implName._({'); result.write(fields.map((field) { - var maybeRequired = - (isNonNullByDefault && !field.isNullable) ? 'required ' : ''; + var maybeRequired = field.isNullable ? '' : 'required '; return '${maybeRequired}this.${field.name}'; }).join(', ')); result.write('}) : super._()'); @@ -901,7 +887,7 @@ abstract class ValueSourceClass } // Builder holds a reference to a value, copies from it lazily. - result.writeln('$implName$_generics$orNull _\$v;'); + result.writeln('$implName$_generics? _\$v;'); result.writeln(''); for (var field in fields) { @@ -919,18 +905,16 @@ abstract class ValueSourceClass final isNullableNestedBuilder = field.isAutoCreateNestedBuilder && field.isNestedBuilder && - (!hasBuilder || - field.builderElementSetterIsNullable || - !isNonNullByDefault); + (!hasBuilder || field.builderElementSetterIsNullable); final hasNullableSetter = !hasBuilder || isNullableNestedBuilder || field.builderElementSetterIsNullable; final getterMaybeOrNull = hasNullableSetter && (!field.isNestedBuilder || !field.isAutoCreateNestedBuilder) - ? orNull + ? '?' : ''; - final setterMaybeOrNull = hasNullableSetter ? orNull : ''; - final maybeLate = !hasNullableSetter ? late : ''; + final setterMaybeOrNull = hasNullableSetter ? '?' : ''; + final maybeLate = !hasNullableSetter ? 'late ' : ''; late String trackedVariable; @@ -1053,7 +1037,7 @@ abstract class ValueSourceClass result.writeln('@override'); result.writeln( - 'void update(void Function(${name}Builder$_generics)$orNull updates) {' + 'void update(void Function(${name}Builder$_generics)? updates) {' ' if (updates != null) updates(this); }'); result.writeln(); @@ -1138,7 +1122,7 @@ abstract class ValueSourceClass // in a nested builder then throw with more information. Otherwise, // just rethrow. result.writeln('} catch (_) {'); - result.writeln('${late}String _\$failedField;'); + result.writeln('late String _\$failedField;'); result.writeln('try {'); result.write(fieldBuilders.keys.map((field) { final fieldBuilder = fieldBuilders[field]; @@ -1202,7 +1186,7 @@ abstract class ValueSourceClass var generateMemoizedHashCode = declaresMemoizedHashCode && comparedFields.isNotEmpty; if (generateMemoizedHashCode) { - result.writeln('int$orNull __hashCode;'); + result.writeln('int? __hashCode;'); } result.writeln('@override'); @@ -1212,7 +1196,7 @@ abstract class ValueSourceClass result.writeln('return ${name.hashCode};'); } else { if (generateMemoizedHashCode) { - result.writeln('if (__hashCode != null) return __hashCode$notNull;'); + result.writeln('if (__hashCode != null) return __hashCode!;'); } // Use a different seed for builders than for values, so they do not have @@ -1274,12 +1258,12 @@ abstract class ValueSourceClass final autoCreatedNestedBuilder = field.isNestedBuilder && settings.autoCreateNestedBuilders; - final maybeOrNull = autoCreatedNestedBuilder ? '' : orNull; + final maybeOrNull = autoCreatedNestedBuilder ? '' : '?'; result.writeln('$type$maybeOrNull get $name;'); // Add `covariant` if we're implementing one or more parent builders. result.writeln('set $name(${interfaces.isEmpty ? '' : 'covariant '} ' - '$type$orNull $name);'); + '$type? $name);'); result.writeln(); } diff --git a/built_value_generator/lib/src/value_source_class.g.dart b/built_value_generator/lib/src/value_source_class.g.dart index 602d0ebf..b1448657 100644 --- a/built_value_generator/lib/src/value_source_class.g.dart +++ b/built_value_generator/lib/src/value_source_class.g.dart @@ -11,10 +11,6 @@ class _$ValueSourceClass extends ValueSourceClass { final InterfaceElement element; ParsedLibraryResult? __parsedLibrary; String? __name; - bool? __isNonNullByDefault; - String? __orNull; - String? __notNull; - String? __late; String? __implName; ClassElement? __builderElement; bool ___builderElement = false; @@ -70,19 +66,6 @@ class _$ValueSourceClass extends ValueSourceClass { @override String get name => __name ??= super.name; - @override - bool get isNonNullByDefault => - __isNonNullByDefault ??= super.isNonNullByDefault; - - @override - String get orNull => __orNull ??= super.orNull; - - @override - String get notNull => __notNull ??= super.notNull; - - @override - String get late => __late ??= super.late; - @override String get implName => __implName ??= super.implName; diff --git a/built_value_generator/lib/src/value_source_field.dart b/built_value_generator/lib/src/value_source_field.dart index c9580e7c..dab30aff 100644 --- a/built_value_generator/lib/src/value_source_field.dart +++ b/built_value_generator/lib/src/value_source_field.dart @@ -13,8 +13,8 @@ import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value_generator/src/dart_types.dart'; import 'package:built_value_generator/src/field_mixin.dart'; -import 'package:built_value_generator/src/fixes.dart'; import 'package:built_value_generator/src/fields.dart' show collectFields; +import 'package:built_value_generator/src/fixes.dart'; import 'package:built_value_generator/src/metadata.dart' show metadataToStringValue; @@ -53,12 +53,6 @@ abstract class ValueSourceField @memoized String get name => element.displayName; - @memoized - bool get isNonNullByDefault => element.library.isNonNullableByDefault; - - @memoized - String get orNull => isNonNullByDefault ? '?' : ''; - @memoized String get type => DartTypes.getName(element.getter!.returnType); @@ -318,23 +312,23 @@ abstract class ValueSourceField 'The current type, "$type", is not allowed because it is mutable.')); } - if (isNonNullByDefault && hasNullableAnnotation) { + if (hasNullableAnnotation) { result.add(GeneratorError((b) => b ..message = 'Remove "@nullable" from field "$name". ' - 'In null safe code, add "?" to the field type instead.')); + 'Add "?" to the field type instead.')); } if (builderFieldExists) { var builderElementTypeOrNull = buildElementType; - if (builderElementTypeIsNullable) builderElementTypeOrNull += orNull; + if (builderElementTypeIsNullable) builderElementTypeOrNull += '?'; final builderType = _toBuilderType(element.type, type); - if (builderElementTypeOrNull != type + orNull && + if (builderElementTypeOrNull != type + '?' && (builderType == null || (builderElementTypeOrNull != builderType && - builderElementTypeOrNull != builderType + orNull))) { + builderElementTypeOrNull != builderType + '?'))) { result.add(GeneratorError((b) => b ..message = 'Make builder field $name have type: ' - '$type$orNull (or, if applicable, builder)')); + '$type? (or, if applicable, builder)')); } } diff --git a/built_value_generator/lib/src/value_source_field.g.dart b/built_value_generator/lib/src/value_source_field.g.dart index 8b79f6c5..fdb2218f 100644 --- a/built_value_generator/lib/src/value_source_field.g.dart +++ b/built_value_generator/lib/src/value_source_field.g.dart @@ -16,8 +16,6 @@ class _$ValueSourceField extends ValueSourceField { @override final FieldElement? builderElement; String? __name; - bool? __isNonNullByDefault; - String? __orNull; String? __type; bool? __isFunctionType; String? __typeWithPrefix; @@ -57,13 +55,6 @@ class _$ValueSourceField extends ValueSourceField { @override String get name => __name ??= super.name; - @override - bool get isNonNullByDefault => - __isNonNullByDefault ??= super.isNonNullByDefault; - - @override - String get orNull => __orNull ??= super.orNull; - @override String get type => __type ??= super.type; diff --git a/built_value_generator/test/built_value_generator_test.dart b/built_value_generator/test/built_value_generator_test.dart index da15f715..a83f209f 100644 --- a/built_value_generator/test/built_value_generator_test.dart +++ b/built_value_generator/test/built_value_generator_test.dart @@ -223,7 +223,7 @@ abstract class Value implements Built { int get x; }'''), contains('1. Remove "@nullable" from field "x". ' - 'In null safe code, add "?" to the field type instead.')); + 'Add "?" to the field type instead.')); }); }); diff --git a/built_value_test/pubspec.yaml b/built_value_test/pubspec.yaml index ee8ee2ef..2069693f 100644 --- a/built_value_test/pubspec.yaml +++ b/built_value_test/pubspec.yaml @@ -11,7 +11,7 @@ topics: - build-runner environment: - sdk: '>=2.12.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: built_value: ^8.7.0 diff --git a/chat_example/pubspec.yaml b/chat_example/pubspec.yaml index 06eb0562..3aba298f 100644 --- a/chat_example/pubspec.yaml +++ b/chat_example/pubspec.yaml @@ -6,7 +6,7 @@ description: > homepage: https://github.com/google/built_value.dart environment: - sdk: '>=2.12.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: built_collection: ^5.0.0 diff --git a/example/lib/polymorphism.dart b/example/lib/polymorphism.dart index 4f4cd4db..194c29f2 100644 --- a/example/lib/polymorphism.dart +++ b/example/lib/polymorphism.dart @@ -65,14 +65,14 @@ abstract class Fish extends Object } /// As with any Built Value, behaviour can be added via mixins. -abstract class Walker { +mixin Walker { int get legs; bool get canWalk => legs > 0; } /// As with any Built Value, behaviour can be added via mixins. -abstract class Swimmer { +mixin Swimmer { int get fins; bool get canSwim => fins > 1; diff --git a/example/lib/polymorphism.g.dart b/example/lib/polymorphism.g.dart index 24d36a16..c5be9a41 100644 --- a/example/lib/polymorphism.g.dart +++ b/example/lib/polymorphism.g.dart @@ -99,7 +99,7 @@ class _$FishSerializer implements StructuredSerializer { } } -abstract class AnimalBuilder { +abstract mixin class AnimalBuilder { void replace(Animal other); void update(void Function(AnimalBuilder) updates); int? get legs; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ab3db7e6..f77c475c 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -5,7 +5,7 @@ description: > homepage: https://github.com/google/built_value.dart environment: - sdk: '>=2.12.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: built_collection: ^5.0.0