diff --git a/CHANGELOG.md b/CHANGELOG.md index 017f9e96..2711f574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.0.0-dev.2 +- Upgraded minimum Dart SDK constraint to `>=3.12.0`. +- Upgraded `analyzer` to `^14.1.0` and `analysis_server_plugin` to `^0.3.20`. - Resolved false positives in `avoid_returning_widgets` rule. - Resolved false positives on constructors in `number_of_parameters` rule. - Improved `member_ordering` configuration. diff --git a/lib/analysis_options.yaml b/lib/analysis_options.yaml index b9203a45..a20f30f7 100644 --- a/lib/analysis_options.yaml +++ b/lib/analysis_options.yaml @@ -138,10 +138,8 @@ linter: - avoid_implementing_value_types - avoid_init_to_null - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - avoid_positional_boolean_parameters - avoid_print - - avoid_private_typedef_functions - avoid_redundant_argument_values - avoid_relative_lib_imports - avoid_renaming_method_parameters @@ -273,7 +271,6 @@ linter: - type_annotate_public_apis - type_init_formals - unawaited_futures - - unnecessary_await_in_return - unnecessary_brace_in_string_interps - unnecessary_breaks - unnecessary_const @@ -298,7 +295,6 @@ linter: - use_decorated_box - use_full_hex_values_for_flutter_colors - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - use_is_even_rather_than_modulo - use_named_constants - use_raw_strings diff --git a/lib/solid_lints.dart b/lib/solid_lints.dart index 55434eb7..d9bc949a 100644 --- a/lib/solid_lints.dart +++ b/lib/solid_lints.dart @@ -3,5 +3,3 @@ /// This package is an analyzer plugin and is intended to be used via /// `analysis_options.yaml`. library; - -export 'main.dart'; diff --git a/lib/src/common/parameter_parser/analysis_options_loader.dart b/lib/src/common/parameter_parser/analysis_options_loader.dart index 88be58d6..f190e961 100644 --- a/lib/src/common/parameter_parser/analysis_options_loader.dart +++ b/lib/src/common/parameter_parser/analysis_options_loader.dart @@ -33,10 +33,9 @@ class AnalysisOptionsLoader { } AnalysisOptionsLoader._({ - required ResourceProvider resourceProvider, - required AnalysisOptionsParser parser, - }) : _resourceProvider = resourceProvider, - _parser = parser; + required this._resourceProvider, + required this._parser, + }); /// Gets the options for a specific rule by its name. Map? getRuleOptions(RuleContext context, String ruleName) => diff --git a/lib/src/common/parameter_parser/package_config_resolver.dart b/lib/src/common/parameter_parser/package_config_resolver.dart index 1cc1207e..e4acd413 100644 --- a/lib/src/common/parameter_parser/package_config_resolver.dart +++ b/lib/src/common/parameter_parser/package_config_resolver.dart @@ -1,4 +1,5 @@ import 'dart:convert'; + import 'package:analyzer/file_system/file_system.dart'; import 'package:solid_lints/src/common/parameter_parser/cached_package_config.dart'; diff --git a/lib/src/lints/avoid_duplicate_code/visitors/ast_structural_hash_visitor.dart b/lib/src/lints/avoid_duplicate_code/visitors/ast_structural_hash_visitor.dart index 49ea8816..70a6ca04 100644 --- a/lib/src/lints/avoid_duplicate_code/visitors/ast_structural_hash_visitor.dart +++ b/lib/src/lints/avoid_duplicate_code/visitors/ast_structural_hash_visitor.dart @@ -23,10 +23,9 @@ class AstStructuralHashVisitor extends UnifyingAstVisitor { /// Creates a new [AstStructuralHashVisitor]. AstStructuralHashVisitor({ - required bool ignoreLiterals, - required bool ignoreIdentifiers, - }) : _ignoreLiterals = ignoreLiterals, - _ignoreIdentifiers = ignoreIdentifiers; + required this._ignoreLiterals, + required this._ignoreIdentifiers, + }); /// Computes the structural hash for the given [node]. /// @@ -124,9 +123,9 @@ class AstStructuralHashVisitor extends UnifyingAstVisitor { } @override - void visitNamedExpression(NamedExpression node) { - _append(node.name.label.name); - super.visitNamedExpression(node); + void visitNamedArgument(NamedArgument node) { + _append(node.name.lexeme); + super.visitNamedArgument(node); } // --- Literals --- diff --git a/lib/src/lints/avoid_duplicate_code/visitors/avoid_duplicate_code_visitor.dart b/lib/src/lints/avoid_duplicate_code/visitors/avoid_duplicate_code_visitor.dart index 3ca1ca67..233d5aa9 100644 --- a/lib/src/lints/avoid_duplicate_code/visitors/avoid_duplicate_code_visitor.dart +++ b/lib/src/lints/avoid_duplicate_code/visitors/avoid_duplicate_code_visitor.dart @@ -3,7 +3,6 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/file_system/file_system.dart'; -import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:collection/collection.dart'; import 'package:solid_lints/src/common/parameter_parser/analysis_options_loader.dart'; import 'package:solid_lints/src/lints/avoid_duplicate_code/avoid_duplicate_code_rule.dart'; @@ -40,19 +39,13 @@ class AvoidDuplicateCodeVisitor extends RecursiveAstVisitor { AvoidDuplicateCodeVisitor( this._rule, this._parameters, { - required String filePath, - required int modificationStamp, - required IgnoreMatcher ignoreMatcher, - ContextRoot? contextRoot, - ResourceProvider? resourceProvider, - AnalysisOptionsLoader? analysisOptionsLoader, - }) : _filePath = filePath, - _modificationStamp = modificationStamp, - _contextRoot = contextRoot, - _resourceProvider = - resourceProvider ?? PhysicalResourceProvider.INSTANCE, - _analysisOptionsLoader = analysisOptionsLoader, - _ignoreMatcher = ignoreMatcher; + required this._filePath, + required this._modificationStamp, + required this._ignoreMatcher, + required this._resourceProvider, + this._contextRoot, + this._analysisOptionsLoader, + }); @override void visitCompilationUnit(CompilationUnit node) { @@ -317,7 +310,7 @@ class AvoidDuplicateCodeVisitor extends RecursiveAstVisitor { return _packageRootCache.putIfAbsent(dirPath, () { var dir = _resourceProvider.getFolder(dirPath); while (true) { - final pubspec = dir.getChildAssumingFile('pubspec.yaml'); + final pubspec = dir.getFile('pubspec.yaml'); if (pubspec.exists) { return dir.path; } diff --git a/lib/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart b/lib/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart index 49d25888..b97a97a2 100644 --- a/lib/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart +++ b/lib/src/lints/avoid_final_with_getter/fixes/avoid_final_with_getter_fix.dart @@ -1,9 +1,9 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.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/visitors/getter_variable_visitor.dart'; import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/variable_references_visitor.dart'; diff --git a/lib/src/lints/avoid_returning_widgets/visitors/avoid_returning_widgets_visitor.dart b/lib/src/lints/avoid_returning_widgets/visitors/avoid_returning_widgets_visitor.dart index 7b9184a4..e8a1d97c 100644 --- a/lib/src/lints/avoid_returning_widgets/visitors/avoid_returning_widgets_visitor.dart +++ b/lib/src/lints/avoid_returning_widgets/visitors/avoid_returning_widgets_visitor.dart @@ -41,7 +41,7 @@ class AvoidReturningWidgetsVisitor extends RecursiveAstVisitor { } if (node is MethodDeclaration && - (node.isAbstract || + (!node.isComplete || node.body is EmptyFunctionBody || (node.isGetter && _isStateWidgetCastingGetter(node)))) { return; diff --git a/lib/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart b/lib/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart index 814520c1..f5b1fe3c 100644 --- a/lib/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart +++ b/lib/src/lints/avoid_unnecessary_type_assertions/fixes/avoid_unnecessary_type_assertions_fix.dart @@ -1,9 +1,9 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/source/source_range.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart'; /// A Quick fix for `avoid_unnecessary_type_assertions` rule diff --git a/lib/src/lints/avoid_unused_parameters/visitors/avoid_unused_parameters_visitor.dart b/lib/src/lints/avoid_unused_parameters/visitors/avoid_unused_parameters_visitor.dart index 31cb12ad..87c7fce3 100644 --- a/lib/src/lints/avoid_unused_parameters/visitors/avoid_unused_parameters_visitor.dart +++ b/lib/src/lints/avoid_unused_parameters/visitors/avoid_unused_parameters_visitor.dart @@ -74,7 +74,7 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor { final parameters = node.parameters; if ((parent is ClassDeclaration && parent.abstractKeyword != null) || - node.isAbstract || + !node.isComplete || node.externalKeyword != null || (parameters == null || parameters.parameters.isEmpty)) { return; @@ -150,24 +150,11 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor { parameter.declaredFragment?.element.baseElement.nonSynthetic, ); - /// Variables declared and initialized as 'Foo(this.param)' - bool isFieldFormalParameter = parameter is FieldFormalParameter; + final isInitializingFormal = + parameter is FieldFormalParameter || + parameter is SuperFormalParameter; - /// Variables declared and initialized as 'Foo(super.param)' - bool isSuperFormalParameter = parameter is SuperFormalParameter; - - if (parameter is DefaultFormalParameter) { - /// Variables as 'Foo({super.param})' or 'Foo({this.param})' - /// is being reported as [DefaultFormalParameter] instead - /// of [SuperFormalParameter] it seems to be an issue in DartSDK - isFieldFormalParameter = parameter.toSource().contains('this.'); - isSuperFormalParameter = parameter.toSource().contains('super.'); - } - - if (name != null && - !isPresentInAll && - !isFieldFormalParameter && - !isSuperFormalParameter) { + if (name != null && !isPresentInAll && !isInitializingFormal) { result.add(parameter); } } diff --git a/lib/src/lints/double_literal_format/fixes/double_literal_format_fix.dart b/lib/src/lints/double_literal_format/fixes/double_literal_format_fix.dart index 9b7e0426..5137afeb 100644 --- a/lib/src/lints/double_literal_format/fixes/double_literal_format_fix.dart +++ b/lib/src/lints/double_literal_format/fixes/double_literal_format_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/double_literal_format/double_literal_format_rule.dart'; import 'package:solid_lints/src/lints/double_literal_format/double_literal_format_utils.dart'; diff --git a/lib/src/lints/feature_envy/utils/member_access_utils.dart b/lib/src/lints/feature_envy/utils/member_access_utils.dart index 707a7153..624d9541 100644 --- a/lib/src/lints/feature_envy/utils/member_access_utils.dart +++ b/lib/src/lints/feature_envy/utils/member_access_utils.dart @@ -15,7 +15,12 @@ abstract final class MemberAccessUtils { final baseElement = switch (target.unwrapTarget) { ExtensionOverride(:final argumentList) => - argumentList.arguments.firstOrNull?.staticType?.element, + argumentList + .arguments + .firstOrNull + ?.argumentExpression + .staticType + ?.element, final expr => expr?.staticType?.element, }; @@ -37,7 +42,12 @@ abstract final class MemberAccessUtils { (target != null || !isPatternField) && switch (target?.unwrapTarget) { ExtensionOverride(:final argumentList) => - argumentList.arguments.firstOrNull?.unwrapTarget.isThisOrSuper ?? + argumentList + .arguments + .firstOrNull + ?.argumentExpression + .unwrapTarget + .isThisOrSuper ?? false, final expr => expr.isThisOrSuperOrNull, }; diff --git a/lib/src/lints/member_ordering/visitors/declaration_ordering_visitor.dart b/lib/src/lints/member_ordering/visitors/declaration_ordering_visitor.dart index 709cb2ed..2066849f 100644 --- a/lib/src/lints/member_ordering/visitors/declaration_ordering_visitor.dart +++ b/lib/src/lints/member_ordering/visitors/declaration_ordering_visitor.dart @@ -44,10 +44,9 @@ class DeclarationOrderingVisitor { /// Creates instance of [DeclarationOrderingVisitor]. DeclarationOrderingVisitor({ - required MemberOrderingParameters parameters, - required bool isFlutterWidget, - }) : _parameters = parameters, - _isFlutterWidget = isFlutterWidget; + required this._parameters, + required this._isFlutterWidget, + }); /// Visits a [ClassMember]. void visit(ClassMember member) => switch (member) { diff --git a/lib/src/lints/member_ordering/visitors/member_ordering_reporter.dart b/lib/src/lints/member_ordering/visitors/member_ordering_reporter.dart index 27be61e4..04e6237e 100644 --- a/lib/src/lints/member_ordering/visitors/member_ordering_reporter.dart +++ b/lib/src/lints/member_ordering/visitors/member_ordering_reporter.dart @@ -33,10 +33,9 @@ class MemberOrderingReporter { /// Creates instance of [MemberOrderingReporter]. const MemberOrderingReporter({ - required List membersInfo, - required MemberOrderingRule rule, - }) : _membersInfo = membersInfo, - _rule = rule; + required this._membersInfo, + required this._rule, + }); /// Generates diagnostic reports based on the configuration parameters. void report({ diff --git a/lib/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart b/lib/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart index 4349e8d0..70cb0053 100644 --- a/lib/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart +++ b/lib/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:collection/collection.dart'; import 'package:solid_lints/src/common/parameter_parser/analysis_options_loader.dart'; import 'package:solid_lints/src/lints/named_parameters_ordering/models/named_parameters_ordering_parameters.dart'; diff --git a/lib/src/lints/named_parameters_ordering/models/parameter_type.dart b/lib/src/lints/named_parameters_ordering/models/parameter_type.dart index 8f560db3..6bf77d62 100644 --- a/lib/src/lints/named_parameters_ordering/models/parameter_type.dart +++ b/lib/src/lints/named_parameters_ordering/models/parameter_type.dart @@ -35,36 +35,15 @@ enum ParameterType { } /// Classifies a [FormalParameter] into a [ParameterType]. - /// - /// Recursively unwraps [DefaultFormalParameter] wrappers to determine - /// the underlying parameter kind. - static ParameterType fromParameter( - FormalParameter parameter, { - bool hasDefaultValue = false, - }) { - if (parameter is DefaultFormalParameter && - parameter.parameter is! DefaultFormalParameter) { - return fromParameter( - parameter.parameter, - hasDefaultValue: parameter.defaultValue != null, - ); - } - - switch (parameter) { - case SuperFormalParameter(:final isRequired): - return isRequired - ? ParameterType.requiredInherited - : ParameterType.inherited; - - case DefaultFormalParameter(): - case _ when hasDefaultValue: - return ParameterType.defaultValue; - - case FieldFormalParameter(:final isRequired) || - FunctionTypedFormalParameter(:final isRequired) || - SimpleFormalParameter(:final isRequired): - return isRequired ? ParameterType.required : ParameterType.nullable; - } + static ParameterType fromParameter(FormalParameter parameter) { + return switch (parameter) { + SuperFormalParameter(:final isRequired) => + isRequired ? ParameterType.requiredInherited : ParameterType.inherited, + FormalParameter(defaultClause: _?) => ParameterType.defaultValue, + FormalParameter(:final isRequired) when isRequired => + ParameterType.required, + _ => ParameterType.nullable, + }; } /// String representation of the parameter type diff --git a/lib/src/lints/no_empty_block/visitors/no_empty_block_visitor.dart b/lib/src/lints/no_empty_block/visitors/no_empty_block_visitor.dart index f58ddd00..6100174d 100644 --- a/lib/src/lints/no_empty_block/visitors/no_empty_block_visitor.dart +++ b/lib/src/lints/no_empty_block/visitors/no_empty_block_visitor.dart @@ -38,12 +38,10 @@ class NoEmptyBlockVisitor extends RecursiveAstVisitor { /// Constructor for [NoEmptyBlockVisitor] NoEmptyBlockVisitor({ - required AnalysisRule rule, - required bool allowWithComments, - required ExcludedIdentifiersListParameter exclude, - }) : _rule = rule, - _allowWithComments = allowWithComments, - _exclude = exclude; + required this._rule, + required this._allowWithComments, + required this._exclude, + }); @override void visitBlock(Block node) { diff --git a/lib/src/lints/no_magic_number/visitors/no_magic_number_rule_visitor.dart b/lib/src/lints/no_magic_number/visitors/no_magic_number_rule_visitor.dart index 012aead9..931766c6 100644 --- a/lib/src/lints/no_magic_number/visitors/no_magic_number_rule_visitor.dart +++ b/lib/src/lints/no_magic_number/visitors/no_magic_number_rule_visitor.dart @@ -71,7 +71,7 @@ class NoMagicNumberRuleVisitor extends SimpleAstVisitor { return p is TypedLiteral || p is MapLiteralEntry || p is RecordLiteral || - (p is NamedExpression && p.parent is RecordLiteral); + p is RecordLiteralNamedField; } bool _isWidgetParameter(Literal literal) { diff --git a/lib/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart b/lib/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart index 76503be7..eec2fc69 100644 --- a/lib/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart +++ b/lib/src/lints/prefer_conditional_expressions/fixes/prefer_conditional_expressions_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/prefer_conditional_expressions/models/statement_info.dart'; import 'package:solid_lints/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart'; diff --git a/lib/src/lints/prefer_conditional_expressions/visitors/prefer_conditional_expressions_visitor.dart b/lib/src/lints/prefer_conditional_expressions/visitors/prefer_conditional_expressions_visitor.dart index d9441907..8114ea3e 100644 --- a/lib/src/lints/prefer_conditional_expressions/visitors/prefer_conditional_expressions_visitor.dart +++ b/lib/src/lints/prefer_conditional_expressions/visitors/prefer_conditional_expressions_visitor.dart @@ -35,10 +35,9 @@ class PreferConditionalExpressionsVisitor extends RecursiveAstVisitor { /// Creates instance of [PreferConditionalExpressionsVisitor] PreferConditionalExpressionsVisitor({ - required PreferConditionalExpressionsRule rule, - required bool ignoreNested, - }) : _rule = rule, - _ignoreNested = ignoreNested; + required this._rule, + required this._ignoreNested, + }); @override void visitIfStatement(IfStatement node) { diff --git a/lib/src/lints/prefer_first/fixes/prefer_first_fix.dart b/lib/src/lints/prefer_first/fixes/prefer_first_fix.dart index 0dad920b..81ba2ebd 100644 --- a/lib/src/lints/prefer_first/fixes/prefer_first_fix.dart +++ b/lib/src/lints/prefer_first/fixes/prefer_first_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/prefer_first/prefer_first_rule.dart'; /// A Quick fix for `prefer_first` rule diff --git a/lib/src/lints/prefer_last/fixes/prefer_last_fix.dart b/lib/src/lints/prefer_last/fixes/prefer_last_fix.dart index 105d6cc0..3272391c 100644 --- a/lib/src/lints/prefer_last/fixes/prefer_last_fix.dart +++ b/lib/src/lints/prefer_last/fixes/prefer_last_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/prefer_last/prefer_last_rule.dart'; /// A Quick fix for `prefer_last` rule diff --git a/lib/src/lints/prefer_match_file_name/visitors/prefer_match_file_name_visitor.dart b/lib/src/lints/prefer_match_file_name/visitors/prefer_match_file_name_visitor.dart index 8f1f7228..2fa9b428 100644 --- a/lib/src/lints/prefer_match_file_name/visitors/prefer_match_file_name_visitor.dart +++ b/lib/src/lints/prefer_match_file_name/visitors/prefer_match_file_name_visitor.dart @@ -42,7 +42,7 @@ class PreferMatchFileNameVisitor extends SimpleAstVisitor { ExtensionDeclaration() => d.name, MixinDeclaration() => d.name, EnumDeclaration() => d.namePart.typeName, - ExtensionTypeDeclaration() => d.primaryConstructor.typeName, + ExtensionTypeDeclaration() => d.namePart.typeName, _ => null, }; diff --git a/lib/src/lints/use_descriptive_names_for_type_parameters/visitors/use_descriptive_names_for_type_parameters_visitor.dart b/lib/src/lints/use_descriptive_names_for_type_parameters/visitors/use_descriptive_names_for_type_parameters_visitor.dart index 428c6f1b..36919c64 100644 --- a/lib/src/lints/use_descriptive_names_for_type_parameters/visitors/use_descriptive_names_for_type_parameters_visitor.dart +++ b/lib/src/lints/use_descriptive_names_for_type_parameters/visitors/use_descriptive_names_for_type_parameters_visitor.dart @@ -69,5 +69,5 @@ class UseDescriptiveNamesForTypeParametersVisitor @override void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) => - _visit(node.primaryConstructor.typeParameters); + _visit(node.namePart.typeParameters); } diff --git a/lib/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart b/lib/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart index 8f10e84b..d4ed9b7a 100644 --- a/lib/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart +++ b/lib/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/use_nearest_context/use_nearest_context_rule.dart'; import 'package:solid_lints/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart'; diff --git a/lib/src/lints/use_nearest_context/fixes/replace_with_nearest_context_parameter_fix.dart b/lib/src/lints/use_nearest_context/fixes/replace_with_nearest_context_parameter_fix.dart index 8baaa491..8030d5ee 100644 --- a/lib/src/lints/use_nearest_context/fixes/replace_with_nearest_context_parameter_fix.dart +++ b/lib/src/lints/use_nearest_context/fixes/replace_with_nearest_context_parameter_fix.dart @@ -1,8 +1,8 @@ +import 'package:analysis_server_plugin/edit/change_builder/change_builder.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; +import 'package:analysis_server_plugin/edit/fix/fix.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; -import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:solid_lints/src/lints/use_nearest_context/use_nearest_context_rule.dart'; import 'package:solid_lints/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart'; diff --git a/lib/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart b/lib/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart index d5b4652f..114462ec 100644 --- a/lib/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart +++ b/lib/src/lints/use_nearest_context/utils/use_nearest_context_utils.dart @@ -1,24 +1,10 @@ import 'package:analyzer/dart/ast/ast.dart'; +import 'package:collection/collection.dart'; +import 'package:solid_lints/src/utils/node_utils.dart'; import 'package:solid_lints/src/utils/types_utils.dart'; /// Finds the closest BuildContext parameter in the AST parent chain of [node]. -SimpleFormalParameter? findClosestBuildContext(AstNode node) { - AstNode? current = node.parent; - - while (current != null) { - if (current is FunctionExpression) { - final functionParams = current.parameters?.parameters ?? []; - for (final param in functionParams) { - final actualParam = param is DefaultFormalParameter - ? param.parameter - : param; - if (actualParam is SimpleFormalParameter && - isBuildContext(actualParam.declaredFragment?.element.type)) { - return actualParam; - } - } - } - current = current.parent; - } - return null; -} +FormalParameter? findClosestBuildContext(AstNode node) => node.ancestors + .whereType() + .expand((fn) => fn.parameters?.parameters ?? const []) + .firstWhereOrNull((p) => isBuildContext(p.declaredFragment?.element.type)); diff --git a/lib/src/models/solid_diagnostic_message.dart b/lib/src/models/solid_diagnostic_message.dart index 85d2ce09..72db10cb 100644 --- a/lib/src/models/solid_diagnostic_message.dart +++ b/lib/src/models/solid_diagnostic_message.dart @@ -21,9 +21,9 @@ class SolidDiagnosticMessage implements DiagnosticMessage { SolidDiagnosticMessage({ required this.filePath, required this.length, - required String message, + required this._message, required this.offset, - }) : _message = message; + }); @override String messageText({required bool includeUrl}) { diff --git a/lib/src/models/solid_lint_rule.dart b/lib/src/models/solid_lint_rule.dart index d6a5ab7b..c0145c98 100644 --- a/lib/src/models/solid_lint_rule.dart +++ b/lib/src/models/solid_lint_rule.dart @@ -23,11 +23,11 @@ abstract class SolidLintRule extends AnalysisRule { /// Constructor for [SolidLintRule] model with parameters. SolidLintRule.withParameters({ required this.analysisOptionsLoader, - required RuleParametersParser parametersParser, + required this._parametersParser, required super.name, required super.description, super.state, - }) : _parametersParser = parametersParser; + }); /// Reads the rule parameters from analysis options and parses them to [T] T? getParametersForContext(RuleContext context) { diff --git a/lib/src/models/solid_multi_lint_rule.dart b/lib/src/models/solid_multi_lint_rule.dart index 00750db1..cbb64a00 100644 --- a/lib/src/models/solid_multi_lint_rule.dart +++ b/lib/src/models/solid_multi_lint_rule.dart @@ -19,11 +19,11 @@ abstract class SolidMultiLintRule extends MultiAnalysisRule { /// Constructor for [SolidMultiLintRule] model with parameters. SolidMultiLintRule({ required this.analysisOptionsLoader, - required RuleParametersParser parametersParser, + required this._parametersParser, required super.name, required super.description, super.state, - }) : _parametersParser = parametersParser; + }); /// Reads the rule parameters from analysis options and parses them to [T]. T? getParametersForContext(RuleContext context) { diff --git a/lib/src/utils/node_utils.dart b/lib/src/utils/node_utils.dart index 880a57e3..1714b856 100644 --- a/lib/src/utils/node_utils.dart +++ b/lib/src/utils/node_utils.dart @@ -48,7 +48,7 @@ extension SimpleIdentifierExtension on SimpleIdentifier { /// Returns `true` if this identifier refers to a variable declared inside /// the body of the function that owns [as] (i.e. a local variable in the /// same scope). - bool isDeclaredInSameFunction({required SimpleFormalParameter as}) { + bool isDeclaredInSameFunction({required FormalParameter as}) { final element = this.element; if (element is! LocalVariableElement) return false; @@ -83,10 +83,21 @@ extension SimpleIdentifierExtension on SimpleIdentifier { /// Extension on [AstNode] to provide generic context/traversal checks. extension AstNodeExtension on AstNode { + /// Returns an iterable of all parent nodes of this node up to the root. + Iterable get ancestors sync* { + for (var current = parent; current != null; current = current.parent) { + yield current; + } + } + /// Returns `true` if the node is within the default value of a formal /// parameter. bool get isDefaultValue => - thisOrAncestorOfType() != null; + thisOrAncestorMatching( + (ancestor) => + ancestor is FormalParameter && ancestor.defaultClause != null, + ) != + null; /// Returns `true` if the node is within a constructor initializer. bool get isInConstructorInitializer => @@ -162,7 +173,7 @@ extension ArgumentListExtension on ArgumentList { /// Returns `true` if this argument list contains a named parameter argument /// with the given [name]. bool containsNamed(String name) => arguments.any( - (arg) => arg is NamedExpression && arg.name.label.name == name, + (arg) => arg is NamedArgument && arg.name.lexeme == name, ); } diff --git a/pubspec.yaml b/pubspec.yaml index c220efac..0f7c585d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,25 +15,21 @@ platforms: windows: environment: - sdk: ">=3.9.0 <4.0.0" + sdk: ">=3.12.0 <4.0.0" dependencies: - # Needed until required types for fixes are exported by analyzer_server_plugin - # More details: https://github.com/dart-lang/sdk/issues/61821 - analyzer_plugin: ^0.14.2 - analyzer: ^10.0.1 + analyzer: ^14.1.0 collection: ^1.19.1 - analysis_server_plugin: ^0.3.3 + analysis_server_plugin: ^0.3.20 equatable: ^2.1.0 glob: ^2.1.3 path: ^1.9.1 yaml: ^3.1.3 - # These packages are required for pana analysis to run correctly - test: ^1.25.14 dev_dependencies: args: ^2.7.0 - analyzer_testing: ^0.1.9 + analyzer_testing: ^0.3.4 + test: ^1.31.2 test_reflective_loader: ^0.4.0 plugin: diff --git a/test/src/common/parameter_parser/analysis_options_loader_test.dart b/test/src/common/parameter_parser/analysis_options_loader_test.dart index aa404ae3..0904c10c 100644 --- a/test/src/common/parameter_parser/analysis_options_loader_test.dart +++ b/test/src/common/parameter_parser/analysis_options_loader_test.dart @@ -797,9 +797,7 @@ analyzer: _TestWorkspacePackage(rootFolder), definingUnit: definingUnit ?? - _TestRuleContextUnit( - rootFolder.getChildAssumingFile('lib/dummy.dart'), - ), + _TestRuleContextUnit(rootFolder.getFile('lib/dummy.dart')), currentUnit: currentUnit, ); } diff --git a/test/src/lints/no_magic_number/no_magic_number_rule_test.dart b/test/src/lints/no_magic_number/no_magic_number_rule_test.dart index bd4ff8c7..62ff52a0 100644 --- a/test/src/lints/no_magic_number/no_magic_number_rule_test.dart +++ b/test/src/lints/no_magic_number/no_magic_number_rule_test.dart @@ -302,7 +302,17 @@ void fn() {} await assertNoDiagnostics(r''' void fn() { var point = (10, 20); + var negativePoint = (-10, -20); var named = (x: 100, y: 200); + var negativeNamed = (x: -100, y: -200); +} +'''); + } + + Future test_reports_magic_number_in_record_expressions() async { + await assertAutoDiagnostics(''' +void fn() { + var point = (${expectLint('10')} + ${expectLint('42')}, x: ${expectLint('100')} * ${expectLint('5')}); } '''); }