|
| 1 | +import 'package:meta/meta.dart'; |
| 2 | +import 'package:meta/meta_meta.dart'; |
| 3 | +import 'package:grumpy_annotations/grumpy_annotations.dart'; |
| 4 | + |
| 5 | +/// {@template initializer} |
| 6 | +/// Marks a method as the *initialization entrypoint* of a class. |
| 7 | +/// |
| 8 | +/// This annotation is meant for frameworks or patterns where the constructor |
| 9 | +/// is not the right place to run setup logic (e.g. Flutter `State.initState`). |
| 10 | +/// |
| 11 | +/// If a class declares a method annotated with `@initializer`, then that method |
| 12 | +/// becomes the place where all [MustCallInConstructor]-annotated methods must |
| 13 | +/// be invoked. |
| 14 | +/// |
| 15 | +/// In other words: |
| 16 | +/// |
| 17 | +/// - **With an initializer:** required calls move from the constructor to the |
| 18 | +/// `@initializer` method. |
| 19 | +/// - **Without an initializer:** required calls must still happen in the |
| 20 | +/// constructor (default behavior of [MustCallInConstructor]). |
| 21 | +/// |
| 22 | +/// The “called anywhere in the inheritance chain satisfies subclasses” rule |
| 23 | +/// still applies: if a superclass initializer performs the required calls, |
| 24 | +/// subclasses do not need to repeat them. |
| 25 | +/// |
| 26 | +/// Example usage in a Flutter `State` class: |
| 27 | +/// ```dart |
| 28 | +/// class MyWidgetState extends State<MyWidget> with SomeMixin { |
| 29 | +/// @override |
| 30 | +/// @initializer |
| 31 | +/// void initState() { |
| 32 | +/// super.initState(); |
| 33 | +/// |
| 34 | +/// someMixinSetup(); // This method is annotated with [MustCallInConstructor] in SomeMixin |
| 35 | +/// } |
| 36 | +/// } |
| 37 | +/// ``` |
| 38 | +/// |
| 39 | +/// Flutter `State` objects often require setup in `initState()` rather than |
| 40 | +/// constructors. Annotate `initState()` with `@initializer`, and annotate the |
| 41 | +/// required setup hooks with [MustCallInConstructor] to enforce they are |
| 42 | +/// invoked from `initState()`. |
| 43 | +/// |
| 44 | +/// See also: |
| 45 | +/// - [MustCallInConstructor] for marking required setup methods. |
| 46 | +/// |
| 47 | +/// {@endtemplate} |
| 48 | +@immutable |
| 49 | +@Target({TargetKind.method}) |
| 50 | +class Initializer { |
| 51 | + /// {@macro initializer} |
| 52 | + const Initializer(); |
| 53 | +} |
| 54 | + |
| 55 | +/// {@macro initializer} |
| 56 | +const initializer = Initializer(); |
0 commit comments