forked from dart-code-checker/dart-code-metrics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
visitor.dart
83 lines (66 loc) · 2.36 KB
/
visitor.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
part of 'format_comment_rule.dart';
const commentsOperator = {
_CommentType.base: '//',
_CommentType.documentation: '///',
};
final _regMacrosExp = RegExp('{@(template|macro) .+}');
const _macrosEndExp = '{@endtemplate}';
const _ignoreExp = 'ignore:';
const _ignoreForFileExp = 'ignore_for_file:';
class _Visitor extends RecursiveAstVisitor<void> {
final Iterable<RegExp> _ignoredPatterns;
_Visitor(this._ignoredPatterns);
final _comments = <_CommentInfo>[];
Iterable<_CommentInfo> get comments => _comments;
void checkComments(AstNode node) {
Token? token = node.beginToken;
while (token != null) {
Token? commentToken = token.precedingComments;
while (commentToken != null) {
_commentValidation(commentToken);
commentToken = commentToken.next;
}
if (token == token.next) {
break;
}
token = token.next;
}
}
void _commentValidation(Token commentToken) {
if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
final token = commentToken.toString();
if (token.startsWith('///')) {
_checkCommentByType(commentToken, _CommentType.documentation);
} else if (token.startsWith('//')) {
_checkCommentByType(commentToken, _CommentType.base);
}
}
}
void _checkCommentByType(Token commentToken, _CommentType type) {
final commentText =
commentToken.toString().substring(commentsOperator[type]!.length);
var text = commentText.trim();
final isIgnoreComment =
text.startsWith(_ignoreExp) || text.startsWith(_ignoreForFileExp);
final isMacros = _regMacrosExp.hasMatch(text) || text == _macrosEndExp;
final isAnIgnoredPattern = _ignoredPatterns.any(
(regExp) => regExp.hasMatch(text),
);
{
if (text.isEmpty || isIgnoreComment || isMacros || isAnIgnoredPattern) {
return;
} else {
text = text.trim();
final upperCase = text[0] == text[0].toUpperCase();
final lastSymbol = _punctuation.contains(text[text.length - 1]);
final hasEmptySpace = commentText[0] == ' ';
final incorrectFormat = !upperCase || !hasEmptySpace || !lastSymbol;
final single =
commentToken.previous == null && commentToken.next == null;
if (incorrectFormat && single) {
_comments.add(_CommentInfo(type, commentToken));
}
}
}
}
}