forked from rubocop/rubocop
-
Notifications
You must be signed in to change notification settings - Fork 2
/
empty_comment.rb
151 lines (132 loc) · 3.68 KB
/
empty_comment.rb
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# frozen_string_literal: true
module RuboCop
module Cop
module Layout
# Checks empty comment.
#
# @example
# # bad
#
# #
# class Foo
# end
#
# # good
#
# #
# # Description of `Foo` class.
# #
# class Foo
# end
#
# @example AllowBorderComment: true (default)
# # good
#
# def foo
# end
#
# #################
#
# def bar
# end
#
# @example AllowBorderComment: false
# # bad
#
# def foo
# end
#
# #################
#
# def bar
# end
#
# @example AllowMarginComment: true (default)
# # good
#
# #
# # Description of `Foo` class.
# #
# class Foo
# end
#
# @example AllowMarginComment: false
# # bad
#
# #
# # Description of `Foo` class.
# #
# class Foo
# end
#
class EmptyComment < Base
include RangeHelp
extend AutoCorrector
MSG = 'Source code comment is empty.'
def on_new_investigation
if allow_margin_comment?
comments = concat_consecutive_comments(processed_source.comments)
investigate(comments)
else
processed_source.comments.each do |comment|
next unless empty_comment_only?(comment_text(comment))
add_offense(comment) { |corrector| autocorrect(corrector, comment) }
end
end
end
private
def investigate(comments)
comments.each do |comment|
next unless empty_comment_only?(comment[0])
comment[1].each do |offense_comment|
add_offense(offense_comment) do |corrector|
autocorrect(corrector, offense_comment)
end
end
end
end
def autocorrect(corrector, node)
previous_token = previous_token(node)
range = if previous_token && same_line?(node, previous_token)
range_with_surrounding_space(range: node.loc.expression, newlines: false)
else
range_by_whole_lines(node.loc.expression, include_final_newline: true)
end
corrector.remove(range)
end
def concat_consecutive_comments(comments)
consecutive_comments = comments.chunk_while { |i, j| i.loc.line.succ == j.loc.line }
consecutive_comments.map do |chunk|
joined_text = chunk.map { |c| comment_text(c) }.join
[joined_text, chunk]
end
end
def empty_comment_only?(comment_text)
empty_comment_pattern = if allow_border_comment?
/\A(#\n)+\z/
else
/\A(#+\n)+\z/
end
empty_comment_pattern.match?(comment_text)
end
def comment_text(comment)
"#{comment.text.strip}\n"
end
def allow_border_comment?
cop_config['AllowBorderComment']
end
def allow_margin_comment?
cop_config['AllowMarginComment']
end
def current_token(comment)
processed_source.find_token { |token| token.pos == comment.loc.expression }
end
def previous_token(node)
current_token = current_token(node)
index = processed_source.tokens.index(current_token)
index.zero? ? nil : processed_source.tokens[index - 1]
end
end
end
end
end