diff --git a/mobx_codegen/CHANGELOG.md b/mobx_codegen/CHANGELOG.md index e9ed8735..c2641986 100644 --- a/mobx_codegen/CHANGELOG.md +++ b/mobx_codegen/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.5.0 + +- Support `late` observables by [@amondnet](https://github.com/amondnet). fix [#919](https://github.com/mobxjs/mobx.dart/issues/919) + ## 2.4.1 - Adds `useDeepEquality` for creating observables by [@amondnet](https://github.com/amondnet) diff --git a/mobx_codegen/lib/src/store_class_visitor.dart b/mobx_codegen/lib/src/store_class_visitor.dart index 17564bf7..83abf574 100644 --- a/mobx_codegen/lib/src/store_class_visitor.dart +++ b/mobx_codegen/lib/src/store_class_visitor.dart @@ -102,6 +102,7 @@ class StoreClassVisitor extends SimpleElementVisitor { name: element.name, isPrivate: element.isPrivate, isReadOnly: _isObservableReadOnly(element), + isLate: element.isLate, equals: _getEquals(element), ); diff --git a/mobx_codegen/lib/src/template/observable.dart b/mobx_codegen/lib/src/template/observable.dart index c536c69a..68e8efd8 100644 --- a/mobx_codegen/lib/src/template/observable.dart +++ b/mobx_codegen/lib/src/template/observable.dart @@ -11,6 +11,7 @@ class ObservableTemplate { required this.name, this.isReadOnly = false, this.isPrivate = false, + this.isLate = false, this.equals, this.useDeepEquality, }); @@ -21,6 +22,7 @@ class ObservableTemplate { final String name; final bool isPrivate; final bool isReadOnly; + final bool isLate; final ExecutableElement? equals; final bool? useDeepEquality; @@ -53,16 +55,34 @@ class ObservableTemplate { }'''; } + String _buildSetters() { + if (isLate) { + return ''' + bool _${name}IsInitialized = false; + @override - String toString() => """ - late final $atomName = Atom(name: '${storeTemplate.parentTypeName}.$name', context: context); - -${_buildGetters()} + set $name($type value) { + $atomName.reportWrite(value, _${name}IsInitialized ? super.$name : null, () { + super.$name = value; + _${name}IsInitialized = true; + }${equals != null ? ', equals: ${equals!.name}' : ''}); + }'''; + } + return ''' @override set $name($type value) { $atomName.reportWrite(value, super.$name, () { super.$name = value; }${equals != null ? ', equals: ${equals!.name}' : ''}${useDeepEquality != null ? ', useDeepEquality: $useDeepEquality' : ''}); - }"""; + }'''; + } + + @override + String toString() => """ + late final $atomName = Atom(name: '${storeTemplate.parentTypeName}.$name', context: context); + +${_buildGetters()} + +${_buildSetters()}"""; } diff --git a/mobx_codegen/lib/version.dart b/mobx_codegen/lib/version.dart index d2bed9e4..bc245f3f 100644 --- a/mobx_codegen/lib/version.dart +++ b/mobx_codegen/lib/version.dart @@ -1,4 +1,4 @@ // Generated via set_version.dart. !!!DO NOT MODIFY BY HAND!!! /// The current version as per `pubspec.yaml`. -const version = '2.4.1'; +const version = '2.5.0'; diff --git a/mobx_codegen/pubspec.yaml b/mobx_codegen/pubspec.yaml index b14e3cd8..91509440 100644 --- a/mobx_codegen/pubspec.yaml +++ b/mobx_codegen/pubspec.yaml @@ -1,6 +1,6 @@ name: mobx_codegen description: Code generator for MobX that adds support for annotating your code with @observable, @computed, @action and also creating Store classes. -version: 2.4.1 +version: 2.5.0 homepage: https://github.com/mobxjs/mobx.dart issue_tracker: https://github.com/mobxjs/mobx.dart/issues diff --git a/mobx_codegen/test/data/valid_late_variables_output.dart b/mobx_codegen/test/data/valid_late_variables_output.dart index 3fdbde0b..9e280d3c 100644 --- a/mobx_codegen/test/data/valid_late_variables_output.dart +++ b/mobx_codegen/test/data/valid_late_variables_output.dart @@ -8,10 +8,14 @@ mixin _$TestStore on _TestStore, Store { return super.username; } + bool _usernameIsInitialized = false; + @override set username(String value) { - _$usernameAtom.reportWrite(value, super.username, () { + _$usernameAtom + .reportWrite(value, _usernameIsInitialized ? super.username : null, () { super.username = value; + _usernameIsInitialized = true; }); } } diff --git a/mobx_codegen/test/generator_usage_test.dart b/mobx_codegen/test/generator_usage_test.dart index 306b6be5..3a6bb2dd 100644 --- a/mobx_codegen/test/generator_usage_test.dart +++ b/mobx_codegen/test/generator_usage_test.dart @@ -124,6 +124,9 @@ abstract class _TestStore with Store { // ignore: only_throw_errors throw 'TEST ERROR'; } + + @observable + late String lateField; } void main() { @@ -279,4 +282,16 @@ void main() { expect(values, equals(['', 'field1', 'field2'])); }); + + test('setting late fields with action works', () { + final store = TestStore('field1', field2: 'field2'); + + final fields = []; + autorun((_) { + fields.add(store.lateField); + }); + store.lateField = 'field'; + + expect(fields, equals(['field'])); + }); } diff --git a/mobx_codegen/test/generator_usage_test.g.dart b/mobx_codegen/test/generator_usage_test.g.dart index 09d94af6..dff31d23 100644 --- a/mobx_codegen/test/generator_usage_test.g.dart +++ b/mobx_codegen/test/generator_usage_test.g.dart @@ -178,6 +178,26 @@ mixin _$TestStore on _TestStore, Store { }); } + late final _$lateFieldAtom = + Atom(name: '_TestStore.lateField', context: context); + + @override + String get lateField { + _$lateFieldAtom.reportRead(); + return super.lateField; + } + + bool _lateFieldIsInitialized = false; + + @override + set lateField(String value) { + _$lateFieldAtom.reportWrite( + value, _lateFieldIsInitialized ? super.lateField : null, () { + super.lateField = value; + _lateFieldIsInitialized = true; + }); + } + @override ObservableFuture future() { final _$future = super.future(); @@ -262,6 +282,7 @@ batchItem2: ${batchItem2}, batchItem3: ${batchItem3}, batchItem4: ${batchItem4}, errorField: ${errorField}, +lateField: ${lateField}, fields: ${fields}, batchedItems: ${batchedItems} '''; diff --git a/mobx_codegen/test/nested_store.g.dart b/mobx_codegen/test/nested_store.g.dart index 6599ebde..79d54e3e 100644 --- a/mobx_codegen/test/nested_store.g.dart +++ b/mobx_codegen/test/nested_store.g.dart @@ -17,10 +17,13 @@ mixin _$NestedStore on _NestedStore, Store { return super.name; } + bool _nameIsInitialized = false; + @override set name(String value) { - _$nameAtom.reportWrite(value, super.name, () { + _$nameAtom.reportWrite(value, _nameIsInitialized ? super.name : null, () { super.name = value; + _nameIsInitialized = true; }); } diff --git a/mobx_codegen/test/store_with_custom_context.g.dart b/mobx_codegen/test/store_with_custom_context.g.dart index aaea811b..17666201 100644 --- a/mobx_codegen/test/store_with_custom_context.g.dart +++ b/mobx_codegen/test/store_with_custom_context.g.dart @@ -18,10 +18,13 @@ mixin _$CustomContextStore on _CustomContextStore, Store { return super.name; } + bool _nameIsInitialized = false; + @override set name(String value) { - _$nameAtom.reportWrite(value, super.name, () { + _$nameAtom.reportWrite(value, _nameIsInitialized ? super.name : null, () { super.name = value; + _nameIsInitialized = true; }); }