Skip to content

Commit 8a02e42

Browse files
marcandrebbatsov
authored andcommitted
Simplify and optimize comment lookup
Highlight for style/safe_navigation_spec isn't perfect though
1 parent a0ec799 commit 8a02e42

File tree

8 files changed

+42
-60
lines changed

8 files changed

+42
-60
lines changed

lib/rubocop/cop/layout/extra_spacing.rb

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class ExtraSpacing < Base
4040
def on_new_investigation
4141
return if processed_source.blank?
4242

43+
@aligned_comments = aligned_locations(processed_source.comments.map(&:loc))
4344
@corrected = Set.new if force_equal_sign_alignment?
4445

4546
processed_source.tokens.each_cons(2) do |token1, token2|
@@ -49,6 +50,18 @@ def on_new_investigation
4950

5051
private
5152

53+
def aligned_locations(locs)
54+
return [] if locs.empty?
55+
56+
aligned = Set[locs.first.line, locs.last.line]
57+
locs.each_cons(3) do |before, loc, after|
58+
col = loc.column
59+
aligned << loc.line if col == before.column || # rubocop:disable Style/MultipleComparison
60+
col == after.column
61+
end
62+
aligned
63+
end
64+
5265
def check_tokens(ast, token1, token2)
5366
return if token2.type == :tNL
5467

@@ -95,7 +108,7 @@ def extra_space_range(token1, token2)
95108

96109
def aligned_tok?(token)
97110
if token.comment?
98-
aligned_comments?(token)
111+
@aligned_comments.include?(token.line)
99112
else
100113
aligned_with_something?(token.pos)
101114
end
@@ -119,26 +132,6 @@ def ignored_ranges(ast)
119132
end.compact
120133
end
121134

122-
def aligned_comments?(comment_token)
123-
ix = processed_source.comments.index do |comment|
124-
comment.loc.expression.begin_pos == comment_token.begin_pos
125-
end
126-
aligned_with_previous_comment?(ix) || aligned_with_next_comment?(ix)
127-
end
128-
129-
def aligned_with_previous_comment?(index)
130-
index.positive? && comment_column(index - 1) == comment_column(index)
131-
end
132-
133-
def aligned_with_next_comment?(index)
134-
index < processed_source.comments.length - 1 &&
135-
comment_column(index + 1) == comment_column(index)
136-
end
137-
138-
def comment_column(index)
139-
processed_source.comments[index].loc.column
140-
end
141-
142135
def force_equal_sign_alignment?
143136
cop_config['ForceEqualSignAlignment']
144137
end

lib/rubocop/cop/lint/redundant_cop_disable_directive.rb

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,12 @@ def initialize(config = nil, options = nil, offenses = nil)
4141
def on_new_investigation
4242
return unless offenses_to_check
4343

44-
comments = processed_source.comments
4544
cop_disabled_line_ranges = processed_source.disabled_line_ranges
4645

4746
redundant_cops = Hash.new { |h, k| h[k] = Set.new }
4847

4948
each_redundant_disable(cop_disabled_line_ranges,
50-
offenses_to_check, comments) do |comment, redundant_cop|
49+
offenses_to_check) do |comment, redundant_cop|
5150
redundant_cops[comment].add(redundant_cop)
5251
end
5352

@@ -88,25 +87,25 @@ def directive_range_in_list(range, ranges)
8887
newlines: false)
8988
end
9089

91-
def each_redundant_disable(cop_disabled_line_ranges, offenses, comments,
90+
def each_redundant_disable(cop_disabled_line_ranges, offenses,
9291
&block)
9392
disabled_ranges = cop_disabled_line_ranges[COP_NAME] || [0..0]
9493

9594
cop_disabled_line_ranges.each do |cop, line_ranges|
9695
each_already_disabled(line_ranges,
97-
disabled_ranges, comments) do |comment|
96+
disabled_ranges) do |comment|
9897
yield comment, cop
9998
end
10099

