diff --git a/mobx_codegen/CHANGELOG.md b/mobx_codegen/CHANGELOG.md index aa392b1c..1fc3d8b7 100644 --- a/mobx_codegen/CHANGELOG.md +++ b/mobx_codegen/CHANGELOG.md @@ -6,6 +6,7 @@ - Add support for analyzer 9.0.0 by migrating to the Element API (from deprecated Element2 API) - Require `analyzer: ^9.0.0` (drop support for analyzer <9.0.0) +- **FIX**: useDeepEquality is not being correctly passed to the generated code. ## 2.7.5 diff --git a/mobx_codegen/lib/src/store_class_visitor.dart b/mobx_codegen/lib/src/store_class_visitor.dart index af3afb7f..486a8cd0 100644 --- a/mobx_codegen/lib/src/store_class_visitor.dart +++ b/mobx_codegen/lib/src/store_class_visitor.dart @@ -30,23 +30,34 @@ class StoreClassVisitor extends SimpleElementVisitor2 { this.typeNameFinder, this.options, ) : errors = StoreClassCodegenErrors(publicTypeName) { - _storeTemplate = template - ..typeParams.templates.addAll(userClass.typeParameters - .map((type) => typeParamTemplate(type, typeNameFinder))) - ..typeArgs.templates.addAll( - userClass.typeParameters.map((t) => t.name).whereType()) - ..parentTypeName = userClass.name! - ..publicTypeName = publicTypeName; + _storeTemplate = + template + ..typeParams.templates.addAll( + userClass.typeParameters.map( + (type) => typeParamTemplate(type, typeNameFinder), + ), + ) + ..typeArgs.templates.addAll( + userClass.typeParameters.map((t) => t.name).whereType(), + ) + ..parentTypeName = userClass.name! + ..publicTypeName = publicTypeName; } - final _observableChecker = - const TypeChecker.typeNamed(MakeObservable, inPackage: 'mobx'); + final _observableChecker = const TypeChecker.typeNamed( + MakeObservable, + inPackage: 'mobx', + ); - final _computedChecker = - const TypeChecker.typeNamed(ComputedMethod, inPackage: 'mobx'); + final _computedChecker = const TypeChecker.typeNamed( + ComputedMethod, + inPackage: 'mobx', + ); - final _actionChecker = - const TypeChecker.typeNamed(MakeAction, inPackage: 'mobx'); + final _actionChecker = const TypeChecker.typeNamed( + MakeAction, + inPackage: 'mobx', + ); final _asyncChecker = AsyncMethodChecker(); @@ -73,8 +84,10 @@ class StoreClassVisitor extends SimpleElementVisitor2 { @override void visitClassElement(ClassElement element) { if (isMixinStoreClass(element)) { - errors.nonAbstractStoreMixinDeclarations - .addIf(!element.isAbstract, element.name!); + errors.nonAbstractStoreMixinDeclarations.addIf( + !element.isAbstract, + element.name!, + ); } // if the class is annotated to generate toString() method we add the information to the _storeTemplate _storeTemplate.generateToString = hasGeneratedToString(options, element); @@ -109,6 +122,7 @@ class StoreClassVisitor extends SimpleElementVisitor2 { isReadOnly: _isObservableReadOnly(element), isLate: element.isLate, equals: _getEquals(element), + useDeepEquality: _getUseDeepEquality(element), ); _storeTemplate.observables.add(template); @@ -122,24 +136,32 @@ class StoreClassVisitor extends SimpleElementVisitor2 { ?.toBoolValue() ?? false; - ExecutableElement? _getEquals(FieldElement element) => _observableChecker - .firstAnnotationOfExact(element) - ?.getField('equals') - ?.toFunctionValue(); + ExecutableElement? _getEquals(FieldElement element) => + _observableChecker + .firstAnnotationOfExact(element) + ?.getField('equals') + ?.toFunctionValue(); + + bool? _getUseDeepEquality(FieldElement element) => + _observableChecker + .firstAnnotationOfExact(element) + ?.getField('useDeepEquality') + ?.toBoolValue(); bool _fieldIsNotValid(FieldElement element) => _any([ - errors.staticObservables.addIf(element.isStatic, element.name!), - errors.finalObservables.addIf(element.isFinal, element.name!), - errors.invalidReadOnlyAnnotations.addIf( - _isObservableReadOnly(element) && element.setter!.isPublic, - element.name!, - ), - ]); - - bool? _isComputedKeepAlive(Element element) => _computedChecker - .firstAnnotationOfExact(element) - ?.getField('keepAlive') - ?.toBoolValue(); + errors.staticObservables.addIf(element.isStatic, element.name!), + errors.finalObservables.addIf(element.isFinal, element.name!), + errors.invalidReadOnlyAnnotations.addIf( + _isObservableReadOnly(element) && element.setter!.isPublic, + element.name!, + ), + ]); + + bool? _isComputedKeepAlive(Element element) => + _computedChecker + .firstAnnotationOfExact(element) + ?.getField('keepAlive') + ?.toBoolValue(); @override void visitGetterElement(GetterElement element) => @@ -170,12 +192,13 @@ class StoreClassVisitor extends SimpleElementVisitor2 { } final template = ComputedTemplate( - computedName: '_\$${element.name}Computed', - storeTemplate: _storeTemplate, - name: element.name!, - type: typeNameFinder.findGetterTypeName(element), - isPrivate: element.isPrivate, - isKeepAlive: _isComputedKeepAlive(element)); + computedName: '_\$${element.name}Computed', + storeTemplate: _storeTemplate, + name: element.name!, + type: typeNameFinder.findGetterTypeName(element), + isPrivate: element.isPrivate, + isKeepAlive: _isComputedKeepAlive(element), + ); _storeTemplate.computeds.add(template); return; @@ -245,21 +268,22 @@ class StoreClassVisitor extends SimpleElementVisitor2 { } bool _asyncObservableIsNotValid(MethodElement method) => _any([ - errors.staticMethods.addIf(method.isStatic, method.name!), - errors.nonAsyncMethods.addIf( - !_asyncChecker.returnsFuture(method) && - !_asyncChecker.returnsStream(method), - method.name!), - ]); + errors.staticMethods.addIf(method.isStatic, method.name!), + errors.nonAsyncMethods.addIf( + !_asyncChecker.returnsFuture(method) && + !_asyncChecker.returnsStream(method), + method.name!, + ), + ]); bool _actionIsNotValid(MethodElement element) => _any([ - errors.staticMethods.addIf(element.isStatic, element.name!), - errors.asyncGeneratorActions.addIf( - element.fragments.any((fragment) => fragment.isAsynchronous) && - element.fragments.any((fragment) => fragment.isGenerator), - element.name!, - ), - ]); + errors.staticMethods.addIf(element.isStatic, element.name!), + errors.asyncGeneratorActions.addIf( + element.fragments.any((fragment) => fragment.isAsynchronous) && + element.fragments.any((fragment) => fragment.isGenerator), + element.name!, + ), + ]); /// Runs validations after all elements have been visited. void validate() { @@ -272,17 +296,19 @@ class StoreClassVisitor extends SimpleElementVisitor2 { } bool _isInvalidPublicSetterOnReadOnlyObservable( - PropertyAccessorElement publicSetter) => - _storeTemplate.observables.templates.any( - (template) => - template.name.nonPrivateName == publicSetter.displayName && - template.isReadOnly, - ); + PropertyAccessorElement publicSetter, + ) => _storeTemplate.observables.templates.any( + (template) => + template.name.nonPrivateName == publicSetter.displayName && + template.isReadOnly, + ); } const _storeMixinChecker = TypeChecker.typeNamed(Store, inPackage: 'mobx'); -const _toStringAnnotationChecker = - TypeChecker.typeNamed(StoreConfig, inPackage: 'mobx'); +const _toStringAnnotationChecker = TypeChecker.typeNamed( + StoreConfig, + inPackage: 'mobx', +); bool isMixinStoreClass(ClassElement classElement) => classElement.mixins.any(_storeMixinChecker.isExactlyType); @@ -295,8 +321,9 @@ bool hasGeneratedToString(BuilderOptions options, ClassElement? classElement) { const fieldKey = 'hasToString'; if (classElement != null && isStoreConfigAnnotatedStoreClass(classElement)) { - final annotation = - _toStringAnnotationChecker.firstAnnotationOfExact(classElement); + final annotation = _toStringAnnotationChecker.firstAnnotationOfExact( + classElement, + ); return annotation?.getField(fieldKey)?.toBoolValue() ?? false; } diff --git a/mobx_codegen/lib/src/template/observable.dart b/mobx_codegen/lib/src/template/observable.dart index 68e8efd8..e36d3e9a 100644 --- a/mobx_codegen/lib/src/template/observable.dart +++ b/mobx_codegen/lib/src/template/observable.dart @@ -65,7 +65,7 @@ class ObservableTemplate { $atomName.reportWrite(value, _${name}IsInitialized ? super.$name : null, () { super.$name = value; _${name}IsInitialized = true; - }${equals != null ? ', equals: ${equals!.name}' : ''}); + }${equals != null ? ', equals: ${equals!.name}' : ''}${useDeepEquality != null ? ', useDeepEquality: $useDeepEquality' : ''}); }'''; } diff --git a/mobx_codegen/pubspec.yaml b/mobx_codegen/pubspec.yaml index eeeaa541..7896c22a 100644 --- a/mobx_codegen/pubspec.yaml +++ b/mobx_codegen/pubspec.yaml @@ -11,7 +11,7 @@ topics: - codegen environment: - sdk: '>=3.7.0 <4.0.0' + sdk: ">=3.7.0 <4.0.0" dependencies: analyzer: '>=9.0.0 < 13.0.0' @@ -19,7 +19,7 @@ dependencies: meta: ^1.3.0 mobx: ^2.6.0 path: ^1.8.0 - source_gen: '>=3.0.0 < 5.0.0' + source_gen: ">=3.0.0 < 5.0.0" dev_dependencies: build_runner: ^2.6.0 diff --git a/mobx_codegen/test/data/annotations_test_class_output.dart b/mobx_codegen/test/data/annotations_test_class_output.dart index 1ac25da1..c0232546 100644 --- a/mobx_codegen/test/data/annotations_test_class_output.dart +++ b/mobx_codegen/test/data/annotations_test_class_output.dart @@ -14,7 +14,7 @@ mixin _$AnnotationsTestClass on AnnotationsTestClassBase, Store { set foo(String value) { _$fooAtom.reportWrite(value, super.foo, () { super.foo = value; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/data/invalid_action_multiple_output.txt b/mobx_codegen/test/data/invalid_action_multiple_output.txt index 75a7132f..7ff1624c 100644 --- a/mobx_codegen/test/data/invalid_action_multiple_output.txt +++ b/mobx_codegen/test/data/invalid_action_multiple_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "Test" observable. Changes needed: - 1. Remove @action annotation for members "firstName" and "lastName". They only apply to methods. + 1. Remove @action annotation for members "firstName" and "lastName". They only apply to methods. \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_computed_multiple_output.txt b/mobx_codegen/test/data/invalid_computed_multiple_output.txt index bce8f2df..534911e0 100644 --- a/mobx_codegen/test/data/invalid_computed_multiple_output.txt +++ b/mobx_codegen/test/data/invalid_computed_multiple_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "Test" observable. Changes needed: - 1. Remove @computed annotation for members "firstName", "lastName" and "changeName". They only apply to property-getters. + 1. Remove @computed annotation for members "firstName", "lastName" and "changeName". They only apply to property-getters. \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_computed_single_output.txt b/mobx_codegen/test/data/invalid_computed_single_output.txt index 6ca2e3ae..1e29a94d 100644 --- a/mobx_codegen/test/data/invalid_computed_single_output.txt +++ b/mobx_codegen/test/data/invalid_computed_single_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "Test" observable. Changes needed: - 1. Remove @computed annotation for the member "firstName". They only apply to property-getters. + 1. Remove @computed annotation for the member "firstName". They only apply to property-getters. \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_mixin_store_output.txt b/mobx_codegen/test/data/invalid_mixin_store_output.txt index e2db0a64..4b015460 100644 --- a/mobx_codegen/test/data/invalid_mixin_store_output.txt +++ b/mobx_codegen/test/data/invalid_mixin_store_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "NonAbstractUser" observable. Changes needed: 1. Classes that use the Store mixin must be marked abstract. Affected classes: "NonAbstractUserBase". \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_multiple_setter_on_readonly_observable_output.txt b/mobx_codegen/test/data/invalid_multiple_setter_on_readonly_observable_output.txt index 05e1bd2a..60f3bbcd 100644 --- a/mobx_codegen/test/data/invalid_multiple_setter_on_readonly_observable_output.txt +++ b/mobx_codegen/test/data/invalid_multiple_setter_on_readonly_observable_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "CounterStore" observable. Changes needed: 1. Must not define a public setter to a readonly field. Remove members "counter" and "counter2". \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_observable_multiple_output.txt b/mobx_codegen/test/data/invalid_observable_multiple_output.txt index 0ed424df..d85417dc 100644 --- a/mobx_codegen/test/data/invalid_observable_multiple_output.txt +++ b/mobx_codegen/test/data/invalid_observable_multiple_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "Test" observable. Changes needed: 1. Remove @observable annotation for members "fullName" and "fullNameUppercased". They only apply to fields. \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_observable_single_output.txt b/mobx_codegen/test/data/invalid_observable_single_output.txt index ca32b400..cb8bd25d 100644 --- a/mobx_codegen/test/data/invalid_observable_single_output.txt +++ b/mobx_codegen/test/data/invalid_observable_single_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "Test" observable. Changes needed: 1. Remove @observable annotation for the member "fullName". They only apply to fields. \ No newline at end of file diff --git a/mobx_codegen/test/data/invalid_output.txt b/mobx_codegen/test/data/invalid_output.txt index 96f21271..35d82ed2 100644 --- a/mobx_codegen/test/data/invalid_output.txt +++ b/mobx_codegen/test/data/invalid_output.txt @@ -1,3 +1,4 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "User" observable. Changes needed: 1. Remove static modifier from the field "foobar". 2. Remove static modifier from the method "getUser". diff --git a/mobx_codegen/test/data/invalid_single_setter_on_readonly_observable_output.txt b/mobx_codegen/test/data/invalid_single_setter_on_readonly_observable_output.txt index 4fc8cf97..175b6413 100644 --- a/mobx_codegen/test/data/invalid_single_setter_on_readonly_observable_output.txt +++ b/mobx_codegen/test/data/invalid_single_setter_on_readonly_observable_output.txt @@ -1,2 +1,3 @@ +Generating .g.dart: StoreGenerator on lib/generator_sample.dart: Could not make class "CounterStore" observable. Changes needed: 1. Must not define a public setter to a readonly field. Remove the member "counter". \ No newline at end of file diff --git a/mobx_codegen/test/data/valid_generic_store_output.dart b/mobx_codegen/test/data/valid_generic_store_output.dart index 5c2d7de0..1f069536 100644 --- a/mobx_codegen/test/data/valid_generic_store_output.dart +++ b/mobx_codegen/test/data/valid_generic_store_output.dart @@ -11,7 +11,7 @@ mixin _$Item on _Item, Store { set value1(T value) { _$value1Atom.reportWrite(value, super.value1, () { super.value1 = value; - }); + }, useDeepEquality: true); } late final _$value2Atom = Atom(name: '_Item.value2', context: context); @@ -26,7 +26,7 @@ mixin _$Item on _Item, Store { set value2(T? value) { _$value2Atom.reportWrite(value, super.value2, () { super.value2 = value; - }); + }, useDeepEquality: true); } late final _$values1Atom = Atom(name: '_Item.values1', context: context); @@ -41,7 +41,7 @@ mixin _$Item on _Item, Store { set values1(List value) { _$values1Atom.reportWrite(value, super.values1, () { super.values1 = value; - }); + }, useDeepEquality: true); } late final _$values2Atom = Atom(name: '_Item.values2', context: context); @@ -56,6 +56,6 @@ mixin _$Item on _Item, Store { set values2(List value) { _$values2Atom.reportWrite(value, super.values2, () { super.values2 = value; - }); + }, useDeepEquality: true); } } diff --git a/mobx_codegen/test/data/valid_import_prefixed_input.dart b/mobx_codegen/test/data/valid_import_prefixed_input.dart index ac1baa10..2a3f5832 100644 --- a/mobx_codegen/test/data/valid_import_prefixed_input.dart +++ b/mobx_codegen/test/data/valid_import_prefixed_input.dart @@ -91,14 +91,18 @@ abstract class UserBase with Store { Future futureBiographyNullable() async => biographyNullable; @observable - Stream loadDirectory(String arg1, - {T directory}) async* { + Stream loadDirectory( + String arg1, { + T directory, + }) async* { yield directory; } @observable - Stream loadDirectoryNullable(String? arg1, - {T? directory}) async* { + Stream loadDirectoryNullable( + String? arg1, { + T? directory, + }) async* { yield directory; } } diff --git a/mobx_codegen/test/data/valid_import_prefixed_output.dart b/mobx_codegen/test/data/valid_import_prefixed_output.dart index f184fca9..696422f4 100644 --- a/mobx_codegen/test/data/valid_import_prefixed_output.dart +++ b/mobx_codegen/test/data/valid_import_prefixed_output.dart @@ -3,9 +3,9 @@ mixin _$User on UserBase, Store { @override io.File get biographyNotes => (_$biographyNotesComputed ??= Computed( - () => super.biographyNotes, - name: 'UserBase.biographyNotes', - )).value; + () => super.biographyNotes, + name: 'UserBase.biographyNotes', + )).value; Computed? _$biographyNotesNullableComputed; @override @@ -27,7 +27,7 @@ mixin _$User on UserBase, Store { set names(List value) { _$namesAtom.reportWrite(value, super.names, () { super.names = value; - }); + }, useDeepEquality: true); } late final _$filesAtom = Atom(name: 'UserBase.files', context: context); @@ -42,7 +42,7 @@ mixin _$User on UserBase, Store { set files(List value) { _$filesAtom.reportWrite(value, super.files, () { super.files = value; - }); + }, useDeepEquality: true); } late final _$filesNullableAtom = Atom( @@ -60,7 +60,7 @@ mixin _$User on UserBase, Store { set filesNullable(List value) { _$filesNullableAtom.reportWrite(value, super.filesNullable, () { super.filesNullable = value; - }); + }, useDeepEquality: true); } late final _$processesAtom = Atom( @@ -78,7 +78,7 @@ mixin _$User on UserBase, Store { set processes(List value) { _$processesAtom.reportWrite(value, super.processes, () { super.processes = value; - }); + }, useDeepEquality: true); } late final _$biographyAtom = Atom( @@ -96,7 +96,7 @@ mixin _$User on UserBase, Store { set biography(io.File value) { _$biographyAtom.reportWrite(value, super.biography, () { super.biography = value; - }); + }, useDeepEquality: true); } late final _$biographyNullableAtom = Atom( @@ -114,7 +114,7 @@ mixin _$User on UserBase, Store { set biographyNullable(io.File? value) { _$biographyNullableAtom.reportWrite(value, super.biographyNullable, () { super.biographyNullable = value; - }); + }, useDeepEquality: true); } late final _$friendWithImplicitTypeArgumentAtom = Atom( @@ -136,6 +136,7 @@ mixin _$User on UserBase, Store { () { super.friendWithImplicitTypeArgument = value; }, + useDeepEquality: true, ); } @@ -158,6 +159,7 @@ mixin _$User on UserBase, Store { () { super.friendWithImplicitTypeArgumentNullable = value; }, + useDeepEquality: true, ); } @@ -180,6 +182,7 @@ mixin _$User on UserBase, Store { () { super.friendWithExplicitTypeArgument = value; }, + useDeepEquality: true, ); } @@ -202,6 +205,7 @@ mixin _$User on UserBase, Store { () { super.friendWithExplicitTypeArgumentNullable = value; }, + useDeepEquality: true, ); } @@ -217,7 +221,7 @@ mixin _$User on UserBase, Store { set callback(void Function(io.File, {T another}) value) { _$callbackAtom.reportWrite(value, super.callback, () { super.callback = value; - }); + }, useDeepEquality: true); } late final _$callbackNullableAtom = Atom( @@ -235,7 +239,7 @@ mixin _$User on UserBase, Store { set callbackNullable(void Function(io.File?, {T? another}) value) { _$callbackNullableAtom.reportWrite(value, super.callbackNullable, () { super.callbackNullable = value; - }); + }, useDeepEquality: true); } late final _$callback2Atom = Atom( @@ -253,7 +257,7 @@ mixin _$User on UserBase, Store { set callback2(io.File Function(String, [int, io.File]) value) { _$callback2Atom.reportWrite(value, super.callback2, () { super.callback2 = value; - }); + }, useDeepEquality: true); } late final _$callback2NullableAtom = Atom( @@ -271,7 +275,7 @@ mixin _$User on UserBase, Store { set callback2Nullable(io.File? Function(String?, [int?, io.File?]) value) { _$callback2NullableAtom.reportWrite(value, super.callback2Nullable, () { super.callback2Nullable = value; - }); + }, useDeepEquality: true); } late final _$localTypedefCallbackAtom = Atom( @@ -293,6 +297,7 @@ mixin _$User on UserBase, Store { () { super.localTypedefCallback = value; }, + useDeepEquality: true, ); } @@ -315,6 +320,7 @@ mixin _$User on UserBase, Store { () { super.localTypedefCallbackNullable = value; }, + useDeepEquality: true, ); } @@ -337,6 +343,7 @@ mixin _$User on UserBase, Store { () { super.prefixedTypedefCallback = value; }, + useDeepEquality: true, ); } @@ -359,6 +366,7 @@ mixin _$User on UserBase, Store { () { super.prefixedTypedefCallbackNullable = value; }, + useDeepEquality: true, ); } diff --git a/mobx_codegen/test/data/valid_input.dart b/mobx_codegen/test/data/valid_input.dart index 5290e280..bb4c96ec 100644 --- a/mobx_codegen/test/data/valid_input.dart +++ b/mobx_codegen/test/data/valid_input.dart @@ -52,8 +52,8 @@ abstract class UserBase with Store { @observable List _testUsers = []; -// @observable -// List backColor = List.generate(60, (i) => Colors.transparent); + // @observable + // List backColor = List.generate(60, (i) => Colors.transparent); @computed String get fullName => '$firstName $middleName $lastName'; diff --git a/mobx_codegen/test/data/valid_input_annotation_store_config_has_to_string.dart b/mobx_codegen/test/data/valid_input_annotation_store_config_has_to_string.dart index 77f2ce83..60305426 100644 --- a/mobx_codegen/test/data/valid_input_annotation_store_config_has_to_string.dart +++ b/mobx_codegen/test/data/valid_input_annotation_store_config_has_to_string.dart @@ -51,8 +51,8 @@ abstract class UserBase with Store { @observable List _testUsers = []; -// @observable -// List backColor = List.generate(60, (i) => Colors.transparent); + // @observable + // List backColor = List.generate(60, (i) => Colors.transparent); @computed String get fullName => '$firstName $middleName $lastName'; diff --git a/mobx_codegen/test/data/valid_keep_alive_computed_output.dart b/mobx_codegen/test/data/valid_keep_alive_computed_output.dart index fbf8e702..f1fa2064 100644 --- a/mobx_codegen/test/data/valid_keep_alive_computed_output.dart +++ b/mobx_codegen/test/data/valid_keep_alive_computed_output.dart @@ -31,6 +31,7 @@ mixin _$TestStore on _TestStore, Store { super.username = value; _usernameIsInitialized = true; }, + useDeepEquality: true, ); } } diff --git a/mobx_codegen/test/data/valid_late_variables_output.dart b/mobx_codegen/test/data/valid_late_variables_output.dart index a9ab7d22..bec5e5db 100644 --- a/mobx_codegen/test/data/valid_late_variables_output.dart +++ b/mobx_codegen/test/data/valid_late_variables_output.dart @@ -21,6 +21,7 @@ mixin _$TestStore on _TestStore, Store { super.username = value; _usernameIsInitialized = true; }, + useDeepEquality: true, ); } } diff --git a/mobx_codegen/test/data/valid_output.dart b/mobx_codegen/test/data/valid_output.dart index 6b77ff70..67aab4b0 100644 --- a/mobx_codegen/test/data/valid_output.dart +++ b/mobx_codegen/test/data/valid_output.dart @@ -3,9 +3,9 @@ mixin _$User on UserBase, Store { @override String get fullName => (_$fullNameComputed ??= Computed( - () => super.fullName, - name: 'UserBase.fullName', - )).value; + () => super.fullName, + name: 'UserBase.fullName', + )).value; Computed? _$fullNameNullableComputed; @override @@ -30,7 +30,7 @@ mixin _$User on UserBase, Store { set firstName(String value) { _$firstNameAtom.reportWrite(value, super.firstName, () { super.firstName = value; - }); + }, useDeepEquality: true); } late final _$firstNameNullableAtom = Atom( @@ -48,7 +48,7 @@ mixin _$User on UserBase, Store { set firstNameNullable(String? value) { _$firstNameNullableAtom.reportWrite(value, super.firstNameNullable, () { super.firstNameNullable = value; - }); + }, useDeepEquality: true); } late final _$middleNameAtom = Atom( @@ -66,7 +66,7 @@ mixin _$User on UserBase, Store { set middleName(String value) { _$middleNameAtom.reportWrite(value, super.middleName, () { super.middleName = value; - }); + }, useDeepEquality: true); } late final _$lastNameAtom = Atom(name: 'UserBase.lastName', context: context); @@ -81,7 +81,7 @@ mixin _$User on UserBase, Store { set lastName(String value) { _$lastNameAtom.reportWrite(value, super.lastName, () { super.lastName = value; - }); + }, useDeepEquality: true); } late final _$friendAtom = Atom(name: 'UserBase.friend', context: context); @@ -96,7 +96,7 @@ mixin _$User on UserBase, Store { set friend(User value) { _$friendAtom.reportWrite(value, super.friend, () { super.friend = value; - }); + }, useDeepEquality: true); } late final _$friendNullableAtom = Atom( @@ -114,7 +114,7 @@ mixin _$User on UserBase, Store { set friendNullable(User? value) { _$friendNullableAtom.reportWrite(value, super.friendNullable, () { super.friendNullable = value; - }); + }, useDeepEquality: true); } late final _$callbackAtom = Atom(name: 'UserBase.callback', context: context); @@ -129,7 +129,7 @@ mixin _$User on UserBase, Store { set callback(void Function() value) { _$callbackAtom.reportWrite(value, super.callback, () { super.callback = value; - }); + }, useDeepEquality: true); } late final _$callbackNullableAtom = Atom( @@ -147,7 +147,7 @@ mixin _$User on UserBase, Store { set callbackNullable(void Function() value) { _$callbackNullableAtom.reportWrite(value, super.callbackNullable, () { super.callbackNullable = value; - }); + }, useDeepEquality: true); } late final _$callback2Atom = Atom( @@ -165,7 +165,7 @@ mixin _$User on UserBase, Store { set callback2(VoidCallback value) { _$callback2Atom.reportWrite(value, super.callback2, () { super.callback2 = value; - }); + }, useDeepEquality: true); } late final _$callback2NullableAtom = Atom( @@ -183,7 +183,7 @@ mixin _$User on UserBase, Store { set callback2Nullable(VoidCallback? value) { _$callback2NullableAtom.reportWrite(value, super.callback2Nullable, () { super.callback2Nullable = value; - }); + }, useDeepEquality: true); } late final _$_testUsersAtom = Atom( @@ -201,7 +201,7 @@ mixin _$User on UserBase, Store { set _testUsers(List value) { _$_testUsersAtom.reportWrite(value, super._testUsers, () { super._testUsers = value; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/data/valid_output_annotation_store_config_has_to_string.dart b/mobx_codegen/test/data/valid_output_annotation_store_config_has_to_string.dart index 048e0501..c672658f 100644 --- a/mobx_codegen/test/data/valid_output_annotation_store_config_has_to_string.dart +++ b/mobx_codegen/test/data/valid_output_annotation_store_config_has_to_string.dart @@ -3,9 +3,9 @@ mixin _$User on UserBase, Store { @override String get fullName => (_$fullNameComputed ??= Computed( - () => super.fullName, - name: 'UserBase.fullName', - )).value; + () => super.fullName, + name: 'UserBase.fullName', + )).value; Computed? _$fullNameNullableComputed; @override @@ -30,7 +30,7 @@ mixin _$User on UserBase, Store { set firstName(String value) { _$firstNameAtom.reportWrite(value, super.firstName, () { super.firstName = value; - }); + }, useDeepEquality: true); } late final _$firstNameNullableAtom = Atom( @@ -48,7 +48,7 @@ mixin _$User on UserBase, Store { set firstNameNullable(String? value) { _$firstNameNullableAtom.reportWrite(value, super.firstNameNullable, () { super.firstNameNullable = value; - }); + }, useDeepEquality: true); } late final _$middleNameAtom = Atom( @@ -66,7 +66,7 @@ mixin _$User on UserBase, Store { set middleName(String value) { _$middleNameAtom.reportWrite(value, super.middleName, () { super.middleName = value; - }); + }, useDeepEquality: true); } late final _$lastNameAtom = Atom(name: 'UserBase.lastName', context: context); @@ -81,7 +81,7 @@ mixin _$User on UserBase, Store { set lastName(String value) { _$lastNameAtom.reportWrite(value, super.lastName, () { super.lastName = value; - }); + }, useDeepEquality: true); } late final _$friendAtom = Atom(name: 'UserBase.friend', context: context); @@ -96,7 +96,7 @@ mixin _$User on UserBase, Store { set friend(User value) { _$friendAtom.reportWrite(value, super.friend, () { super.friend = value; - }); + }, useDeepEquality: true); } late final _$friendNullableAtom = Atom( @@ -114,7 +114,7 @@ mixin _$User on UserBase, Store { set friendNullable(User? value) { _$friendNullableAtom.reportWrite(value, super.friendNullable, () { super.friendNullable = value; - }); + }, useDeepEquality: true); } late final _$callbackAtom = Atom(name: 'UserBase.callback', context: context); @@ -129,7 +129,7 @@ mixin _$User on UserBase, Store { set callback(void Function() value) { _$callbackAtom.reportWrite(value, super.callback, () { super.callback = value; - }); + }, useDeepEquality: true); } late final _$callbackNullableAtom = Atom( @@ -147,7 +147,7 @@ mixin _$User on UserBase, Store { set callbackNullable(void Function() value) { _$callbackNullableAtom.reportWrite(value, super.callbackNullable, () { super.callbackNullable = value; - }); + }, useDeepEquality: true); } late final _$callback2Atom = Atom( @@ -165,7 +165,7 @@ mixin _$User on UserBase, Store { set callback2(VoidCallback value) { _$callback2Atom.reportWrite(value, super.callback2, () { super.callback2 = value; - }); + }, useDeepEquality: true); } late final _$callback2NullableAtom = Atom( @@ -183,7 +183,7 @@ mixin _$User on UserBase, Store { set callback2Nullable(VoidCallback? value) { _$callback2NullableAtom.reportWrite(value, super.callback2Nullable, () { super.callback2Nullable = value; - }); + }, useDeepEquality: true); } late final _$_testUsersAtom = Atom( @@ -201,7 +201,7 @@ mixin _$User on UserBase, Store { set _testUsers(List value) { _$_testUsersAtom.reportWrite(value, super._testUsers, () { super._testUsers = value; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/data/with_extension_output.dart b/mobx_codegen/test/data/with_extension_output.dart index 6c94ca85..8cb51b6d 100644 --- a/mobx_codegen/test/data/with_extension_output.dart +++ b/mobx_codegen/test/data/with_extension_output.dart @@ -14,7 +14,7 @@ mixin _$Foo on _Foo, Store { _$nameAtom.reportWrite(value, _nameIsInitialized ? super.name : null, () { super.name = value; _nameIsInitialized = true; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/generator_usage_test.g.dart b/mobx_codegen/test/generator_usage_test.g.dart index 0b814d83..83fe6016 100644 --- a/mobx_codegen/test/generator_usage_test.g.dart +++ b/mobx_codegen/test/generator_usage_test.g.dart @@ -12,23 +12,30 @@ mixin _$TestStore on _TestStore, Store { Computed? _$fieldsComputed; @override - String get fields => (_$fieldsComputed ??= - Computed(() => super.fields, name: '_TestStore.fields')) - .value; + String get fields => + (_$fieldsComputed ??= Computed( + () => super.fields, + name: '_TestStore.fields', + )) + .value; Computed? _$fieldsKeepAliveComputed; @override - String get fieldsKeepAlive => (_$fieldsKeepAliveComputed ??= Computed( - () => super.fieldsKeepAlive, - name: '_TestStore.fieldsKeepAlive', - keepAlive: true)) - .value; + String get fieldsKeepAlive => + (_$fieldsKeepAliveComputed ??= Computed( + () => super.fieldsKeepAlive, + name: '_TestStore.fieldsKeepAlive', + keepAlive: true, + )) + .value; Computed? _$batchedItemsComputed; @override String get batchedItems => - (_$batchedItemsComputed ??= Computed(() => super.batchedItems, - name: '_TestStore.batchedItems')) + (_$batchedItemsComputed ??= Computed( + () => super.batchedItems, + name: '_TestStore.batchedItems', + )) .value; late final _$field1Atom = Atom(name: '_TestStore.field1', context: context); @@ -43,7 +50,7 @@ mixin _$TestStore on _TestStore, Store { set field1(String value) { _$field1Atom.reportWrite(value, super.field1, () { super.field1 = value; - }); + }, useDeepEquality: true); } late final _$field2Atom = Atom(name: '_TestStore.field2', context: context); @@ -58,7 +65,7 @@ mixin _$TestStore on _TestStore, Store { set field2(String? value) { _$field2Atom.reportWrite(value, super.field2, () { super.field2 = value; - }); + }, useDeepEquality: true); } late final _$stuffAtom = Atom(name: '_TestStore.stuff', context: context); @@ -73,7 +80,7 @@ mixin _$TestStore on _TestStore, Store { set stuff(String value) { _$stuffAtom.reportWrite(value, super.stuff, () { super.stuff = value; - }); + }, useDeepEquality: true); } late final _$alwaysAtom = Atom(name: '_TestStore.always', context: context); @@ -86,9 +93,15 @@ mixin _$TestStore on _TestStore, Store { @override set always(String value) { - _$alwaysAtom.reportWrite(value, super.always, () { - super.always = value; - }, equals: observableAlwaysNotEqual); + _$alwaysAtom.reportWrite( + value, + super.always, + () { + super.always = value; + }, + equals: observableAlwaysNotEqual, + useDeepEquality: true, + ); } late final _$customAtom = Atom(name: '_TestStore.custom', context: context); @@ -101,13 +114,21 @@ mixin _$TestStore on _TestStore, Store { @override set custom(String value) { - _$customAtom.reportWrite(value, super.custom, () { - super.custom = value; - }, equals: customEquals); + _$customAtom.reportWrite( + value, + super.custom, + () { + super.custom = value; + }, + equals: customEquals, + useDeepEquality: true, + ); } - late final _$batchItem1Atom = - Atom(name: '_TestStore.batchItem1', context: context); + late final _$batchItem1Atom = Atom( + name: '_TestStore.batchItem1', + context: context, + ); @override String get batchItem1 { @@ -119,11 +140,13 @@ mixin _$TestStore on _TestStore, Store { set batchItem1(String value) { _$batchItem1Atom.reportWrite(value, super.batchItem1, () { super.batchItem1 = value; - }); + }, useDeepEquality: true); } - late final _$batchItem2Atom = - Atom(name: '_TestStore.batchItem2', context: context); + late final _$batchItem2Atom = Atom( + name: '_TestStore.batchItem2', + context: context, + ); @override String get batchItem2 { @@ -135,11 +158,13 @@ mixin _$TestStore on _TestStore, Store { set batchItem2(String value) { _$batchItem2Atom.reportWrite(value, super.batchItem2, () { super.batchItem2 = value; - }); + }, useDeepEquality: true); } - late final _$batchItem3Atom = - Atom(name: '_TestStore.batchItem3', context: context); + late final _$batchItem3Atom = Atom( + name: '_TestStore.batchItem3', + context: context, + ); @override String get batchItem3 { @@ -151,11 +176,13 @@ mixin _$TestStore on _TestStore, Store { set batchItem3(String value) { _$batchItem3Atom.reportWrite(value, super.batchItem3, () { super.batchItem3 = value; - }); + }, useDeepEquality: true); } - late final _$batchItem4Atom = - Atom(name: '_TestStore.batchItem4', context: context); + late final _$batchItem4Atom = Atom( + name: '_TestStore.batchItem4', + context: context, + ); @override String get batchItem4 { @@ -167,11 +194,13 @@ mixin _$TestStore on _TestStore, Store { set batchItem4(String value) { _$batchItem4Atom.reportWrite(value, super.batchItem4, () { super.batchItem4 = value; - }); + }, useDeepEquality: true); } - late final _$errorFieldAtom = - Atom(name: '_TestStore.errorField', context: context); + late final _$errorFieldAtom = Atom( + name: '_TestStore.errorField', + context: context, + ); @override String get errorField { @@ -183,11 +212,13 @@ mixin _$TestStore on _TestStore, Store { set errorField(String value) { _$errorFieldAtom.reportWrite(value, super.errorField, () { super.errorField = value; - }); + }, useDeepEquality: true); } - late final _$lateFieldAtom = - Atom(name: '_TestStore.lateField', context: context); + late final _$lateFieldAtom = Atom( + name: '_TestStore.lateField', + context: context, + ); @override String get lateField { @@ -200,10 +231,14 @@ mixin _$TestStore on _TestStore, Store { @override set lateField(String value) { _$lateFieldAtom.reportWrite( - value, _lateFieldIsInitialized ? super.lateField : null, () { - super.lateField = value; - _lateFieldIsInitialized = true; - }); + value, + _lateFieldIsInitialized ? super.lateField : null, + () { + super.lateField = value; + _lateFieldIsInitialized = true; + }, + useDeepEquality: true, + ); } @override @@ -230,46 +265,58 @@ mixin _$TestStore on _TestStore, Store { return ObservableStream(_$stream, context: context); } - late final _$loadStuffAsyncAction = - AsyncAction('_TestStore.loadStuff', context: context); + late final _$loadStuffAsyncAction = AsyncAction( + '_TestStore.loadStuff', + context: context, + ); @override Future loadStuff() { return _$loadStuffAsyncAction.run(() => super.loadStuff()); } - late final _$loadStuff2AsyncAction = - AsyncAction('_TestStore.loadStuff2', context: context); + late final _$loadStuff2AsyncAction = AsyncAction( + '_TestStore.loadStuff2', + context: context, + ); @override ObservableFuture loadStuff2() { return ObservableFuture( - _$loadStuff2AsyncAction.run(() => super.loadStuff2())); + _$loadStuff2AsyncAction.run(() => super.loadStuff2()), + ); } - late final _$batchedChangesAsyncAction = - AsyncAction('_TestStore.batchedChanges', context: context); + late final _$batchedChangesAsyncAction = AsyncAction( + '_TestStore.batchedChanges', + context: context, + ); @override Future batchedChanges() { return _$batchedChangesAsyncAction.run(() => super.batchedChanges()); } - late final _$throwsErrorAsyncAction = - AsyncAction('_TestStore.throwsError', context: context); + late final _$throwsErrorAsyncAction = AsyncAction( + '_TestStore.throwsError', + context: context, + ); @override Future throwsError() { return _$throwsErrorAsyncAction.run(() => super.throwsError()); } - late final _$_TestStoreActionController = - ActionController(name: '_TestStore', context: context); + late final _$_TestStoreActionController = ActionController( + name: '_TestStore', + context: context, + ); @override void setFields(String field1, String field2) { - final _$actionInfo = - _$_TestStoreActionController.startAction(name: '_TestStore.setFields'); + final _$actionInfo = _$_TestStoreActionController.startAction( + name: '_TestStore.setFields', + ); try { return super.setFields(field1, field2); } finally { diff --git a/mobx_codegen/test/nested_store.g.dart b/mobx_codegen/test/nested_store.g.dart index 79d54e3e..eed04fab 100644 --- a/mobx_codegen/test/nested_store.g.dart +++ b/mobx_codegen/test/nested_store.g.dart @@ -24,7 +24,7 @@ mixin _$NestedStore on _NestedStore, Store { _$nameAtom.reportWrite(value, _nameIsInitialized ? super.name : null, () { super.name = value; _nameIsInitialized = true; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/store_class_visitor_test.dart b/mobx_codegen/test/store_class_visitor_test.dart index 2e6b4821..174cda4a 100644 --- a/mobx_codegen/test/store_class_visitor_test.dart +++ b/mobx_codegen/test/store_class_visitor_test.dart @@ -48,11 +48,12 @@ StoreClassVisitor makeVisitorWithErrors() { ); store.observables.add(readOnlyTemplate); final visitor = StoreClassVisitor( - 'publicTypeName', - ClassElementMock('anotherName'), - store, - LibraryScopedNameFinderFake(), - BuilderOptions.empty); + 'publicTypeName', + ClassElementMock('anotherName'), + store, + LibraryScopedNameFinderFake(), + BuilderOptions.empty, + ); final setter = PropertyAccessorElementMock('name'); visitor.publicSettersCache.add(setter); return visitor; @@ -73,5 +74,101 @@ void main() { true, ); }); + + test( + 'useDeepEquality is included in generated setter when set to true', + () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + useDeepEquality: true, + ); + final output = template.toString(); + expect(output, contains('useDeepEquality: true')); + }, + ); + + test( + 'useDeepEquality is included in generated setter when set to false', + () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + useDeepEquality: false, + ); + final output = template.toString(); + expect(output, contains('useDeepEquality: false')); + }, + ); + + test('useDeepEquality is not included in generated setter when null', () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + useDeepEquality: null, + ); + final output = template.toString(); + expect(output, isNot(contains('useDeepEquality'))); + }); + + test( + 'useDeepEquality is included in generated late field setter when set to true', + () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + isLate: true, + useDeepEquality: true, + ); + final output = template.toString(); + expect(output, contains('useDeepEquality: true')); + }, + ); + + test( + 'useDeepEquality is included in generated late field setter when set to false', + () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + isLate: true, + useDeepEquality: false, + ); + final output = template.toString(); + expect(output, contains('useDeepEquality: false')); + }, + ); + + test( + 'useDeepEquality is not included in generated late field setter when null', + () { + final store = StoreTemplateFake()..parentTypeName = 'TestStore'; + final template = ObservableTemplate( + storeTemplate: store, + type: 'List', + name: 'items', + atomName: '_itemsAtom', + isLate: true, + useDeepEquality: null, + ); + final output = template.toString(); + expect(output, isNot(contains('useDeepEquality'))); + }, + ); }); } diff --git a/mobx_codegen/test/store_with_custom_context.g.dart b/mobx_codegen/test/store_with_custom_context.g.dart index 17666201..2c71dc14 100644 --- a/mobx_codegen/test/store_with_custom_context.g.dart +++ b/mobx_codegen/test/store_with_custom_context.g.dart @@ -9,8 +9,10 @@ part of 'store_with_custom_context.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic, no_leading_underscores_for_local_identifiers mixin _$CustomContextStore on _CustomContextStore, Store { - late final _$nameAtom = - Atom(name: '_CustomContextStore.name', context: context); + late final _$nameAtom = Atom( + name: '_CustomContextStore.name', + context: context, + ); @override String get name { @@ -25,7 +27,7 @@ mixin _$CustomContextStore on _CustomContextStore, Store { _$nameAtom.reportWrite(value, _nameIsInitialized ? super.name : null, () { super.name = value; _nameIsInitialized = true; - }); + }, useDeepEquality: true); } @override diff --git a/mobx_codegen/test/test_utils.dart b/mobx_codegen/test/test_utils.dart index b6fd16d9..b1c5e220 100644 --- a/mobx_codegen/test/test_utils.dart +++ b/mobx_codegen/test/test_utils.dart @@ -9,8 +9,11 @@ import 'package:source_gen/source_gen.dart'; import 'package:test/test.dart'; class TestInfo { - const TestInfo( - {required this.description, required this.source, required this.output}); + const TestInfo({ + required this.description, + required this.source, + required this.output, + }); final String description; final String output; @@ -24,9 +27,7 @@ Future generate(String source) async { // classes with the same name in the same library, which will clash. final Builder builder = PartBuilder([StoreGenerator()], '.g.dart'); - final sources = { - '$pkgName|lib/generator_sample.dart': source, - }; + final sources = {'$pkgName|lib/generator_sample.dart': source}; final errors = []; void captureError(LogRecord logRecord) { @@ -34,7 +35,8 @@ Future generate(String source) async { // If we've encountered an exception, print to stderr for easier debugging if (logRecord.error != null) { stderr.writeln( - '${logRecord.message}\n${logRecord.error}${logRecord.stackTrace}'); + '${logRecord.message}\n${logRecord.error}${logRecord.stackTrace}', + ); } errors.add(logRecord.message); @@ -44,15 +46,22 @@ Future generate(String source) async { final readerWriter = TestReaderWriter(rootPackage: pkgName); await readerWriter.testing.loadIsolateSources(); - await testBuilder(builder, sources, - rootPackage: pkgName, readerWriter: readerWriter, onLog: captureError); + await testBuilder( + builder, + sources, + rootPackage: pkgName, + readerWriter: readerWriter, + onLog: captureError, + ); if (errors.isNotEmpty) { return errors.join('\n'); } - final assetId = AssetId(pkgName, - '.dart_tool/build/generated/generator_sample/lib/generator_sample.g.dart'); + final assetId = AssetId( + pkgName, + '.dart_tool/build/generated/generator_sample/lib/generator_sample.g.dart', + ); final assetExists = await readerWriter.canRead(assetId); if (!assetExists) { @@ -64,7 +73,8 @@ Future generate(String source) async { String getFilePath(String filename) { final context = path.Context( - style: Platform.isWindows ? path.Style.windows : path.Style.posix); + style: Platform.isWindows ? path.Style.windows : path.Style.posix, + ); final baseDir = context.dirname(Directory.current.path); final filePath = context.join(baseDir, 'mobx_codegen', 'test', filename);