diff --git a/CHANGELOG.md b/CHANGELOG.md index 07be4bf7b1..6cf1949f64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +* feat: support ignoring regular comments for [`format-comment`](https://dartcodemetrics.dev/docs/rules/common/format-comment). + ## 5.2.1 * fix: avoid null check exception in the analyzer. diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/config_parser.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/config_parser.dart index 994d61c1b3..d853e7e48d 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/config_parser.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/config_parser.dart @@ -2,11 +2,15 @@ part of 'format_comment_rule.dart'; class _ConfigParser { static const _ignoredPatternsConfig = 'ignored-patterns'; + static const _onlyDocComments = 'only-doc-comments'; - static Iterable getIgnoredPatterns(Map config) => + static Iterable parseIgnoredPatterns(Map config) => config[_ignoredPatternsConfig] is Iterable ? List.from( config[_ignoredPatternsConfig] as Iterable, ).map(RegExp.new) : const []; + + static bool parseOnlyDocComments(Map config) => + config[_onlyDocComments] == true; } diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule.dart index fdd4d65a16..670b730535 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule.dart @@ -26,8 +26,11 @@ class FormatCommentRule extends CommonRule { /// match at least one of them. final Iterable _ignoredPatterns; + final bool _onlyDocComments; + FormatCommentRule([Map config = const {}]) - : _ignoredPatterns = _ConfigParser.getIgnoredPatterns(config), + : _ignoredPatterns = _ConfigParser.parseIgnoredPatterns(config), + _onlyDocComments = _ConfigParser.parseOnlyDocComments(config), super( id: ruleId, severity: readSeverity(config, Severity.style), @@ -40,13 +43,17 @@ class FormatCommentRule extends CommonRule { final json = super.toJson(); json[_ConfigParser._ignoredPatternsConfig] = _ignoredPatterns.map((exp) => exp.pattern).toList(); + json[_ConfigParser._onlyDocComments] = _onlyDocComments; return json; } @override Iterable check(InternalResolvedUnitResult source) { - final visitor = _Visitor(_ignoredPatterns)..checkComments(source.unit.root); + final visitor = _Visitor( + _ignoredPatterns, + _onlyDocComments, + )..checkComments(source.unit.root); return [ for (final comment in visitor.comments) diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/visitor.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/visitor.dart index 7f2a78e261..43a56c65a5 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/visitor.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/format_comment/visitor.dart @@ -1,6 +1,6 @@ part of 'format_comment_rule.dart'; -const commentsOperator = { +const _commentsOperator = { _CommentType.base: '//', _CommentType.documentation: '///', }; @@ -12,8 +12,10 @@ const _ignoreForFileExp = 'ignore_for_file:'; class _Visitor extends RecursiveAstVisitor { final Iterable _ignoredPatterns; + final bool _onlyDocComments; - _Visitor(this._ignoredPatterns); + // ignore: avoid_positional_boolean_parameters + _Visitor(this._ignoredPatterns, this._onlyDocComments); final _comments = <_CommentInfo>[]; @@ -41,7 +43,7 @@ class _Visitor extends RecursiveAstVisitor { final token = commentToken.toString(); if (token.startsWith('///')) { _checkCommentByType(commentToken, _CommentType.documentation); - } else if (token.startsWith('//')) { + } else if (token.startsWith('//') && !_onlyDocComments) { _checkCommentByType(commentToken, _CommentType.base); } } @@ -49,7 +51,7 @@ class _Visitor extends RecursiveAstVisitor { void _checkCommentByType(Token commentToken, _CommentType type) { final commentText = - commentToken.toString().substring(commentsOperator[type]!.length); + commentToken.toString().substring(_commentsOperator[type]!.length); var text = commentText.trim(); diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule_test.dart similarity index 82% rename from test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_test.dart rename to test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule_test.dart index d36827c396..083dde3fa0 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_test.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/format_comment/format_comment_rule_test.dart @@ -85,6 +85,34 @@ void main() { ); }); + test('reports about found issues only for doc comments', () async { + final unit = await RuleTestHelper.resolveFromFile(_multiline); + final issues = FormatCommentRule(const { + 'only-doc-comments': true, + }).check(unit); + + RuleTestHelper.verifyIssues( + issues: issues, + startLines: [2, 5, 17], + startColumns: [3, 3, 1], + locationTexts: [ + '/// The value this wraps', + '/// true if this box contains a value.', + '/// deletes the file at [path] from the file system.', + ], + messages: [ + 'Prefer formatting comments like sentences.', + 'Prefer formatting comments like sentences.', + 'Prefer formatting comments like sentences.', + ], + replacements: [ + '/// The value this wraps.', + '/// True if this box contains a value.', + '/// Deletes the file at [path] from the file system.', + ], + ); + }); + test('reports no issues', () async { final unit = await RuleTestHelper.resolveFromFile(_withoutIssuePath); RuleTestHelper.verifyNoIssues(FormatCommentRule().check(unit)); diff --git a/website/docs/rules/common/format-comment.mdx b/website/docs/rules/common/format-comment.mdx index 8211906f71..879cb4490a 100644 --- a/website/docs/rules/common/format-comment.mdx +++ b/website/docs/rules/common/format-comment.mdx @@ -6,6 +6,8 @@ Prefer format comments like sentences. Use `ignored-patterns` configuration, if you want to ignore comments that match the given regular expressions. +Use `only-doc-comments` configuration, if you want to check only documentation comments (`///`). + ### ⚙️ Config example {#config-example} ```yaml @@ -14,6 +16,7 @@ dart_code_metrics: rules: ... - format-comment: + only-doc-comments: true ignored-patterns: - ^ cSpell.* # Ignores all the comments that start with 'cSpell' (for example: '// cSpell:disable-next-line'). ```