101-
each_line_range(line_ranges, disabled_ranges, offenses, comments,
100+
each_line_range(line_ranges, disabled_ranges, offenses,
102101
cop, &block)
103102
end
104103
end
105104

106-
def each_line_range(line_ranges, disabled_ranges, offenses, comments,
105+
def each_line_range(line_ranges, disabled_ranges, offenses,
107106
cop)
108107
line_ranges.each_with_index do |line_range, ix|
109-
comment = comments.find { |c| c.loc.line == line_range.begin }
108+
comment = processed_source.comment_at_line(line_range.begin)
110109
next if ignore_offense?(disabled_ranges, line_range)
111110

112111
redundant_cop = find_redundant(comment, offenses, cop, line_range,
@@ -115,7 +114,7 @@ def each_line_range(line_ranges, disabled_ranges, offenses, comments,
115114
end
116115
end
117116

118-
def each_already_disabled(line_ranges, disabled_ranges, comments)
117+
def each_already_disabled(line_ranges, disabled_ranges)
119118
line_ranges.each_cons(2) do |previous_range, range|
120119
next if ignore_offense?(disabled_ranges, range)
121120
next if previous_range.end != range.begin
@@ -124,14 +123,12 @@ def each_already_disabled(line_ranges, disabled_ranges, comments)
124123
# the end of the previous range, it means that the cop was
125124
# already disabled by an earlier comment. So it's redundant
126125
# whether there are offenses or not.
127-
redundant_comment = comments.find do |c|
128-
c.loc.line == range.begin &&
129-
# Comments disabling all cops don't count since it's reasonable
130-
# to disable a few select cops first and then all cops further
131-
# down in the code.
132-
!all_disabled?(c)
133-
end
134-
yield redundant_comment if redundant_comment
126+
comment = processed_source.comment_at_line(range.begin)
127+
128+
# Comments disabling all cops don't count since it's reasonable
129+
# to disable a few select cops first and then all cops further
130+
# down in the code.
131+
yield comment if comment && !all_disabled?(comment)
135132
end
136133
end
137134

lib/rubocop/cop/mixin/line_length_help.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ def ignore_cop_directives?
1212

1313
def directive_on_source_line?(line_index)
1414
source_line_number = line_index + processed_source.buffer.first_line
15-
comment =
16-
processed_source.comments
17-
.detect { |e| e.location.line == source_line_number }
15+
comment = processed_source.comment_at_line(source_line_number)
1816

1917
return false unless comment
2018

lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ def new_line_needed_before_closing_brace?(node)
2727
last_element_line =
2828
last_element_range_with_trailing_comma(node).last_line
2929

30-
last_element_commented =
31-
processed_source.comments.any? { |c| c.loc.line == last_element_line }
30+
last_element_commented = processed_source.comment_at_line(last_element_line)
3231

3332
last_element_commented && (node.chained? || node.argument?)
3433
end

lib/rubocop/cop/mixin/percent_array.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,8 @@ def message(_node)
2828
end
2929

3030
def comments_in_array?(node)
31-
comments = processed_source.comments
32-
array_range = node.source_range.to_a
33-
34-
comments.any? do |comment|
35-
!(comment.loc.expression.to_a & array_range).empty?
36-
end
31+
line_span = node.source_range.first_line...node.source_range.last_line
32+
processed_source.each_comment_in_lines(line_span).any?
3733
end
3834

3935
def check_percent_array(node)

lib/rubocop/cop/mixin/trailing_comma.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,8 @@ def should_have_comma?(style, node)
7474
end
7575

7676
def inside_comment?(range, comma_offset)
77-
processed_source.comments.any? do |comment|
78-
comment_offset = comment.loc.expression.begin_pos - range.begin_pos
79-
comment_offset >= 0 && comment_offset < comma_offset
80-
end
77+
comment = processed_source.comment_at_line(range.line)
78+
comment && comment.loc.expression.begin_pos < range.begin_pos + comma_offset
8179
end
8280

8381
# Returns true if the node has round/square/curly brackets.

lib/rubocop/cop/style/safe_navigation.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ def handle_comments(corrector, node, method_call)
136136
end
137137

138138
def comments(node)
139-
processed_source.comments.select do |comment|
140-
comment.loc.first_line > node.loc.first_line &&
141-
comment.loc.last_line < node.loc.last_line
142-
end
139+
processed_source.each_comment_in_lines(
140+
node.loc.first_line...
141+
node.loc.last_line
142+
).to_a
143143
end
144144

145145
def allowed_if_condition?(node)

spec/rubocop/cop/style/safe_navigation_spec.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -674,18 +674,19 @@
674674

675675
it 'does not lose comments within if expression' do
676676
expect_offense(<<~RUBY, variable: variable)
677-
if %{variable}
678-
^^^^{variable} Use safe navigation (`&.`) instead [...]
677+
if %{variable} # hello
678+
^^^^{variable}^^^^^^^^ Use safe navigation (`&.`) instead [...]
679679
# this is a comment
680680
# another comment
681681
%{variable}.bar
682-
end
682+
end # bye!
683683
RUBY
684684

685685
expect_correction(<<~RUBY)
686+
# hello
686687
# this is a comment
687688
# another comment
688-
#{variable}&.bar
689+
#{variable}&.bar # bye!
689690
RUBY
690691
end
691692

0 commit comments

Comments
 (0)