rubocop 0.40.0 → 0.41.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +7 -1014
- data/config/default.yml +61 -5
- data/config/disabled.yml +6 -0
- data/config/enabled.yml +63 -4
- data/lib/rubocop.rb +17 -1
- data/lib/rubocop/ast_node.rb +56 -42
- data/lib/rubocop/ast_node/traversal.rb +3 -3
- data/lib/rubocop/cli.rb +14 -9
- data/lib/rubocop/comment_config.rb +85 -32
- data/lib/rubocop/config.rb +29 -8
- data/lib/rubocop/config_loader.rb +1 -1
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/corrector.rb +13 -0
- data/lib/rubocop/cop/lint/block_alignment.rb +25 -11
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +5 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +69 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +60 -0
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +57 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +95 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -13
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +25 -19
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +16 -8
- data/lib/rubocop/cop/mixin/if_node.rb +1 -2
- data/lib/rubocop/cop/mixin/integer_node.rb +13 -0
- data/lib/rubocop/cop/mixin/match_range.rb +26 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +16 -7
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +18 -1
- data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -4
- data/lib/rubocop/cop/mixin/percent_literal.rb +10 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +24 -6
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +20 -7
- data/lib/rubocop/cop/mixin/string_literals_help.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +34 -20
- data/lib/rubocop/cop/performance/flat_map.rb +23 -10
- data/lib/rubocop/cop/performance/push_splat.rb +47 -0
- data/lib/rubocop/cop/performance/redundant_block_call.rb +24 -1
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -5
- data/lib/rubocop/cop/performance/sample.rb +15 -11
- data/lib/rubocop/cop/rails/exit.rb +62 -0
- data/lib/rubocop/cop/rails/output_safety.rb +45 -0
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +12 -4
- data/lib/rubocop/cop/rails/request_referer.rb +40 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +63 -28
- data/lib/rubocop/cop/rails/validation.rb +37 -23
- data/lib/rubocop/cop/style/alias.rb +10 -6
- data/lib/rubocop/cop/style/bare_percent_literals.rb +18 -7
- data/lib/rubocop/cop/style/block_delimiters.rb +15 -22
- data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +19 -8
- data/lib/rubocop/cop/style/comment_indentation.rb +13 -5
- data/lib/rubocop/cop/style/conditional_assignment.rb +111 -59
- data/lib/rubocop/cop/style/documentation.rb +7 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +43 -0
- data/lib/rubocop/cop/style/each_with_object.rb +25 -14
- data/lib/rubocop/cop/style/empty_else.rb +6 -10
- data/lib/rubocop/cop/style/extra_spacing.rb +20 -3
- data/lib/rubocop/cop/style/file_name.rb +16 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +20 -13
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +32 -0
- data/lib/rubocop/cop/style/infinite_loop.rb +42 -5
- data/lib/rubocop/cop/style/lambda.rb +22 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +12 -4
- data/lib/rubocop/cop/style/module_function.rb +28 -6
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +49 -12
- data/lib/rubocop/cop/style/mutable_constant.rb +8 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +43 -31
- data/lib/rubocop/cop/style/not.rb +33 -13
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +92 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +26 -8
- data/lib/rubocop/cop/style/{deprecated_hash_methods.rb → preferred_hash_methods.rb} +8 -8
- data/lib/rubocop/cop/style/redundant_parentheses.rb +29 -19
- data/lib/rubocop/cop/style/redundant_self.rb +13 -6
- data/lib/rubocop/cop/style/space_after_not.rb +7 -5
- data/lib/rubocop/cop/style/space_around_keyword.rb +6 -0
- data/lib/rubocop/cop/style/space_around_operators.rb +5 -1
- data/lib/rubocop/cop/style/space_before_first_arg.rb +21 -9
- data/lib/rubocop/cop/style/space_inside_array_percent_literal.rb +53 -0
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +2 -2
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +26 -6
- data/lib/rubocop/cop/style/space_inside_percent_literal_delimiters.rb +64 -0
- data/lib/rubocop/cop/style/string_literals.rb +37 -8
- data/lib/rubocop/cop/style/symbol_array.rb +21 -12
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -19
- data/lib/rubocop/cop/style/word_array.rb +1 -5
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
- data/lib/rubocop/cop/team.rb +40 -27
- data/lib/rubocop/cop/util.rb +13 -42
- data/lib/rubocop/formatter/disabled_config_formatter.rb +37 -14
- data/lib/rubocop/formatter/html_formatter.rb +3 -7
- data/lib/rubocop/result_cache.rb +18 -4
- data/{spec/support → lib/rubocop/rspec}/cop_helper.rb +3 -0
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +33 -0
- data/lib/rubocop/rspec/shared_contexts.rb +75 -0
- data/lib/rubocop/rspec/shared_examples.rb +101 -0
- data/lib/rubocop/rspec/support.rb +9 -0
- data/lib/rubocop/runner.rb +2 -2
- data/lib/rubocop/string_interpreter.rb +58 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +27 -7
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
module Lint
|
7
|
+
# This cop checks for quotes and commas in %w, e.g.
|
8
|
+
#
|
9
|
+
# `%w('foo', "bar")`
|
10
|
+
#
|
11
|
+
# it is more likely that the additional characters are unintended (for
|
12
|
+
# example, mistranslating an array of literals to percent string notation)
|
13
|
+
# rather than meant to be part of the resulting strings.
|
14
|
+
class PercentStringArray < Cop
|
15
|
+
include PercentLiteral
|
16
|
+
|
17
|
+
MSG = "Within `%w`/`%W`, quotes and ',' are unnecessary and may be " \
|
18
|
+
'unwanted in the resulting strings.'.freeze
|
19
|
+
|
20
|
+
def on_array(node)
|
21
|
+
process(node, *%w(%w %W))
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_percent_literal(node)
|
25
|
+
if contains_quotes_or_commas?(node)
|
26
|
+
add_offense(node, :expression, MSG)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def contains_quotes_or_commas?(node)
|
33
|
+
patterns = [/,$/, /^'.*'$/, /^".*"$/]
|
34
|
+
|
35
|
+
node.children.any? do |child|
|
36
|
+
literal = child.children.first
|
37
|
+
|
38
|
+
# To avoid likely false positives (e.g. a single ' or ")
|
39
|
+
next if literal.to_s.gsub(/[^\p{Alnum}]/, '').empty?
|
40
|
+
|
41
|
+
patterns.any? { |pat| literal =~ pat }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def autocorrect(node)
|
46
|
+
lambda do |corrector|
|
47
|
+
node.children.each do |child|
|
48
|
+
range = child.loc.expression
|
49
|
+
|
50
|
+
match = /['"]?,?$/.match(range.source)
|
51
|
+
corrector.remove_trailing(range, match[0].length) if match
|
52
|
+
|
53
|
+
corrector.remove_leading(range, 1) if /^['"]/ =~ range.source
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
module Lint
|
7
|
+
# This cop checks for colons and commas in %i, e.g.
|
8
|
+
#
|
9
|
+
# `%i(:foo, :bar)`
|
10
|
+
#
|
11
|
+
# it is more likely that the additional characters are unintended (for
|
12
|
+
# example, mistranslating an array of literals to percent string notation)
|
13
|
+
# rather than meant to be part of the resulting symbols.
|
14
|
+
class PercentSymbolArray < Cop
|
15
|
+
include PercentLiteral
|
16
|
+
|
17
|
+
MSG = "Within `%i`/`%I`, ':' and ',' are unnecessary and may be " \
|
18
|
+
'unwanted in the resulting symbols.'.freeze
|
19
|
+
|
20
|
+
def on_array(node)
|
21
|
+
process(node, *%w(%i %I))
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_percent_literal(node)
|
25
|
+
if contains_colons_or_commas?(node)
|
26
|
+
add_offense(node, :expression, MSG)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def contains_colons_or_commas?(node)
|
33
|
+
patterns = [/^:/, /,$/]
|
34
|
+
node.children.any? do |child|
|
35
|
+
literal = child.children.first
|
36
|
+
|
37
|
+
# To avoid likely false positives (e.g. a single ' or ")
|
38
|
+
next if literal.to_s.gsub(/[^\p{Alnum}]/, '').empty?
|
39
|
+
|
40
|
+
patterns.any? { |pat| literal =~ pat }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def autocorrect(node)
|
45
|
+
lambda do |corrector|
|
46
|
+
node.children.each do |child|
|
47
|
+
range = child.loc.expression
|
48
|
+
|
49
|
+
corrector.remove_trailing(range, 1) if /,$/ =~ range.source
|
50
|
+
corrector.remove_leading(range, 1) if /^:/ =~ range.source
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
module Lint
|
7
|
+
# This cop checks for a rescued exception that get shadowed by a
|
8
|
+
# less specific exception being rescued before a more specific
|
9
|
+
# exception is rescued.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# begin
|
14
|
+
# something
|
15
|
+
# rescue Exception
|
16
|
+
# handle_exception
|
17
|
+
# rescue StandardError
|
18
|
+
# handle_standard_error
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# #good
|
22
|
+
# begin
|
23
|
+
# something
|
24
|
+
# rescue StandardError
|
25
|
+
# handle_standard_error
|
26
|
+
# rescue Exception
|
27
|
+
# handle_exception
|
28
|
+
# end
|
29
|
+
class ShadowedException < Cop
|
30
|
+
MSG = 'Do not shadow rescued Exceptions'.freeze
|
31
|
+
|
32
|
+
def on_rescue(node)
|
33
|
+
return if rescue_modifier?(node)
|
34
|
+
_body, *rescues, _else = *node
|
35
|
+
rescued_groups = rescues.each_with_object([]) do |group, exceptions|
|
36
|
+
rescue_group, = *group
|
37
|
+
|
38
|
+
exceptions << evaluate_exceptions(rescue_group)
|
39
|
+
end
|
40
|
+
|
41
|
+
rescue_group_rescues_multiple_levels = rescued_groups.any? do |group|
|
42
|
+
!contains_multiple_levels_of_exceptions?(group)
|
43
|
+
end
|
44
|
+
|
45
|
+
return if rescue_group_rescues_multiple_levels &&
|
46
|
+
rescued_groups == sort_rescued_groups(rescued_groups)
|
47
|
+
|
48
|
+
add_offense(node, :expression)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def rescue_modifier?(node)
|
54
|
+
node && node.rescue_type? &&
|
55
|
+
(node.parent.nil? || !(node.parent.kwbegin_type? ||
|
56
|
+
node.parent.ensure_type?))
|
57
|
+
end
|
58
|
+
|
59
|
+
def contains_multiple_levels_of_exceptions?(group)
|
60
|
+
group.any? do |exception|
|
61
|
+
higher_exception = false
|
62
|
+
group.each_with_index do |_e, i|
|
63
|
+
higher_exception ||= group[i] < exception
|
64
|
+
end
|
65
|
+
|
66
|
+
higher_exception
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def evaluate_exceptions(rescue_group)
|
71
|
+
if rescue_group
|
72
|
+
rescued_exceptions = rescue_group.source.delete(' ').split(',')
|
73
|
+
|
74
|
+
rescued_exceptions.each_with_object([]) do |exception, converted|
|
75
|
+
begin
|
76
|
+
converted << instance_eval(exception, __FILE__, __LINE__)
|
77
|
+
rescue StandardError, ScriptError
|
78
|
+
next
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# treat an empty `rescue` as `rescue StandardError`
|
83
|
+
[StandardError]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def sort_rescued_groups(groups)
|
88
|
+
groups.sort do |x, y|
|
89
|
+
x <=> y || 0
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def on_block(node)
|
71
|
-
return unless
|
71
|
+
return unless instance_eval_or_new_call?(node)
|
72
72
|
|
73
73
|
check_node(node.children[2]) # block body
|
74
74
|
end
|
@@ -95,6 +95,10 @@ module RuboCop
|
|
95
95
|
(block (send _ {:class_eval :instance_eval}) ...)
|
96
96
|
PATTERN
|
97
97
|
|
98
|
+
def_node_matcher :class_or_module_or_struct_new_call?, <<-PATTERN
|
99
|
+
(block (send (const nil {:Class :Module :Struct}) :new ...) ...)
|
100
|
+
PATTERN
|
101
|
+
|
98
102
|
def check_node(node)
|
99
103
|
return if node.nil?
|
100
104
|
|
@@ -114,17 +118,8 @@ module RuboCop
|
|
114
118
|
def check_child_nodes(node, unused, cur_vis)
|
115
119
|
node.child_nodes.each do |child|
|
116
120
|
if (new_vis = access_modifier(child))
|
117
|
-
|
118
|
-
|
119
|
-
add_offense(child, :expression, format(MSG, cur_vis))
|
120
|
-
else
|
121
|
-
# was the previous modifier never applied to any defs?
|
122
|
-
add_offense(unused, :expression, format(MSG, cur_vis)) if unused
|
123
|
-
# once we have already warned about a certain modifier, don't
|
124
|
-
# warn again even if it is never applied to any method defs
|
125
|
-
unused = child
|
126
|
-
end
|
127
|
-
cur_vis = new_vis
|
121
|
+
cur_vis, unused =
|
122
|
+
check_new_visibility(child, unused, new_vis, cur_vis)
|
128
123
|
elsif method_definition?(child)
|
129
124
|
unused = nil
|
130
125
|
elsif start_of_new_scope?(child)
|
@@ -137,13 +132,33 @@ module RuboCop
|
|
137
132
|
[cur_vis, unused]
|
138
133
|
end
|
139
134
|
|
135
|
+
def check_new_visibility(node, unused, new_vis, cur_vis)
|
136
|
+
# does this modifier just repeat the existing visibility?
|
137
|
+
if new_vis == cur_vis
|
138
|
+
add_offense(node, :expression, format(MSG, cur_vis))
|
139
|
+
else
|
140
|
+
# was the previous modifier never applied to any defs?
|
141
|
+
add_offense(unused, :expression, format(MSG, cur_vis)) if unused
|
142
|
+
# once we have already warned about a certain modifier, don't
|
143
|
+
# warn again even if it is never applied to any method defs
|
144
|
+
unused = node
|
145
|
+
end
|
146
|
+
|
147
|
+
[new_vis, unused]
|
148
|
+
end
|
149
|
+
|
140
150
|
def method_definition?(child)
|
141
151
|
static_method_definition?(child) || dynamic_method_definition?(child)
|
142
152
|
end
|
143
153
|
|
144
154
|
def start_of_new_scope?(child)
|
145
155
|
child.module_type? || child.class_type? ||
|
146
|
-
child.sclass_type? ||
|
156
|
+
child.sclass_type? || instance_eval_or_new_call?(child)
|
157
|
+
end
|
158
|
+
|
159
|
+
def instance_eval_or_new_call?(child)
|
160
|
+
class_or_instance_eval?(child) ||
|
161
|
+
class_or_module_or_struct_new_call?(child)
|
147
162
|
end
|
148
163
|
end
|
149
164
|
end
|
@@ -31,26 +31,19 @@ module RuboCop
|
|
31
31
|
unless items.empty?
|
32
32
|
base_column ||= display_column(items.first.source_range)
|
33
33
|
end
|
34
|
-
|
35
|
-
items
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
# offense again and correct it.
|
47
|
-
add_offense(nil, expr)
|
48
|
-
else
|
49
|
-
add_offense(current, :expression)
|
50
|
-
end
|
51
|
-
end
|
34
|
+
|
35
|
+
each_bad_alignment(items, base_column) do |current|
|
36
|
+
expr = current.source_range
|
37
|
+
if offenses.any? { |o| within?(expr, o.location) }
|
38
|
+
# If this offense is within a line range that is already being
|
39
|
+
# realigned by autocorrect, we report the offense without
|
40
|
+
# autocorrecting it. Two rewrites in the same area by the same
|
41
|
+
# cop can not be handled. The next iteration will find the
|
42
|
+
# offense again and correct it.
|
43
|
+
add_offense(nil, expr)
|
44
|
+
else
|
45
|
+
add_offense(current, :expression)
|
52
46
|
end
|
53
|
-
prev_line = current.loc.line
|
54
47
|
end
|
55
48
|
end
|
56
49
|
|
@@ -77,6 +70,19 @@ module RuboCop
|
|
77
70
|
|
78
71
|
private
|
79
72
|
|
73
|
+
def each_bad_alignment(items, base_column)
|
74
|
+
prev_line = -1
|
75
|
+
items.each do |current|
|
76
|
+
if current.loc.line > prev_line &&
|
77
|
+
begins_its_line?(current.source_range)
|
78
|
+
@column_delta = base_column - display_column(current.source_range)
|
79
|
+
|
80
|
+
yield current if @column_delta != 0
|
81
|
+
end
|
82
|
+
prev_line = current.loc.line
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
80
86
|
def autocorrect_line(corrector, line_begin_pos, expr, column_delta,
|
81
87
|
heredoc_ranges)
|
82
88
|
range = calculate_range(expr, line_begin_pos, column_delta)
|
@@ -21,22 +21,30 @@ module RuboCop
|
|
21
21
|
end_loc = node.loc.end
|
22
22
|
return unless end_loc # Discard modifier forms of if/while/until.
|
23
23
|
|
24
|
-
matching =
|
25
|
-
range.line == end_loc.line ||
|
26
|
-
effective_column(range) == end_loc.column
|
27
|
-
end
|
24
|
+
matching = matching_ranges(end_loc, align_ranges)
|
28
25
|
|
29
26
|
if matching.key?(style)
|
30
27
|
correct_style_detected
|
31
28
|
else
|
32
|
-
|
33
|
-
msg = format(MSG, end_loc.line, end_loc.column, align_with.source,
|
34
|
-
align_with.line, align_with.column)
|
35
|
-
add_offense(node, end_loc, msg)
|
29
|
+
add_offense_for_misalignment(node, align_ranges[style])
|
36
30
|
style_detected(matching.keys)
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
34
|
+
def matching_ranges(end_loc, align_ranges)
|
35
|
+
align_ranges.select do |_, range|
|
36
|
+
range.line == end_loc.line ||
|
37
|
+
effective_column(range) == end_loc.column
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_offense_for_misalignment(node, align_with)
|
42
|
+
end_loc = node.loc.end
|
43
|
+
msg = format(MSG, end_loc.line, end_loc.column, align_with.source,
|
44
|
+
align_with.line, align_with.column)
|
45
|
+
add_offense(node, end_loc, msg)
|
46
|
+
end
|
47
|
+
|
40
48
|
def parameter_name
|
41
49
|
'AlignWith'
|
42
50
|
end
|
@@ -11,8 +11,7 @@ module RuboCop
|
|
11
11
|
|
12
12
|
def modifier_if?(node)
|
13
13
|
node.loc.respond_to?(:keyword) &&
|
14
|
-
%w(if unless).include?(node.loc.keyword.source) &&
|
15
|
-
node.loc.respond_to?(:end) && node.loc.end.nil?
|
14
|
+
%w(if unless).include?(node.loc.keyword.source) && node.modifier_form?
|
16
15
|
end
|
17
16
|
|
18
17
|
def elsif?(node)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
# Common functionality for checking integer nodes.
|
7
|
+
module IntegerNode
|
8
|
+
def integer_part(node)
|
9
|
+
node.source.sub(/^[+-]/, '').split('.').first
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
# Common functionality for obtaining source ranges from regexp matches
|
7
|
+
module MatchRange
|
8
|
+
# Return a new `Range` covering the first matching group number for each
|
9
|
+
# match of `regex` inside `range`
|
10
|
+
def each_match_range(range, regex)
|
11
|
+
range.source.scan(regex) do
|
12
|
+
yield match_range(range, Regexp.last_match)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# For a `match` inside `range`, return a new `Range` covering the match
|
17
|
+
def match_range(range, match)
|
18
|
+
Parser::Source::Range.new(
|
19
|
+
range.source_buffer,
|
20
|
+
range.begin_pos + match.begin(1),
|
21
|
+
range.begin_pos + match.end(1)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -71,7 +71,8 @@ module RuboCop
|
|
71
71
|
|
72
72
|
def incorrect_style_detected(range, node, lhs, rhs)
|
73
73
|
add_offense(range, range, message(node, lhs, rhs)) do
|
74
|
-
if
|
74
|
+
if supported_styles.size > 2 ||
|
75
|
+
offending_range(node, lhs, rhs, alternative_style)
|
75
76
|
unrecognized_style_detected
|
76
77
|
else
|
77
78
|
opposite_style_detected
|
@@ -130,17 +131,25 @@ module RuboCop
|
|
130
131
|
when :block
|
131
132
|
break if part_of_block_body?(candidate, a)
|
132
133
|
when :send
|
133
|
-
|
134
|
-
|
135
|
-
# The []= operator and setters (a.b = c) are parsed as :send nodes.
|
136
|
-
assignment_call?(method_name) &&
|
137
|
-
(!candidate || within_node?(candidate, args.last))
|
134
|
+
valid_method_rhs_candidate?(candidate, a)
|
138
135
|
when *Util::ASGN_NODES
|
139
|
-
|
136
|
+
valid_rhs_candidate?(candidate, assignment_rhs(a))
|
140
137
|
end
|
141
138
|
end
|
142
139
|
end
|
143
140
|
|
141
|
+
# The []= operator and setters (a.b = c) are parsed as :send nodes.
|
142
|
+
def valid_method_rhs_candidate?(candidate, node)
|
143
|
+
_receiver, method_name, *args = *node
|
144
|
+
|
145
|
+
assignment_call?(method_name) &&
|
146
|
+
valid_rhs_candidate?(candidate, args.last)
|
147
|
+
end
|
148
|
+
|
149
|
+
def valid_rhs_candidate?(candidate, node)
|
150
|
+
!candidate || within_node?(candidate, node)
|
151
|
+
end
|
152
|
+
|
144
153
|
def assignment_call?(method_name)
|
145
154
|
method_name == :[]= || method_name.to_s =~ /^\w.*=$/
|
146
155
|
end
|