diff --git a/mobx_lint/CHANGELOG.md b/mobx_lint/CHANGELOG.md new file mode 100644 index 00000000..1ad71e67 --- /dev/null +++ b/mobx_lint/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- add wrap with observer assist by [@amondnet](https://github.com/amondnet) diff --git a/mobx_lint/LICENSE b/mobx_lint/LICENSE new file mode 100644 index 00000000..b26a0c15 --- /dev/null +++ b/mobx_lint/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 MobX + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mobx_lint/README.md b/mobx_lint/README.md new file mode 100644 index 00000000..64a5446c --- /dev/null +++ b/mobx_lint/README.md @@ -0,0 +1,52 @@ +mobx_lint is a developer tool for users of mobx, designed to help stop common issues and simplify repetitive tasks. + +mobx_lint adds various warnings with quick fixes and refactoring options, such as: + +- Refactor wrap a widget with Observer + +## Installing mobx_lint + +mobx_lint is implemented using [custom_lint]. As such, it uses custom_lint's installation logic. +Long story short: + +- Add both mobx_lint and custom_lint to your `pubspec.yaml`: + ```yaml + dev_dependencies: + custom_lint: + mobx_lint: + ``` +- Enable `custom_lint`'s plugin in your `analysis_options.yaml`: + + ```yaml + analyzer: + plugins: + - custom_lint + ``` + +## Running mobx_lint in the terminal/CI + +Custom lint rules created by mobx_lint may not show-up in `dart analyze`. +To fix this, you can run a custom command line: `custom_lint`. + +Since your project should already have custom_lint installed +(cf [installing mobx_lint](#installing-mobx_lint)), then you should be +able to run: + +```sh +dart run custom_lint +``` + +Alternatively, you can globally install `custom_lint`: + +```sh +# Install custom_lint for all projects +dart pub global activate custom_lint +# run custom_lint's command line in a project +custom_lint +``` + +## All assists + +### Wrap widgets with a `Consumer` + +![Wrap with Consumer sample](resources/wrap_with_observer.gif) diff --git a/mobx_lint/analysis_options.yaml b/mobx_lint/analysis_options.yaml new file mode 100644 index 00000000..dee8927a --- /dev/null +++ b/mobx_lint/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/mobx_lint/lib/mobx_lint.dart b/mobx_lint/lib/mobx_lint.dart new file mode 100644 index 00000000..0e3e47fa --- /dev/null +++ b/mobx_lint/lib/mobx_lint.dart @@ -0,0 +1,17 @@ +library mobx_lint; + +import 'package:custom_lint_builder/custom_lint_builder.dart'; + +import 'src/assists/wrap_with_observer.dart'; + +PluginBase createPlugin() => _MobxPlugin(); + +class _MobxPlugin extends PluginBase { + @override + List getLintRules(CustomLintConfigs configs) => []; + + @override + List getAssists() => [ + WrapWithObserver(), + ]; +} diff --git a/mobx_lint/lib/src/assists/wrap_with_observer.dart b/mobx_lint/lib/src/assists/wrap_with_observer.dart new file mode 100644 index 00000000..105f7554 --- /dev/null +++ b/mobx_lint/lib/src/assists/wrap_with_observer.dart @@ -0,0 +1,45 @@ +import 'package:analyzer/source/source_range.dart'; +import 'package:custom_lint_builder/custom_lint_builder.dart'; +import 'package:mobx_lint/src/mobx_custom_lint.dart'; + +import '../mobx_types.dart'; + +/// Right above "wrap in builder" +const wrapPriority = 28; + +class WrapWithObserver extends MobxAssist { + WrapWithObserver(); + + @override + void run( + CustomLintResolver resolver, + ChangeReporter reporter, + CustomLintContext context, + SourceRange target, + ) { + context.registry.addInstanceCreationExpression((node) { + // Select from "new" to the opening bracket + if (!target.intersects(node.constructorName.sourceRange)) return; + + final createdType = node.constructorName.type.type; + + if (createdType == null || + !widgetType.isAssignableFromType(createdType)) { + return; + } + + final changeBuilder = reporter.createChangeBuilder( + message: 'Wrap with Observer', + priority: wrapPriority, + ); + + changeBuilder.addDartFileEdit((builder) { + builder.addSimpleInsertion( + node.offset, + 'Observer(builder: (context) { return ', + ); + builder.addSimpleInsertion(node.end, '; },)'); + }); + }); + } +} diff --git a/mobx_lint/lib/src/mobx_custom_lint.dart b/mobx_lint/lib/src/mobx_custom_lint.dart new file mode 100644 index 00000000..6d347253 --- /dev/null +++ b/mobx_lint/lib/src/mobx_custom_lint.dart @@ -0,0 +1,13 @@ +import 'package:analyzer/source/source_range.dart'; +import 'package:custom_lint_builder/custom_lint_builder.dart'; + +abstract class MobxAssist extends DartAssist { + @override + Future startUp( + CustomLintResolver resolver, + CustomLintContext context, + SourceRange target, + ) async { + await super.startUp(resolver, context, target); + } +} diff --git a/mobx_lint/lib/src/mobx_types.dart b/mobx_lint/lib/src/mobx_types.dart new file mode 100644 index 00000000..6bb4dc8e --- /dev/null +++ b/mobx_lint/lib/src/mobx_types.dart @@ -0,0 +1,4 @@ +import 'package:custom_lint_builder/custom_lint_builder.dart'; + +/// [TypeChecker] from `Widget` from Flutter +const widgetType = TypeChecker.fromName('Widget', packageName: 'flutter'); \ No newline at end of file diff --git a/mobx_lint/pubspec.yaml b/mobx_lint/pubspec.yaml new file mode 100644 index 00000000..a07a78c4 --- /dev/null +++ b/mobx_lint/pubspec.yaml @@ -0,0 +1,19 @@ +name: mobx_lint +description: A starting point for Dart libraries or applications. +version: 1.0.0 +# repository: https://github.com/my_org/my_repo + +environment: + sdk: ">=2.16.0 <3.0.0" + +dependencies: + analyzer: ">=6.0.0 <7.0.0" + analyzer_plugin: ^0.11.2 + collection: ^1.16.0 + custom_lint_builder: ^0.5.2 + meta: ^1.7.0 + path: ^1.8.1 + mobx: ^2.2.0 +dev_dependencies: + lints: ^2.0.0 + test: ^1.21.0 diff --git a/mobx_lint/resources/wrap_with_observer.gif b/mobx_lint/resources/wrap_with_observer.gif new file mode 100644 index 00000000..441ffd55 Binary files /dev/null and b/mobx_lint/resources/wrap_with_observer.gif differ