diff --git a/lib/main.dart b/lib/main.dart index d997dbe4..a6f55fad 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,40 +3,34 @@ import 'package:analysis_server_plugin/registry.dart'; import 'package:solid_lints/src/common/parameter_parser/analysis_options_loader.dart'; import 'package:solid_lints/src/lints/avoid_debug_print_in_release/avoid_debug_print_in_release_rule.dart'; import 'package:solid_lints/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart'; -import 'package:solid_lints/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart'; import 'package:solid_lints/src/lints/avoid_global_state/avoid_global_state_rule.dart'; +import 'package:solid_lints/src/lints/avoid_late_keyword/avoid_late_keyword_rule.dart'; import 'package:solid_lints/src/lints/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart'; import 'package:solid_lints/src/lints/avoid_returning_widgets/avoid_returning_widgets_rule.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_return_variable/avoid_unnecessary_return_variable_rule.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_setstate/avoid_unnecessary_set_state_rule.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart'; -import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart'; import 'package:solid_lints/src/lints/avoid_unrelated_type_assertions/avoid_unrelated_type_assertions_rule.dart'; import 'package:solid_lints/src/lints/avoid_unused_parameters/avoid_unused_parameters_rule.dart'; import 'package:solid_lints/src/lints/avoid_using_api/avoid_using_api_rule.dart'; import 'package:solid_lints/src/lints/cyclomatic_complexity/cyclomatic_complexity_rule.dart'; import 'package:solid_lints/src/lints/double_literal_format/double_literal_format_rule.dart'; -import 'package:solid_lints/src/lints/double_literal_format/fixes/double_literal_format_fix.dart'; import 'package:solid_lints/src/lints/function_lines_of_code/function_lines_of_code_rule.dart'; import 'package:solid_lints/src/lints/member_ordering/member_ordering_rule.dart'; -import 'package:solid_lints/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart'; import 'package:solid_lints/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart'; import 'package:solid_lints/src/lints/newline_before_return/newline_before_return_rule.dart'; import 'package:solid_lints/src/lints/no_empty_block/no_empty_block_rule.dart'; import 'package:solid_lints/src/lints/no_equal_then_else/no_equal_then_else_rule.dart'; import 'package:solid_lints/src/lints/no_magic_number/no_magic_number_rule.dart'; import 'package:solid_lints/src/lints/number_of_parameters/number_of_parameters_rule.dart'; -import 'package:solid_lints/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart'; import 'package:solid_lints/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart'; import 'package:solid_lints/src/lints/prefer_early_return/prefer_early_return_rule.dart'; -import 'package:solid_lints/src/lints/prefer_first/fixes/prefer_first_fix.dart'; import 'package:solid_lints/src/lints/prefer_first/prefer_first_rule.dart'; -import 'package:solid_lints/src/lints/prefer_last/fixes/prefer_last_fix.dart'; import 'package:solid_lints/src/lints/prefer_last/prefer_last_rule.dart'; import 'package:solid_lints/src/lints/prefer_match_file_name/prefer_match_file_name_rule.dart'; import 'package:solid_lints/src/lints/proper_super_calls/proper_super_calls_rule.dart'; -import 'package:solid_lints/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart'; import 'package:solid_lints/src/lints/use_nearest_context/use_nearest_context_rule.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; /// The entry point for the Solid Lints analyser server plugin. /// @@ -56,90 +50,45 @@ class SolidLintsPlugin extends Plugin { void register(PluginRegistry registry) { final analysisLoader = AnalysisOptionsLoader(); - final avoidUnnecessaryTypeAssertionsRule = - AvoidUnnecessaryTypeAssertionsRule(); - final doubleLiteralFormatRule = DoubleLiteralFormatRule(); - final preferFirstRule = PreferFirstRule(); - final preferConditionalExpressionsRule = PreferConditionalExpressionsRule( - analysisOptionsLoader: analysisLoader, - ); - final preferLastRule = PreferLastRule(); - final lintRules = [ + AvoidDebugPrintInReleaseRule(), AvoidFinalWithGetterRule(), AvoidGlobalStateRule(), + AvoidLateKeywordRule(analysisOptionsLoader: analysisLoader), AvoidNonNullAssertionRule(analysisOptionsLoader: analysisLoader), - avoidUnnecessaryTypeAssertionsRule, - AvoidDebugPrintInReleaseRule(), - doubleLiteralFormatRule, - ProperSuperCallsRule(), - NamedParametersOrderingRule(analysisOptionsLoader: analysisLoader), AvoidReturningWidgetsRule(analysisOptionsLoader: analysisLoader), - MemberOrderingRule(analysisOptionsLoader: analysisLoader), - AvoidUnusedParametersRule(analysisOptionsLoader: analysisLoader), - NumberOfParametersRule(analysisOptionsLoader: analysisLoader), - FunctionLinesOfCodeRule(analysisOptionsLoader: analysisLoader), - CyclomaticComplexityRule(analysisOptionsLoader: analysisLoader), - NoEmptyBlockRule(analysisOptionsLoader: analysisLoader), - UseNearestContextRule(), - NoMagicNumberRule(analysisOptionsLoader: analysisLoader), - AvoidUsingApiRule(analysisOptionsLoader: analysisLoader), - preferFirstRule, - preferConditionalExpressionsRule, - preferLastRule, - PreferMatchFileNameRule(analysisOptionsLoader: analysisLoader), - // TODO: Add more lint rules and use analysisLoader - // for rules that need parameters - // For example: `CyclomaticComplexityRule(analysisLoader)` AvoidUnnecessaryReturnVariableRule(), AvoidUnnecessarySetStateRule(), + AvoidUnnecessaryTypeAssertionsRule(), AvoidUnrelatedTypeAssertionsRule(), + AvoidUnusedParametersRule(analysisOptionsLoader: analysisLoader), + AvoidUsingApiRule(analysisOptionsLoader: analysisLoader), + CyclomaticComplexityRule(analysisOptionsLoader: analysisLoader), + DoubleLiteralFormatRule(), + FunctionLinesOfCodeRule(analysisOptionsLoader: analysisLoader), + MemberOrderingRule(analysisOptionsLoader: analysisLoader), + NamedParametersOrderingRule(analysisOptionsLoader: analysisLoader), NewlineBeforeReturnRule(), + NoEmptyBlockRule(analysisOptionsLoader: analysisLoader), NoEqualThenElseRule(), + NoMagicNumberRule(analysisOptionsLoader: analysisLoader), + NumberOfParametersRule(analysisOptionsLoader: analysisLoader), + PreferConditionalExpressionsRule(analysisOptionsLoader: analysisLoader), PreferEarlyReturnRule(), + PreferFirstRule(), + PreferLastRule(), + PreferMatchFileNameRule(analysisOptionsLoader: analysisLoader), + ProperSuperCallsRule(), + UseNearestContextRule(), ]; for (final lintRule in lintRules) { registry.registerLintRule(lintRule); + if (lintRule is RuleWithFixes) { + for (final entry in (lintRule as RuleWithFixes).fixesForCodes) { + registry.registerFixForRule(entry.key, entry.value); + } + } } - - for (final code in doubleLiteralFormatRule.diagnosticCodes) { - registry.registerFixForRule(code, DoubleLiteralFormatFix.new); - } - - registry.registerFixForRule( - AvoidFinalWithGetterRule.code, - AvoidFinalWithGetterFix.new, - ); - - registry.registerFixForRule( - avoidUnnecessaryTypeAssertionsRule.diagnosticCode, - AvoidUnnecessaryTypeAssertionsFix.new, - ); - - registry.registerFixForRule( - UseNearestContextRule.code, - RenameNearestContextParameterFix.new, - ); - - registry.registerFixForRule( - preferFirstRule.diagnosticCode, - PreferFirstFix.new, - ); - - registry.registerFixForRule( - preferLastRule.diagnosticCode, - PreferLastFix.new, - ); - - registry.registerFixForRule( - preferConditionalExpressionsRule.diagnosticCode, - PreferConditionalExpressionsFix.new, - ); - - registry.registerFixForRule( - NamedParametersOrderingRule.code, - NamedParametersOrderingFix.new, - ); } } diff --git a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart b/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart index 727e3dfe..f06218f9 100644 --- a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart +++ b/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart @@ -2,7 +2,9 @@ import 'package:analyzer/analysis_rule/analysis_rule.dart'; import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart'; import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; /// Avoid using final private fields with getters. /// @@ -30,7 +32,7 @@ import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/avoid_fin /// } /// ``` /// -class AvoidFinalWithGetterRule extends AnalysisRule { +class AvoidFinalWithGetterRule extends AnalysisRule implements RuleWithFixes { /// This lint rule represents /// the error whether we use final private fields with getters. static const lintName = 'avoid_final_with_getter'; @@ -44,11 +46,16 @@ class AvoidFinalWithGetterRule extends AnalysisRule { /// Creates a new instance of [AvoidFinalWithGetterRule] AvoidFinalWithGetterRule() - : super(name: lintName, description: code.problemMessage); + : super(name: lintName, description: code.problemMessage); @override LintCode get diagnosticCode => code; + @override + FixesForCodes get fixesForCodes => const [ + MapEntry(code, AvoidFinalWithGetterFix.new), + ]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart b/lib/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart index 906c934b..7148ee55 100644 --- a/lib/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart +++ b/lib/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart @@ -2,15 +2,18 @@ import 'package:analyzer/analysis_rule/analysis_rule.dart'; import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/visitors/unnecessary_is_expression_visitor.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/visitors/unnecessary_where_type_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; /// Warns about unnecessary usage of `is` and `whereType` operators. /// /// ### Example: /// {@macro solid_lints.avoid_unnecessary_type_assertions.example_is} /// {@macro solid_lints.avoid_unnecessary_type_assertions.example_where} -class AvoidUnnecessaryTypeAssertionsRule extends AnalysisRule { +class AvoidUnnecessaryTypeAssertionsRule extends AnalysisRule + implements RuleWithFixes { /// The name of 'is' operator static const operatorIsName = 'is'; @@ -26,9 +29,6 @@ class AvoidUnnecessaryTypeAssertionsRule extends AnalysisRule { "Unnecessary usage of the {0}.", ); - @override - DiagnosticCode get diagnosticCode => _unnecessaryTypeAssertionsCode; - /// Creates a new instance of [AvoidUnnecessaryTypeAssertionsRule] AvoidUnnecessaryTypeAssertionsRule() : super( @@ -36,6 +36,17 @@ class AvoidUnnecessaryTypeAssertionsRule extends AnalysisRule { description: "Unnecessary usage of typecast operators.", ); + @override + DiagnosticCode get diagnosticCode => _unnecessaryTypeAssertionsCode; + + @override + FixesForCodes get fixesForCodes => const [ + MapEntry( + _unnecessaryTypeAssertionsCode, + AvoidUnnecessaryTypeAssertionsFix.new, + ), + ]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/double_literal_format/double_literal_format_rule.dart b/lib/src/lints/double_literal_format/double_literal_format_rule.dart index d90d3726..5fb7806e 100644 --- a/lib/src/lints/double_literal_format/double_literal_format_rule.dart +++ b/lib/src/lints/double_literal_format/double_literal_format_rule.dart @@ -2,7 +2,9 @@ import 'package:analyzer/analysis_rule/analysis_rule.dart'; import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/double_literal_format/fixes/double_literal_format_fix.dart'; import 'package:solid_lints/src/lints/double_literal_format/visitors/double_literal_format_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; /// A `double_literal_format` rule which /// checks that double literals should begin with 0. instead of just ., @@ -23,7 +25,8 @@ import 'package:solid_lints/src/lints/double_literal_format/visitors/double_lite /// var a = 5.23, b = 0.16e+5, c = -0.25, d = -0.4e-5; /// ``` /// {@endtemplate} -class DoubleLiteralFormatRule extends MultiAnalysisRule { +class DoubleLiteralFormatRule extends MultiAnalysisRule + implements RuleWithFixes { /// This lint rule represents /// the error whether we use bad formatted double literals. static const lintName = 'double_literal_format'; @@ -96,13 +99,6 @@ class DoubleLiteralFormatRule extends MultiAnalysisRule { uniqueName: 'trailingZero', ); - @override - List get diagnosticCodes => [ - leadingZeroCode, - leadingDecimalCode, - trailingZeroCode, - ]; - /// Creates a new instance of [DoubleLiteralFormatRule] DoubleLiteralFormatRule() : super( @@ -113,6 +109,17 @@ class DoubleLiteralFormatRule extends MultiAnalysisRule { 'should not start with a leading 0', ); + @override + List get diagnosticCodes => [ + leadingZeroCode, + leadingDecimalCode, + trailingZeroCode, + ]; + + @override + FixesForCodes get fixesForCodes => + diagnosticCodes.map((code) => MapEntry(code, DoubleLiteralFormatFix.new)); + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart b/lib/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart index 110ee5de..fd1a1b65 100644 --- a/lib/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart +++ b/lib/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart @@ -1,9 +1,11 @@ import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart'; import 'package:solid_lints/src/lints/named_parameters_ordering/models/named_parameters_ordering_parameters.dart'; import 'package:solid_lints/src/lints/named_parameters_ordering/models/parameter_type.dart'; import 'package:solid_lints/src/lints/named_parameters_ordering/visitors/named_parameters_ordering_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// A lint which allows to enforce a particular named parameter ordering @@ -102,7 +104,8 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// } /// ``` class NamedParametersOrderingRule - extends SolidLintRule { + extends SolidLintRule + implements RuleWithFixes { /// The name of this lint rule. static const lintName = 'named_parameters_ordering'; @@ -112,9 +115,6 @@ class NamedParametersOrderingRule '{0} named parameters should be before {1} named parameters.', ); - @override - LintCode get diagnosticCode => code; - /// Creates a new instance of [NamedParametersOrderingRule]. NamedParametersOrderingRule({ required super.analysisOptionsLoader, @@ -126,6 +126,14 @@ class NamedParametersOrderingRule parametersParser: NamedParametersOrderingParameters.fromJson, ); + @override + LintCode get diagnosticCode => code; + + @override + FixesForCodes get fixesForCodes => const [ + MapEntry(code, NamedParametersOrderingFix.new), + ]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart b/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart index 5f501972..4e7731f5 100644 --- a/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart +++ b/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart @@ -1,8 +1,10 @@ import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart'; import 'package:solid_lints/src/lints/prefer_conditional_expressions/models/prefer_conditional_expressions_parameters.dart'; import 'package:solid_lints/src/lints/prefer_conditional_expressions/visitors/prefer_conditional_expressions_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; import 'package:solid_lints/src/models/solid_lint_rule.dart'; // Inspired by TSLint (https://palantir.github.io/tslint/rules/prefer-conditional-expression/) @@ -56,7 +58,8 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// } /// ``` class PreferConditionalExpressionsRule - extends SolidLintRule { + extends SolidLintRule + implements RuleWithFixes { /// This lint rule represents the error when an if-else statement /// can be simplified to a conditional expression. static const lintName = 'prefer_conditional_expressions'; @@ -66,9 +69,6 @@ class PreferConditionalExpressionsRule 'Prefer conditional expression.', ); - @override - LintCode get diagnosticCode => _code; - /// Creates a new instance of [PreferConditionalExpressionsRule] PreferConditionalExpressionsRule({ required super.analysisOptionsLoader, @@ -78,6 +78,14 @@ class PreferConditionalExpressionsRule parametersParser: PreferConditionalExpressionsParameters.fromJson, ); + @override + LintCode get diagnosticCode => _code; + + @override + FixesForCodes get fixesForCodes => const [ + MapEntry(_code, PreferConditionalExpressionsFix.new), + ]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/prefer_first/prefer_first_rule.dart b/lib/src/lints/prefer_first/prefer_first_rule.dart index b644cffe..ee40ea13 100644 --- a/lib/src/lints/prefer_first/prefer_first_rule.dart +++ b/lib/src/lints/prefer_first/prefer_first_rule.dart @@ -1,7 +1,9 @@ import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/prefer_first/fixes/prefer_first_fix.dart'; import 'package:solid_lints/src/lints/prefer_first/visitors/prefer_first_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// Warns about usage of iterable[0] or iterable.elementAt(0) instead of @@ -25,7 +27,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// /// a.first; // OK /// ``` -class PreferFirstRule extends SolidLintRule { +class PreferFirstRule extends SolidLintRule implements RuleWithFixes { /// This lint rule represents the error if number of /// parameters reaches the maximum value. static const lintName = 'prefer_first'; @@ -35,11 +37,16 @@ class PreferFirstRule extends SolidLintRule { "Use first instead of accessing the element at zero index.", ); + /// Creates a new instance of [PreferFirstRule] + PreferFirstRule() : super(name: lintName, description: _code.problemMessage); + @override LintCode get diagnosticCode => _code; - /// Creates a new instance of [PreferFirstRule] - PreferFirstRule() : super(name: lintName, description: _code.problemMessage); + @override + FixesForCodes get fixesForCodes => const [ + MapEntry(_code, PreferFirstFix.new), + ]; @override void registerNodeProcessors( diff --git a/lib/src/lints/prefer_last/prefer_last_rule.dart b/lib/src/lints/prefer_last/prefer_last_rule.dart index ff75f5ba..07bf81b8 100644 --- a/lib/src/lints/prefer_last/prefer_last_rule.dart +++ b/lib/src/lints/prefer_last/prefer_last_rule.dart @@ -1,7 +1,9 @@ import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/prefer_last/fixes/prefer_last_fix.dart'; import 'package:solid_lints/src/lints/prefer_last/visitors/prefer_last_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// Warns about usage of `iterable[length - 1]` or @@ -25,7 +27,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// /// a.last; // OK /// ``` -class PreferLastRule extends SolidLintRule { +class PreferLastRule extends SolidLintRule implements RuleWithFixes { /// This lint rule represents the error if iterable /// access can be simplified. static const lintName = 'prefer_last'; @@ -41,6 +43,9 @@ class PreferLastRule extends SolidLintRule { @override LintCode get diagnosticCode => _code; + @override + FixesForCodes get fixesForCodes => const [MapEntry(_code, PreferLastFix.new)]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/lints/use_nearest_context/use_nearest_context_rule.dart b/lib/src/lints/use_nearest_context/use_nearest_context_rule.dart index 56af784a..3fab889f 100644 --- a/lib/src/lints/use_nearest_context/use_nearest_context_rule.dart +++ b/lib/src/lints/use_nearest_context/use_nearest_context_rule.dart @@ -2,7 +2,10 @@ import 'package:analyzer/analysis_rule/analysis_rule.dart'; import 'package:analyzer/analysis_rule/rule_context.dart'; import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/error/error.dart'; +import 'package:solid_lints/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart'; +import 'package:solid_lints/src/lints/use_nearest_context/fixes/replace_with_nearest_context_parameter_fix.dart'; import 'package:solid_lints/src/lints/use_nearest_context/visitors/use_nearest_context_visitor.dart'; +import 'package:solid_lints/src/models/rule_with_fixes.dart'; /// A rule which checks that we use BuildContext from the nearest available /// scope. @@ -49,7 +52,7 @@ import 'package:solid_lints/src/lints/use_nearest_context/visitors/use_nearest_c /// } /// ``` /// -class UseNearestContextRule extends AnalysisRule { +class UseNearestContextRule extends AnalysisRule implements RuleWithFixes { /// This lint rule represents the error if BuildContext is used not from the /// nearest available scope static const lintName = 'use_nearest_context'; @@ -62,14 +65,20 @@ class UseNearestContextRule extends AnalysisRule { /// Creates a new instance of [UseNearestContextRule]. UseNearestContextRule() - : super( - name: lintName, - description: code.problemMessage, - ); + : super( + name: lintName, + description: code.problemMessage, + ); @override LintCode get diagnosticCode => code; + @override + FixesForCodes get fixesForCodes => const [ + MapEntry(code, RenameNearestContextParameterFix.new), + MapEntry(code, ReplaceWithNearestContextParameterFix.new), + ]; + @override void registerNodeProcessors( RuleVisitorRegistry registry, diff --git a/lib/src/models/rule_with_fixes.dart b/lib/src/models/rule_with_fixes.dart new file mode 100644 index 00000000..2be5ca98 --- /dev/null +++ b/lib/src/models/rule_with_fixes.dart @@ -0,0 +1,19 @@ +import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/error/error.dart'; + +/// A function that creates a [CorrectionProducer] for a given context. +typedef ProducerGenerator = + CorrectionProducer Function({ + required CorrectionProducerContext context, + }); + +/// A collection of diagnostic codes and their associated fix generators. +typedef FixesForCodes = Iterable>; + +/// An interface for lint rules that have associated quick fixes. +abstract interface class RuleWithFixes { + /// Returns the map entries of diagnostic code and its associated fix + /// generator. + FixesForCodes get fixesForCodes; +}