@@ -18,129 +18,20 @@ import SwiftSyntax
18
18
///
19
19
/// Lint: If a block comment appears, a lint error is raised.
20
20
///
21
- /// Format: If a block comment appears on its own on a line, or if a block comment spans multiple
22
- /// lines without appearing on the same line as code, it will be replaced with multiple
23
- /// single-line comments.
24
- /// If a block comment appears inline with code, it will be removed and hoisted to the line
25
- /// above the code it appears on.
26
- ///
27
21
/// - SeeAlso: https://google.github.io/swift#non-documentation-comments
28
- public final class NoBlockComments : SyntaxFormatRule {
29
- public override func visit( _ token: TokenSyntax ) -> Syntax {
30
- var pieces = [ TriviaPiece] ( )
31
- var hasBlockComment = false
32
- var validToken = token
33
-
34
- // Ensures that the comments that appear inline with code have
35
- // at least 2 spaces before the `//`.
36
- if let nextToken = token. nextToken,
37
- containsBlockCommentInline ( trivia: nextToken. leadingTrivia)
38
- {
39
- hasBlockComment = true
40
- validToken = addSpacesBeforeComment ( token)
41
- }
42
-
43
- // Ensures that all block comments are replaced with line comment,
44
- // unless the comment is between tokens on the same line.
45
- for piece in token. leadingTrivia {
46
- if case . blockComment( let text) = piece,
47
- !commentIsBetweenCode( token)
48
- {
49
- diagnose ( . avoidBlockComment, on: token)
50
- hasBlockComment = true
51
- let lineCommentText = convertBlockCommentsToLineComments ( text)
52
- let lineComment = TriviaPiece . lineComment ( lineCommentText)
53
- pieces. append ( lineComment)
54
- } else {
55
- pieces. append ( piece)
22
+ public final class NoBlockComments : SyntaxLintRule {
23
+ public override func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind {
24
+ for triviaIndex in token. leadingTrivia. indices {
25
+ let piece = token. leadingTrivia [ triviaIndex]
26
+ if case . blockComment = piece {
27
+ diagnose ( . avoidBlockComment, on: token, leadingTriviaIndex: triviaIndex)
56
28
}
57
29
}
58
- validToken = validToken. withLeadingTrivia ( Trivia ( pieces: pieces) )
59
- return hasBlockComment ? validToken : token
60
- }
61
-
62
- /// Returns a Boolean value indicating if the given trivia has a piece trivia
63
- /// of block comment inline with code.
64
- private func containsBlockCommentInline( trivia: Trivia ) -> Bool {
65
- // When the comment isn't inline with code, it doesn't need to
66
- // to check that there are two spaces before the line comment.
67
- if let firstPiece = trivia. first {
68
- if case . newlines( _) = firstPiece {
69
- return false
70
- }
71
- }
72
- for piece in trivia {
73
- if case . blockComment( _) = piece {
74
- return true
75
- }
76
- }
77
- return false
78
- }
79
-
80
- /// Indicates if a block comment is between tokens on the same line.
81
- /// If it does, it should only raise a lint error.
82
- private func commentIsBetweenCode( _ token: TokenSyntax ) -> Bool {
83
- let hasCommentBetweenCode = token. leadingTrivia. isBetweenTokens
84
- if hasCommentBetweenCode {
85
- diagnose ( . avoidBlockCommentBetweenCode, on: token)
86
- }
87
- return hasCommentBetweenCode
88
- }
89
-
90
- /// Ensures there is always at least 2 spaces before the comment.
91
- private func addSpacesBeforeComment( _ token: TokenSyntax ) -> TokenSyntax {
92
- let numSpaces = token. trailingTrivia. numberOfSpaces
93
- if numSpaces < 2 {
94
- let addSpaces = 2 - numSpaces
95
- return token. withTrailingTrivia (
96
- token. trailingTrivia. appending ( . spaces( addSpaces) ) )
97
- }
98
- return token
99
- }
100
-
101
- /// Receives the text of a Block comment and converts it to a Line Comment format text.
102
- private func convertBlockCommentsToLineComments( _ text: String ) -> String {
103
- // Removes the '/*', '*/', the extra spaces and newlines from the comment.
104
- let textTrim = text. dropFirst ( 2 ) . dropLast ( 2 )
105
- . trimmingCharacters ( in: . whitespacesAndNewlines)
106
-
107
- let splitComment = textTrim. split ( separator: " \n " , omittingEmptySubsequences: false )
108
- var lineCommentText = [ String] ( )
109
-
110
- for line in splitComment {
111
- let startsComment = line. starts ( with: " " ) || line. count == 0 ? " // " : " // "
112
- lineCommentText. append ( startsComment + line)
113
- }
114
- return lineCommentText. joined ( separator: " \n " )
30
+ return . skipChildren
115
31
}
116
32
}
117
33
118
34
extension Diagnostic . Message {
119
35
static let avoidBlockComment = Diagnostic . Message (
120
36
. warning, " replace block comment with line comments " )
121
-
122
- static let avoidBlockCommentBetweenCode = Diagnostic . Message (
123
- . warning, " remove block comment inline with code " )
124
- }
125
-
126
- extension Trivia {
127
- /// Indicates if the trivia is between tokens, for example
128
- /// if a leading trivia that contains a comment, doesn't starts
129
- /// and finishes with a new line then the comment is between tokens.
130
- var isBetweenTokens : Bool {
131
- var beginsNewLine = false
132
- var endsNewLine = false
133
-
134
- if let firstPiece = self . first,
135
- let lastPiece = self . reversed ( ) . first
136
- {
137
- if case . newlines( _) = firstPiece {
138
- beginsNewLine = true
139
- }
140
- if case . newlines( _) = lastPiece {
141
- endsNewLine = true
142
- }
143
- }
144
- return !beginsNewLine && !endsNewLine
145
- }
146
37
}
0 commit comments