From cd3c7b40ea0a9093e8962790a7027a01bf9bf1a0 Mon Sep 17 00:00:00 2001 From: Mudrytskyi Date: Wed, 13 Mar 2024 17:55:46 +0200 Subject: [PATCH 1/2] Excluded methods/functions named 'copyWith' from `number_of_parameters` lint --- CHANGELOG.md | 1 + .../number_of_parameters_metric.dart | 33 +++++++++++++++- lint_test/number_of_parameters_test.dart | 38 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a21c1cdc..bc1d5190 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Added `avoid_using_debug_print` rule - Fixed an issue with no_magic_number lint +- Excluded methods/functions named 'copyWith' from `number_of_parameters` lint ## 0.1.4 diff --git a/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart b/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart index cd343a56..2589e99d 100644 --- a/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart +++ b/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart @@ -7,7 +7,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// A number of parameters metric which checks whether we didn't exceed /// the maximum allowed number of parameters for a function, method or -/// constructor. +/// constructor. Methods or functions named 'copyWith' are excluded. /// /// ### Example: /// @@ -35,6 +35,27 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// void method(a, b) {} // OK /// } /// ``` +/// +/// ### Allowed +/// ```dart +/// UserDto copyWith({ +/// String? email, +/// String? firstName, +/// String? id, +/// String? imageUrl, +/// String? lastName, +/// String? phone, +/// }) { +/// return UserDto( +/// email: email ?? this.email, +/// firstName: firstName ?? this.firstName, +/// id: id ?? this.id, +/// imageUrl: imageUrl ?? this.imageUrl, +/// lastName: lastName ?? this.lastName, +/// phone: phone ?? this.phone, +/// ); +/// } +/// ``` class NumberOfParametersMetric extends SolidLintRule { /// The [LintCode] of this lint rule that represents the error if number of @@ -58,6 +79,10 @@ class NumberOfParametersMetric return NumberOfParametersMetric._(rule); } + bool _hasAllowedName(String name) { + return name == 'copyWith'; + } + @override void run( CustomLintResolver resolver, @@ -65,6 +90,9 @@ class NumberOfParametersMetric CustomLintContext context, ) { context.registry.addDeclaration((node) { + if (node is! MethodDeclaration && node is! FunctionDeclaration) { + return; + } final parameters = switch (node) { (final MethodDeclaration node) => node.parameters?.parameters.length ?? 0, @@ -73,7 +101,8 @@ class NumberOfParametersMetric _ => 0, }; - if (parameters > config.parameters.maxParameters) { + if (parameters > config.parameters.maxParameters && + !_hasAllowedName(node.declaredElement?.name ?? '')) { reporter.reportErrorForOffset( code, node.firstTokenAfterCommentAndMetadata.offset, diff --git a/lint_test/number_of_parameters_test.dart b/lint_test/number_of_parameters_test.dart index 12fa6e21..94ca928b 100644 --- a/lint_test/number_of_parameters_test.dart +++ b/lint_test/number_of_parameters_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// ignore_for_file: prefer_match_file_name /// Check number of parameters fail /// /// `number_of_parameters: max_parameters` @@ -5,3 +7,39 @@ String numberOfParameters(String a, String b, String c) { return a + b + c; } + +class UserDto { + final String email; + final String firstName; + final String id; + final String imageUrl; + final String lastName; + + final String phone; + const UserDto({ + required this.id, + required this.firstName, + required this.lastName, + required this.imageUrl, + required this.email, + required this.phone, + }); + + UserDto copyWith({ + String? email, + String? firstName, + String? id, + String? imageUrl, + String? lastName, + String? phone, + }) { + return UserDto( + email: email ?? this.email, + firstName: firstName ?? this.firstName, + id: id ?? this.id, + imageUrl: imageUrl ?? this.imageUrl, + lastName: lastName ?? this.lastName, + phone: phone ?? this.phone, + ); + } +} From f3219bf9499db507a06fc14fee47da1883ea3d7e Mon Sep 17 00:00:00 2001 From: Mudrytskyi Date: Wed, 13 Mar 2024 18:08:56 +0200 Subject: [PATCH 2/2] fix function and node selection issue --- .../number_of_parameters_metric.dart | 21 ++++++++++----- lint_test/number_of_parameters_test.dart | 27 ++++++++++++++++++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart b/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart index 2589e99d..2f1ad654 100644 --- a/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart +++ b/lib/src/lints/number_of_parameters/number_of_parameters_metric.dart @@ -7,7 +7,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart'; /// A number of parameters metric which checks whether we didn't exceed /// the maximum allowed number of parameters for a function, method or -/// constructor. Methods or functions named 'copyWith' are excluded. +/// constructor. Methods named 'copyWith' are excluded. /// /// ### Example: /// @@ -101,12 +101,21 @@ class NumberOfParametersMetric _ => 0, }; - if (parameters > config.parameters.maxParameters && - !_hasAllowedName(node.declaredElement?.name ?? '')) { - reporter.reportErrorForOffset( + final isMethod = node is MethodDeclaration; + + final declaredElement = node.declaredElement; + if (declaredElement == null) { + return; + } + final shouldInclude = switch (isMethod) { + true => !_hasAllowedName(node.declaredElement?.name ?? ''), + false => true, + }; + + if (parameters > config.parameters.maxParameters && shouldInclude) { + reporter.reportErrorForElement( code, - node.firstTokenAfterCommentAndMetadata.offset, - node.end, + declaredElement, ); } }); diff --git a/lint_test/number_of_parameters_test.dart b/lint_test/number_of_parameters_test.dart index 94ca928b..f940e492 100644 --- a/lint_test/number_of_parameters_test.dart +++ b/lint_test/number_of_parameters_test.dart @@ -3,11 +3,17 @@ /// Check number of parameters fail /// /// `number_of_parameters: max_parameters` -/// expect_lint: number_of_parameters + +// expect_lint: number_of_parameters String numberOfParameters(String a, String b, String c) { return a + b + c; } +// expect_lint: number_of_parameters +String copyWith(String a, String b, String c) { + return a + b + c; +} + class UserDto { final String email; final String firstName; @@ -42,4 +48,23 @@ class UserDto { phone: phone ?? this.phone, ); } + +// expect_lint: number_of_parameters + UserDto test({ + String? email, + String? firstName, + String? id, + String? imageUrl, + String? lastName, + String? phone, + }) { + return UserDto( + email: email ?? this.email, + firstName: firstName ?? this.firstName, + id: id ?? this.id, + imageUrl: imageUrl ?? this.imageUrl, + lastName: lastName ?? this.lastName, + phone: phone ?? this.phone, + ); + } }