From 91d05ff7b28b11c08bf46e9414173b559c04e8da Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:46:47 +0200 Subject: [PATCH 1/6] feat(no_empty_block): add allow_comments allows excluding methods that contain any comments --- .../models/no_empty_block_parameters.dart | 7 +++++++ .../lints/no_empty_block/no_empty_block_rule.dart | 4 +++- .../visitors/no_empty_block_visitor.dart | 12 ++++++++++++ lint_test/analysis_options.yaml | 9 +++++---- lint_test/no_empty_block_test.dart | 12 ++++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart b/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart index 42f1eb44..898e5fad 100644 --- a/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart +++ b/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart @@ -3,18 +3,25 @@ import 'package:solid_lints/src/common/parameters/excluded_identifiers_list_para /// A data model class that represents the "no empty block" lint input /// parameters. class NoEmptyBlockParameters { + static const _allowCommentsConfig = 'allow_comments'; + /// A list of methods that should be excluded from the lint. final ExcludedIdentifiersListParameter exclude; + /// Whether to exclude empty blocks that contain any comments. + final bool allowComments; + /// Constructor for [NoEmptyBlockParameters] model NoEmptyBlockParameters({ required this.exclude, + required this.allowComments, }); /// Method for creating from json data factory NoEmptyBlockParameters.fromJson(Map json) { return NoEmptyBlockParameters( exclude: ExcludedIdentifiersListParameter.defaultFromJson(json), + allowComments: json[_allowCommentsConfig] as bool? ?? false, ); } } diff --git a/lib/src/lints/no_empty_block/no_empty_block_rule.dart b/lib/src/lints/no_empty_block/no_empty_block_rule.dart index a30576f4..335321e2 100644 --- a/lib/src/lints/no_empty_block/no_empty_block_rule.dart +++ b/lib/src/lints/no_empty_block/no_empty_block_rule.dart @@ -81,7 +81,9 @@ class NoEmptyBlockRule extends SolidLintRule { final isIgnored = config.parameters.exclude.shouldIgnore(node); if (isIgnored) return; - final visitor = NoEmptyBlockVisitor(); + final visitor = NoEmptyBlockVisitor( + allowComments: config.parameters.allowComments, + ); node.accept(visitor); for (final emptyBlock in visitor.emptyBlocks) { 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 3248f3bd..458b2e4a 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 @@ -29,8 +29,16 @@ const _todoComment = 'TODO'; /// The AST visitor that will find all empty blocks, excluding catch blocks /// and blocks containing [_todoComment] class NoEmptyBlockVisitor extends RecursiveAstVisitor { + final bool _allowComments; + final _emptyBlocks = []; + /// Constructor for [NoEmptyBlockVisitor] + /// [_allowComments] indicates whether to allow empty blocks that contain + /// any comments + NoEmptyBlockVisitor({required bool allowComments}) + : _allowComments = allowComments; + /// All empty blocks Iterable get emptyBlocks => _emptyBlocks; @@ -40,6 +48,7 @@ class NoEmptyBlockVisitor extends RecursiveAstVisitor { if (node.statements.isNotEmpty) return; if (node.parent is CatchClause) return; + if (_allowComments && _isPrecedingCommentAny(node)) return; if (_isPrecedingCommentToDo(node)) return; _emptyBlocks.add(node); @@ -47,4 +56,7 @@ class NoEmptyBlockVisitor extends RecursiveAstVisitor { static bool _isPrecedingCommentToDo(Block node) => node.endToken.precedingComments?.lexeme.contains(_todoComment) ?? false; + + static bool _isPrecedingCommentAny(Block node) => + node.endToken.precedingComments != null; } diff --git a/lint_test/analysis_options.yaml b/lint_test/analysis_options.yaml index e5a001c3..20900a29 100644 --- a/lint_test/analysis_options.yaml +++ b/lint_test/analysis_options.yaml @@ -9,7 +9,7 @@ custom_lint: exclude: - class_name: Exclude method_name: excludeMethod - - method_name: excludeMethod + - method_name: excludeMethod - number_of_parameters: max_parameters: 2 exclude: @@ -24,7 +24,7 @@ custom_lint: - avoid_global_state - avoid_returning_widgets: exclude: - - class_name: ExcludeWidget + - class_name: ExcludeWidget method_name: excludeWidgetMethod - method_name: excludeMethod - avoid_unnecessary_setstate @@ -34,7 +34,7 @@ custom_lint: - avoid_unrelated_type_assertions - avoid_unused_parameters: exclude: - - class_name: Exclude + - class_name: Exclude method_name: excludeMethod - method_name: excludeMethod - simpleMethodName @@ -42,8 +42,9 @@ custom_lint: - exclude - newline_before_return - no_empty_block: + allow_comments: true exclude: - - class_name: Exclude + - class_name: Exclude method_name: excludeMethod - method_name: excludeMethod - no_equal_then_else diff --git a/lint_test/no_empty_block_test.dart b/lint_test/no_empty_block_test.dart index 96f2ef0d..9d19653b 100644 --- a/lint_test/no_empty_block_test.dart +++ b/lint_test/no_empty_block_test.dart @@ -57,3 +57,15 @@ class Exclude { // no lint void excludeMethod() {} } + +// no lint +void emptyMethodWithComments() { + // comment explaining why this block is empty +} + +void anotherExample() { + // no lint + nestedFun(() { + // explain why this block is empty + }); +} From 10b3de02e7c456e469428ce3dc8562ba892453b1 Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Wed, 23 Apr 2025 18:09:27 +0200 Subject: [PATCH 2/6] rename(no_empty_block): allow_comments to allow_with_comments --- .../models/no_empty_block_parameters.dart | 8 ++++---- lib/src/lints/no_empty_block/no_empty_block_rule.dart | 2 +- .../visitors/no_empty_block_visitor.dart | 10 +++++----- lint_test/analysis_options.yaml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart b/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart index 898e5fad..d8e143f3 100644 --- a/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart +++ b/lib/src/lints/no_empty_block/models/no_empty_block_parameters.dart @@ -3,25 +3,25 @@ import 'package:solid_lints/src/common/parameters/excluded_identifiers_list_para /// A data model class that represents the "no empty block" lint input /// parameters. class NoEmptyBlockParameters { - static const _allowCommentsConfig = 'allow_comments'; + static const _allowWithCommentsConfig = 'allow_with_comments'; /// A list of methods that should be excluded from the lint. final ExcludedIdentifiersListParameter exclude; /// Whether to exclude empty blocks that contain any comments. - final bool allowComments; + final bool allowWithComments; /// Constructor for [NoEmptyBlockParameters] model NoEmptyBlockParameters({ required this.exclude, - required this.allowComments, + required this.allowWithComments, }); /// Method for creating from json data factory NoEmptyBlockParameters.fromJson(Map json) { return NoEmptyBlockParameters( exclude: ExcludedIdentifiersListParameter.defaultFromJson(json), - allowComments: json[_allowCommentsConfig] as bool? ?? false, + allowWithComments: json[_allowWithCommentsConfig] as bool? ?? false, ); } } diff --git a/lib/src/lints/no_empty_block/no_empty_block_rule.dart b/lib/src/lints/no_empty_block/no_empty_block_rule.dart index 335321e2..546e0eac 100644 --- a/lib/src/lints/no_empty_block/no_empty_block_rule.dart +++ b/lib/src/lints/no_empty_block/no_empty_block_rule.dart @@ -82,7 +82,7 @@ class NoEmptyBlockRule extends SolidLintRule { if (isIgnored) return; final visitor = NoEmptyBlockVisitor( - allowComments: config.parameters.allowComments, + allowWithComments: config.parameters.allowWithComments, ); node.accept(visitor); 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 458b2e4a..3f1e50d3 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 @@ -29,15 +29,15 @@ const _todoComment = 'TODO'; /// The AST visitor that will find all empty blocks, excluding catch blocks /// and blocks containing [_todoComment] class NoEmptyBlockVisitor extends RecursiveAstVisitor { - final bool _allowComments; + final bool _allowWithComments; final _emptyBlocks = []; /// Constructor for [NoEmptyBlockVisitor] - /// [_allowComments] indicates whether to allow empty blocks that contain + /// [_allowWithComments] indicates whether to allow empty blocks that contain /// any comments - NoEmptyBlockVisitor({required bool allowComments}) - : _allowComments = allowComments; + NoEmptyBlockVisitor({required bool allowWithComments}) + : _allowWithComments = allowWithComments; /// All empty blocks Iterable get emptyBlocks => _emptyBlocks; @@ -48,7 +48,7 @@ class NoEmptyBlockVisitor extends RecursiveAstVisitor { if (node.statements.isNotEmpty) return; if (node.parent is CatchClause) return; - if (_allowComments && _isPrecedingCommentAny(node)) return; + if (_allowWithComments && _isPrecedingCommentAny(node)) return; if (_isPrecedingCommentToDo(node)) return; _emptyBlocks.add(node); diff --git a/lint_test/analysis_options.yaml b/lint_test/analysis_options.yaml index 20900a29..94fdbefb 100644 --- a/lint_test/analysis_options.yaml +++ b/lint_test/analysis_options.yaml @@ -42,7 +42,7 @@ custom_lint: - exclude - newline_before_return - no_empty_block: - allow_comments: true + allow_with_comments: true exclude: - class_name: Exclude method_name: excludeMethod From 786bc9629a100bbb6e8f040e5c60fbf894b73997 Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Wed, 23 Apr 2025 18:13:01 +0200 Subject: [PATCH 3/6] test(no_empty_block): add test case for nested if else with comment --- lint_test/no_empty_block_test.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lint_test/no_empty_block_test.dart b/lint_test/no_empty_block_test.dart index 9d19653b..793dd031 100644 --- a/lint_test/no_empty_block_test.dart +++ b/lint_test/no_empty_block_test.dart @@ -69,3 +69,14 @@ void anotherExample() { // explain why this block is empty }); } + +void nestedIfElse() { + if (true) { + if (true) { + // no lint + if (true) { + // explain why this block is empty + } + } + } +} From df17f46f22ef3b66596047e02e010a1ffdf1f247 Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Thu, 24 Apr 2025 10:42:35 +0200 Subject: [PATCH 4/6] Add version 0.4.0 changelog --- CHANGELOG.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e806260..4fdab793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.0 + +- Added `allow_with_comments` parameter for `no_empty_block` lint. + ## 0.3.0 - Added `exclude` parameter for the following lints: @@ -30,11 +34,11 @@ ## 0.2.0 - Added `avoid_final_with_getter` rule -- Improve `avoid_late_keyword` - `ignored_types` to support ignoring subtype of the node type (https://github.com/solid-software/solid_lints/issues/157) -- Abstract methods should be omitted by `proper_super_calls` (https://github.com/solid-software/solid_lints/issues/159) -- Add a rule prefer_guard_clause for reversing nested if statements (https://github.com/solid-software/solid_lints/issues/91) -- add exclude params support to avoid_returning_widgets rule (https://github.com/solid-software/solid_lints/issues/131) -- add quick fix to avoid_final_with_getter (https://github.com/solid-software/solid_lints/pull/164) +- Improve `avoid_late_keyword` - `ignored_types` to support ignoring subtype of the node type () +- Abstract methods should be omitted by `proper_super_calls` () +- Add a rule prefer_guard_clause for reversing nested if statements () +- add exclude params support to avoid_returning_widgets rule () +- add quick fix to avoid_final_with_getter () - Renamed `avoid_debug_print` to `avoid_debug_print_in_release` - The `avoid_debug_print_in_release` no longer reports a warning if the `debugPrint` call is wrapped in a `!kReleaseMode` check. - Update custom_lints to work with newer Flutter @@ -50,8 +54,8 @@ - Fixed unexpected avoid_unnecessary_type_assertions - Added `excludeNames` param for `function_lines_of_code` lint - Improved `avoid_unrelated_type_assertions` to support true and false results -- Set default `cyclomatic_complexity` to 10 (https://github.com/solid-software/solid_lints/issues/146) - Credits: Arthur Miranda (https://github.com/arthurbcd) +- Set default `cyclomatic_complexity` to 10 () + Credits: Arthur Miranda () ## 0.1.4 @@ -86,7 +90,7 @@ - avoid_unrelated_type_assertions - avoid_unused_parameters - avoid_using_api - Credits: getBoolean (https://github.com/getBoolean) + Credits: getBoolean () - cyclomatic_complexity - double_literal_format - function_lines_of_code From 2c87b2f17a51f3cf20fe1c3b6def5d9468f226dc Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Thu, 24 Apr 2025 10:45:41 +0200 Subject: [PATCH 5/6] bump version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 5b44c7e7..630605c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: solid_lints description: Lints for Dart and Flutter based on software industry standards and best practices. -version: 0.3.0 +version: 0.4.0 homepage: https://github.com/solid-software/solid_lints/ documentation: https://solid-software.github.io/solid_lints/docs/intro topics: [lints, linter, lint, analysis, analyzer] From e89ac3bebe8400bc24c9727dd791543db4601c25 Mon Sep 17 00:00:00 2001 From: Andrew Bekhiet <40571928+Andrew-Bekhiet@users.noreply.github.com> Date: Thu, 24 Apr 2025 11:07:10 +0200 Subject: [PATCH 6/6] Revert "bump version" This reverts commit 2c87b2f17a51f3cf20fe1c3b6def5d9468f226dc. --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 630605c7..5b44c7e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: solid_lints description: Lints for Dart and Flutter based on software industry standards and best practices. -version: 0.4.0 +version: 0.3.0 homepage: https://github.com/solid-software/solid_lints/ documentation: https://solid-software.github.io/solid_lints/docs/intro topics: [lints, linter, lint, analysis, analyzer]