-
Notifications
You must be signed in to change notification settings - Fork 13
New bloc-related lints #458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
03e7e0d
e618f17
c7faf0b
b5d3e85
cd0e922
78b6a0d
911b7a7
4094c28
0fba727
b816990
8af91e0
2ec49e5
68be7ef
41034b3
b3e78b2
577c203
99c86fe
9156ed7
27f12a2
c627c59
3db10b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -413,6 +413,203 @@ class MyWidget extends StatelessWidget { | |||||
|
|
||||||
| None | ||||||
|
|
||||||
| ### `bloc_class_modifiers` | ||||||
|
|
||||||
| **DO** add `final` or `sealed` modifiers to bloc state, event, and presentation event classes. | ||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyState {} | ||||||
|
|
||||||
| class MyStateInitial extends MyState {} | ||||||
|
|
||||||
| class MyStateLoading extends MyState {} | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| sealed class MyState {} | ||||||
|
|
||||||
| final class MyStateInitial extends MyState {} | ||||||
|
|
||||||
| final class MyStateLoading extends MyState {} | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ### `bloc_const_constructors` | ||||||
|
|
||||||
| **DO** define unnamed const constructors for bloc state, event, and presentation event classes. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto, it would be nice to highlight that this lint works only if bloc is in the same file as states, events etc |
||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyState {} | ||||||
| ``` | ||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyState { | ||||||
| MyState(); | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyState { | ||||||
| const MyState(); | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ### `bloc_related_classes_equatable` | ||||||
|
|
||||||
| **DO** mix in `EquatableMixin` in bloc state, event, and presentation event classes. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is obvious why it is better to use this mixin, but we could add some info about it here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reasoning from the issue can be mentioned or quoted: felangel/equatable#160 |
||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyState { | ||||||
| MyState(this.value); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| final int value; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| import 'package:equatable/equatable.dart'; | ||||||
|
|
||||||
| class MyState with EquatableMixin { | ||||||
| const MyState(this.value); | ||||||
|
|
||||||
| final int value; | ||||||
|
|
||||||
| @override | ||||||
| List<Object?> get props => [value]; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ### `bloc_related_class_naming` | ||||||
|
|
||||||
| **DO** prefix bloc state, event, and presentation event classes with the name of the bloc. | ||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyAwesomeBloc extends Bloc<WrongEvent, SomeState> { | ||||||
| // ... | ||||||
| } | ||||||
|
|
||||||
| class WrongEvent {} | ||||||
|
|
||||||
| class SomeState {} | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyAwesomeBloc extends Bloc<MyAwesomeEvent, MyAwesomeState> { | ||||||
| // ... | ||||||
| } | ||||||
|
|
||||||
| class MyAwesomeEvent {} | ||||||
|
|
||||||
| class MyAwesomeState {} | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ### `bloc_subclasses_naming` | ||||||
|
|
||||||
| **DO** prefix bloc state, event and presentation event subclasses with the name of the base class. | ||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyAwesomeBloc extends Bloc<MyAwesomeEvent, MyAwesomeState> { | ||||||
| // ... | ||||||
| } | ||||||
|
|
||||||
| sealed class MyAwesomeState {} | ||||||
|
|
||||||
| final class SomeState extends MyAwesomeState {} | ||||||
|
|
||||||
| final class AnotherState extends MyAwesomeState {} | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| class MyAwesomeBloc extends Bloc<MyAwesomeEvent, MyAwesomeState> { | ||||||
| // ... | ||||||
| } | ||||||
|
|
||||||
| sealed class MyAwesomeState {} | ||||||
|
|
||||||
| final class MyAwesomeStateInitial extends MyAwesomeState {} | ||||||
|
|
||||||
| final class MyAwesomeStateLoading extends MyAwesomeState {} | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ### `prefer_equatable_mixin` | ||||||
|
|
||||||
| **DO** mix in `EquatableMixin` instead of extending `Equatable`. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So disappointing that a lint is needed for that. |
||||||
|
|
||||||
| **BAD:** | ||||||
|
|
||||||
| ```dart | ||||||
| import 'package:equatable/equatable.dart'; | ||||||
|
|
||||||
| class Foobar extends Equatable { | ||||||
| const Foobar(this.value); | ||||||
|
|
||||||
| final int value; | ||||||
|
|
||||||
| @override | ||||||
| List<Object?> get props => [value]; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| **GOOD:** | ||||||
|
|
||||||
| ```dart | ||||||
| import 'package:equatable/equatable.dart'; | ||||||
|
|
||||||
| class Foobar with EquatableMixin { | ||||||
| const Foobar(this.value); | ||||||
|
|
||||||
| final int value; | ||||||
|
|
||||||
| @override | ||||||
| List<Object?> get props => [value]; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### Configuration | ||||||
|
|
||||||
| None. | ||||||
|
|
||||||
| ## Assists | ||||||
|
|
||||||
| Assists are IDE refactorings not related to a particular issue. They can be triggered by placing your cursor over a relevant piece of code and opening the code actions dialog. For instance, in VSCode this is done with <kbd>ctrl</kbd>+<kbd>.</kbd> or <kbd>⌘</kbd>+<kbd>.</kbd>. | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import 'package:custom_lint_builder/custom_lint_builder.dart'; | ||
|
|
||
| extension TypeCheckers on Never { | ||
| // dart | ||
| static const iterable = TypeChecker.fromUrl('dart:core#Iterable'); | ||
|
|
||
| // equatable | ||
| static const equatable = TypeChecker.fromName( | ||
| 'Equatable', | ||
| packageName: 'equatable', | ||
| ); | ||
| static const equatableMixin = TypeChecker.fromName( | ||
| 'EquatableMixin', | ||
| packageName: 'equatable', | ||
| ); | ||
|
|
||
| // flutter | ||
| static const statelessWidget = TypeChecker.fromName( | ||
| 'StatelessWidget', | ||
| packageName: 'flutter', | ||
| ); | ||
| static const state = TypeChecker.fromName('State', packageName: 'flutter'); | ||
| static const column = TypeChecker.fromName('Column', packageName: 'flutter'); | ||
| static const row = TypeChecker.fromName('Row', packageName: 'flutter'); | ||
| static const wrap = TypeChecker.fromName('Wrap', packageName: 'flutter'); | ||
| static const flex = TypeChecker.fromName('Flex', packageName: 'flutter'); | ||
| static const sliverList = TypeChecker.fromName( | ||
| 'SliverList', | ||
| packageName: 'flutter', | ||
| ); | ||
| static const sliverMainAxisGroup = TypeChecker.fromName( | ||
| 'SliverMainAxisGroup', | ||
| packageName: 'flutter', | ||
| ); | ||
| static const sliverCrossAxisGroup = TypeChecker.fromName( | ||
| 'SliverCrossAxisGroup', | ||
| packageName: 'flutter', | ||
| ); | ||
| static const sliverChildListDelegate = TypeChecker.fromName( | ||
| 'SliverChildListDelegate', | ||
| packageName: 'flutter', | ||
| ); | ||
|
|
||
| static const multiSliver = TypeChecker.fromName( | ||
| 'MultiSliver', | ||
| packageName: 'sliver_tools', | ||
| ); | ||
|
|
||
| // hooks | ||
| static const hookWidget = TypeChecker.fromName( | ||
| 'HookWidget', | ||
| packageName: 'flutter_hooks', | ||
| ); | ||
| static const hookBuilder = TypeChecker.fromName( | ||
| 'HookBuilder', | ||
| packageName: 'flutter_hooks', | ||
| ); | ||
| static const hookConsumer = TypeChecker.fromName( | ||
| 'HookConsumer', | ||
| packageName: 'hooks_riverpod', | ||
| ); | ||
| static const hookConsumerWidget = TypeChecker.fromName( | ||
| 'HookConsumerWidget', | ||
| packageName: 'hooks_riverpod', | ||
| ); | ||
|
|
||
| // bloc | ||
| static const cubit = TypeChecker.fromName('Cubit', packageName: 'bloc'); | ||
| static const bloc = TypeChecker.fromName('Bloc', packageName: 'bloc'); | ||
| static const blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); | ||
| static const blocPresentation = TypeChecker.fromName( | ||
| 'BlocPresentationMixin', | ||
| packageName: 'bloc_presentation', | ||
| ); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.