Skip to content

Commit

Permalink
fix: copyWith sometimes not working with null (#808)
Browse files Browse the repository at this point in the history
fixes #807
fixes #803
  • Loading branch information
rrousselGit committed Nov 29, 2022
1 parent 3d9a455 commit f785d1e
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 5 deletions.
4 changes: 4 additions & 0 deletions packages/freezed/CHANGELOG.md
@@ -1,3 +1,7 @@
# [Unreleased fix]

Fixes copyWith not working with `null` on some scenarios.

# 2.2.1

Upgrade analyzer
Expand Down
2 changes: 1 addition & 1 deletion packages/freezed/lib/builder.dart
Expand Up @@ -13,7 +13,7 @@ Builder freezed(BuilderOptions options) {
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
''',
options: options,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/freezed/lib/src/templates/parameter_template.dart
@@ -1,9 +1,9 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:build/build.dart';
import 'package:freezed/src/templates/concrete_template.dart';
import 'package:freezed/src/templates/properties.dart';
import 'package:freezed/src/templates/prototypes.dart';
import 'package:freezed/src/tools/type.dart';
import 'package:freezed/src/utils.dart';

class GenericsDefinitionTemplate {
Expand Down Expand Up @@ -70,7 +70,7 @@ class ParametersTemplate {
Future<Parameter> asParameter(ParameterElement e) async {
final value = Parameter(
name: e.name,
isNullable: e.type.nullabilitySuffix == NullabilitySuffix.question,
isNullable: e.type.isNullable,
isDartList: e.type.isDartCoreList,
isDartMap: e.type.isDartCoreMap,
isDartSet: e.type.isDartCoreSet,
Expand Down
4 changes: 2 additions & 2 deletions packages/freezed/lib/src/templates/properties.dart
@@ -1,7 +1,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:build/build.dart';
import 'package:freezed/src/tools/type.dart';
import 'package:source_gen/source_gen.dart';

import '../utils.dart';
Expand Down Expand Up @@ -49,7 +49,7 @@ class Property {

return Property(
name: element.name,
isNullable: element.type.nullabilitySuffix == NullabilitySuffix.question,
isNullable: element.type.isNullable,
isDartList: element.type.isDartCoreList,
isDartMap: element.type.isDartCoreMap,
isDartSet: element.type.isDartCoreSet,
Expand Down
10 changes: 10 additions & 0 deletions packages/freezed/lib/src/tools/type.dart
Expand Up @@ -5,6 +5,16 @@ import 'package:collection/collection.dart';

import 'imports.dart';

extension DartTypeX on DartType {
bool get isNullable {
final that = this;
if (that is TypeParameterType) {
return that.bound.isNullable;
}
return isDynamic || nullabilitySuffix == NullabilitySuffix.question;
}
}

/// Returns the [Element] for a given [DartType]
///
/// this is usually type.element, except if it is a typedef then it is
Expand Down
39 changes: 39 additions & 0 deletions packages/freezed/test/deep_copy_test.dart
Expand Up @@ -5,6 +5,9 @@ import 'package:test/test.dart';

import 'common.dart';
import 'integration/deep_copy.dart';
import 'integration/generic.dart'
show AnyGeneric, NullableGeneric, NonNullableGeneric;
import 'integration/single_class_constructor.dart' show Dynamic;

void main() {
// TODO: copyWith is identical to itself if don't have descendants
Expand Down Expand Up @@ -67,6 +70,42 @@ void main() {
() => company.copyWith.director!.assistant!(name: 'John'),
throwsA(isA<TypeError>()),
);

expect(
Dynamic(foo: 42, bar: 21).copyWith(foo: null, bar: null),
Dynamic(foo: null, bar: null),
);
expect(
Dynamic(foo: 42, bar: 21).copyWith(),
Dynamic(foo: 42, bar: 21),
);

expect(
AnyGeneric<int?>(42).copyWith(value: null),
AnyGeneric<int?>(null),
);
expect(
AnyGeneric<int?>(42).copyWith(),
AnyGeneric<int?>(42),
);

expect(
NullableGeneric<int?>(42).copyWith(value: null),
NullableGeneric<int?>(null),
);
expect(
NullableGeneric<int?>(42).copyWith(),
NullableGeneric<int?>(42),
);

expect(
NonNullableGeneric<int>(42).copyWith(value: 21),
NonNullableGeneric<int>(21),
);
expect(
NonNullableGeneric<int>(42).copyWith(),
NonNullableGeneric<int>(42),
);
});

group('DeepGeneric', () {
Expand Down
15 changes: 15 additions & 0 deletions packages/freezed/test/integration/generic.dart
Expand Up @@ -7,6 +7,21 @@ class Model<T> {
final T value;
}

@freezed
class AnyGeneric<T> with _$AnyGeneric<T> {
factory AnyGeneric(T value) = _AnyGeneric<T>;
}

@freezed
class NullableGeneric<T extends Object?> with _$NullableGeneric<T> {
factory NullableGeneric(T value) = _NullableGeneric<T>;
}

@freezed
class NonNullableGeneric<T extends Object> with _$NonNullableGeneric<T> {
factory NonNullableGeneric(T value) = _NonNullableGeneric<T>;
}

@freezed
class Generic<T extends Model<dynamic>> with _$Generic<T> {
factory Generic(T model) = _Generic<T>;
Expand Down
10 changes: 10 additions & 0 deletions packages/freezed/test/integration/single_class_constructor.dart
@@ -1,10 +1,20 @@
// ignore_for_file: unnecessary_question_mark

import 'dart:async';
import 'dart:collection';

import 'package:freezed_annotation/freezed_annotation.dart';

part 'single_class_constructor.freezed.dart';

@freezed
class Dynamic with _$Dynamic {
factory Dynamic({
dynamic foo,
dynamic? bar,
}) = DynamicFirst;
}

class CustomMap<A, B> extends MapBase<A, B> {
CustomMap(this._source);

Expand Down

0 comments on commit f785d1e

Please sign in to comment.