rubocop 1.46.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +24 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
- data/lib/rubocop/comment_config.rb +2 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +39 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +4 -4
- data/lib/rubocop/cop/layout/class_structure.rb +5 -3
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
- data/lib/rubocop/cop/lint/missing_super.rb +31 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +9 -1
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +2 -2
- data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +3 -2
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +1 -6
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/registry.rb +3 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +23 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -2
- data/lib/rubocop/cop/style/case_like_if.rb +20 -3
- data/lib/rubocop/cop/style/collection_compact.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -6
- data/lib/rubocop/cop/style/dir_empty.rb +60 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +10 -4
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_empty.rb +71 -0
- data/lib/rubocop/cop/style/file_read.rb +1 -1
- data/lib/rubocop/cop/style/file_write.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +1 -1
- data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +76 -9
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max.rb +3 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +12 -7
- data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +10 -3
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/require_order.rb +1 -3
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +3 -3
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/directive_comment.rb +3 -3
- data/lib/rubocop/ext/comment.rb +18 -0
- data/lib/rubocop/formatter/junit_formatter.rb +4 -1
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +10 -3
@@ -82,7 +82,7 @@ module RuboCop
|
|
82
82
|
|
83
83
|
def offense_range(node)
|
84
84
|
if socket_const?(node.receiver) || dir_env_file_const?(node.receiver)
|
85
|
-
node.
|
85
|
+
node.source_range.begin.join(node.loc.selector.end)
|
86
86
|
elsif node.method?(:attr)
|
87
87
|
node
|
88
88
|
else
|
@@ -187,7 +187,7 @@ module RuboCop
|
|
187
187
|
if DEF_TYPES.include?(node.type)
|
188
188
|
node.loc.keyword.join(node.loc.name)
|
189
189
|
else
|
190
|
-
node.
|
190
|
+
node.source_range
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
@@ -258,7 +258,7 @@ module RuboCop
|
|
258
258
|
end
|
259
259
|
|
260
260
|
def source_location(node)
|
261
|
-
range = node.
|
261
|
+
range = node.source_range
|
262
262
|
path = smart_path(range.source_buffer.name)
|
263
263
|
"#{path}:#{range.line}"
|
264
264
|
end
|
@@ -86,9 +86,7 @@ module RuboCop
|
|
86
86
|
# Cache by loc, not by regexp content, as content can be repeated in multiple patterns
|
87
87
|
key = node.loc
|
88
88
|
|
89
|
-
@interpolation_locs[key] ||= node.children.select(&:begin_type?).map
|
90
|
-
interpolation.loc.expression
|
91
|
-
end
|
89
|
+
@interpolation_locs[key] ||= node.children.select(&:begin_type?).map(&:source_range)
|
92
90
|
end
|
93
91
|
end
|
94
92
|
end
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
def autocorrect(corrector, node, first_else)
|
82
82
|
corrector.insert_after(node.loc.else, "\n")
|
83
83
|
|
84
|
-
blank_range = range_between(node.loc.else.end_pos, first_else.
|
84
|
+
blank_range = range_between(node.loc.else.end_pos, first_else.source_range.begin_pos)
|
85
85
|
corrector.replace(blank_range, indentation(node))
|
86
86
|
end
|
87
87
|
end
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
77
77
|
return false unless processed_source.contains_comment?(node.source_range)
|
78
78
|
|
79
79
|
line_comment = processed_source.comment_at_line(node.source_range.line)
|
80
|
-
!line_comment || !comment_disables_cop?(line_comment.
|
80
|
+
!line_comment || !comment_disables_cop?(line_comment.source)
|
81
81
|
end
|
82
82
|
|
83
83
|
def allow_empty_lambdas?
|
@@ -72,6 +72,8 @@ module RuboCop
|
|
72
72
|
return if cop_config['AllowComments'] && contains_comments?(node)
|
73
73
|
|
74
74
|
add_offense(node, message: format(MSG, keyword: node.keyword)) do |corrector|
|
75
|
+
next if node.parent&.call_type?
|
76
|
+
|
75
77
|
autocorrect(corrector, node)
|
76
78
|
end
|
77
79
|
end
|
@@ -86,7 +88,7 @@ module RuboCop
|
|
86
88
|
|
87
89
|
def remove_comments(corrector, node)
|
88
90
|
comments_in_range(node).each do |comment|
|
89
|
-
range = range_by_whole_lines(comment.
|
91
|
+
range = range_by_whole_lines(comment.source_range, include_final_newline: true)
|
90
92
|
corrector.remove(range)
|
91
93
|
end
|
92
94
|
end
|
@@ -141,7 +143,7 @@ module RuboCop
|
|
141
143
|
if empty_if_branch?(node) && else_branch?(node)
|
142
144
|
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
143
145
|
elsif node.loc.else
|
144
|
-
node.source_range.with(end_pos: node.condition.
|
146
|
+
node.source_range.with(end_pos: node.condition.source_range.end_pos)
|
145
147
|
elsif all_branches_body_missing?(node)
|
146
148
|
if_node = node.ancestors.detect(&:if?)
|
147
149
|
node.source_range.with(end_pos: if_node.loc.end.end_pos)
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
def on_interpolation(begin_node)
|
26
26
|
return unless begin_node.children.empty?
|
27
27
|
|
28
|
-
add_offense(begin_node) { |corrector| corrector.remove(begin_node.
|
28
|
+
add_offense(begin_node) { |corrector| corrector.remove(begin_node.source_range) }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -58,7 +58,7 @@ module RuboCop
|
|
58
58
|
(node.str_type? && !node.loc.respond_to?(:begin)) || node.source_range.is?('__LINE__')
|
59
59
|
end
|
60
60
|
|
61
|
-
# rubocop:disable Metrics/MethodLength
|
61
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
62
62
|
def autocorrected_value(node)
|
63
63
|
case node.type
|
64
64
|
when :int
|
@@ -71,13 +71,15 @@ module RuboCop
|
|
71
71
|
autocorrected_value_for_symbol(node)
|
72
72
|
when :array
|
73
73
|
autocorrected_value_for_array(node)
|
74
|
+
when :hash
|
75
|
+
autocorrected_value_for_hash(node)
|
74
76
|
when :nil
|
75
77
|
''
|
76
78
|
else
|
77
79
|
node.source.gsub('"', '\"')
|
78
80
|
end
|
79
81
|
end
|
80
|
-
# rubocop:enable Metrics/MethodLength
|
82
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
81
83
|
|
82
84
|
def autocorrected_value_for_string(node)
|
83
85
|
if node.source.start_with?("'", '%q')
|
@@ -89,9 +91,18 @@ module RuboCop
|
|
89
91
|
|
90
92
|
def autocorrected_value_for_symbol(node)
|
91
93
|
end_pos =
|
92
|
-
node.loc.end ? node.loc.end.begin_pos : node.
|
94
|
+
node.loc.end ? node.loc.end.begin_pos : node.source_range.end_pos
|
93
95
|
|
94
|
-
range_between(node.loc.begin.end_pos, end_pos).source
|
96
|
+
range_between(node.loc.begin.end_pos, end_pos).source.gsub('"', '\"')
|
97
|
+
end
|
98
|
+
|
99
|
+
def autocorrected_value_in_hash_for_symbol(node)
|
100
|
+
# TODO: We need to detect symbol unacceptable names more correctly
|
101
|
+
if / |"|'/.match?(node.value.to_s)
|
102
|
+
":\\\"#{node.value.to_s.gsub('"') { '\\\\\"' }}\\\""
|
103
|
+
else
|
104
|
+
":#{node.value}"
|
105
|
+
end
|
95
106
|
end
|
96
107
|
|
97
108
|
def autocorrected_value_for_array(node)
|
@@ -100,6 +111,37 @@ module RuboCop
|
|
100
111
|
contents_range(node).source.split.to_s.gsub('"', '\"')
|
101
112
|
end
|
102
113
|
|
114
|
+
def autocorrected_value_for_hash(node)
|
115
|
+
hash_string = node.children.map do |child|
|
116
|
+
key = autocorrected_value_in_hash(child.key)
|
117
|
+
value = autocorrected_value_in_hash(child.value)
|
118
|
+
"#{key}=>#{value}"
|
119
|
+
end.join(', ')
|
120
|
+
|
121
|
+
"{#{hash_string}}"
|
122
|
+
end
|
123
|
+
|
124
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
125
|
+
def autocorrected_value_in_hash(node)
|
126
|
+
case node.type
|
127
|
+
when :int
|
128
|
+
node.children.last.to_i.to_s
|
129
|
+
when :float
|
130
|
+
node.children.last.to_f.to_s
|
131
|
+
when :str
|
132
|
+
"\\\"#{node.value.to_s.gsub('"') { '\\\\\"' }}\\\""
|
133
|
+
when :sym
|
134
|
+
autocorrected_value_in_hash_for_symbol(node)
|
135
|
+
when :array
|
136
|
+
autocorrected_value_for_array(node)
|
137
|
+
when :hash
|
138
|
+
autocorrected_value_for_hash(node)
|
139
|
+
else
|
140
|
+
node.source.gsub('"', '\"')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
144
|
+
|
103
145
|
# Does node print its own source when converted to a string?
|
104
146
|
def prints_as_self?(node)
|
105
147
|
node.basic_literal? ||
|
@@ -28,6 +28,21 @@ module RuboCop
|
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
# # bad
|
31
|
+
# Employee = Class.new(Person) do
|
32
|
+
# def initialize(name, salary)
|
33
|
+
# @salary = salary
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# Employee = Class.new(Person) do
|
39
|
+
# def initialize(name, salary)
|
40
|
+
# super(name)
|
41
|
+
# @salary = salary
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # bad
|
31
46
|
# class Parent
|
32
47
|
# def self.inherited(base)
|
33
48
|
# do_something
|
@@ -55,6 +70,13 @@ module RuboCop
|
|
55
70
|
|
56
71
|
CALLBACKS = (CLASS_LIFECYCLE_CALLBACKS + METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
|
57
72
|
|
73
|
+
# @!method class_new_block(node)
|
74
|
+
def_node_matcher :class_new_block, <<~RUBY
|
75
|
+
({block numblock}
|
76
|
+
(send
|
77
|
+
(const {nil? cbase} :Class) :new $_) ...)
|
78
|
+
RUBY
|
79
|
+
|
58
80
|
def on_def(node)
|
59
81
|
return unless offender?(node)
|
60
82
|
|
@@ -88,8 +110,15 @@ module RuboCop
|
|
88
110
|
end
|
89
111
|
|
90
112
|
def inside_class_with_stateful_parent?(node)
|
91
|
-
|
92
|
-
|
113
|
+
if (block_node = node.each_ancestor(:block, :numblock).first)
|
114
|
+
return false unless (super_class = class_new_block(block_node))
|
115
|
+
|
116
|
+
!stateless_class?(super_class)
|
117
|
+
elsif (class_node = node.each_ancestor(:class).first)
|
118
|
+
class_node.parent_class && !stateless_class?(class_node.parent_class)
|
119
|
+
else
|
120
|
+
false
|
121
|
+
end
|
93
122
|
end
|
94
123
|
|
95
124
|
def stateless_class?(node)
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
|
42
42
|
def autocorrect(corrector, node)
|
43
43
|
node.children.each do |child|
|
44
|
-
range = child.
|
44
|
+
range = child.source_range
|
45
45
|
|
46
46
|
corrector.remove_trailing(range, 1) if range.source.end_with?(',')
|
47
47
|
corrector.remove_leading(range, 1) if
|
@@ -231,7 +231,7 @@ module RuboCop
|
|
231
231
|
cop_names = cops.sort.map { |c| describe(c) }.join(', ')
|
232
232
|
|
233
233
|
add_offense(location, message: message(cop_names)) do |corrector|
|
234
|
-
range = comment_range_with_surrounding_space(location, comment.
|
234
|
+
range = comment_range_with_surrounding_space(location, comment.source_range)
|
235
235
|
|
236
236
|
if leave_free_comment?(comment, range)
|
237
237
|
corrector.replace(range, ' # ')
|
@@ -263,8 +263,8 @@ module RuboCop
|
|
263
263
|
|
264
264
|
def cop_range(comment, cop)
|
265
265
|
cop = remove_department_marker(cop)
|
266
|
-
matching_range(comment.
|
267
|
-
matching_range(comment.
|
266
|
+
matching_range(comment.source_range, cop) ||
|
267
|
+
matching_range(comment.source_range, Badge.parse(cop).cop_name) ||
|
268
268
|
raise("Couldn't find #{cop} in comment: #{comment.text}")
|
269
269
|
end
|
270
270
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def comment_start(comment)
|
77
|
-
comment.
|
77
|
+
comment.source_range.begin_pos
|
78
78
|
end
|
79
79
|
|
80
80
|
def cop_name_indention(comment, name)
|
@@ -82,7 +82,7 @@ module RuboCop
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def range_with_comma(comment, name)
|
85
|
-
source = comment.
|
85
|
+
source = comment.source
|
86
86
|
|
87
87
|
begin_pos = cop_name_indention(comment, name)
|
88
88
|
end_pos = begin_pos + name.size
|
@@ -94,14 +94,14 @@ module RuboCop
|
|
94
94
|
|
95
95
|
def range_to_remove(begin_pos, end_pos, comment)
|
96
96
|
start = comment_start(comment)
|
97
|
-
source = comment.
|
97
|
+
source = comment.source
|
98
98
|
|
99
99
|
if source[begin_pos - 1] == ','
|
100
100
|
range_with_comma_before(start, begin_pos, end_pos)
|
101
101
|
elsif source[end_pos] == ','
|
102
102
|
range_with_comma_after(comment, start, begin_pos, end_pos)
|
103
103
|
else
|
104
|
-
range_between(start, comment.
|
104
|
+
range_between(start, comment.source_range.end_pos)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -112,7 +112,7 @@ module RuboCop
|
|
112
112
|
# If the list of cops is comma-separated, but without a empty space after the comma,
|
113
113
|
# we should **not** remove the prepending empty space, thus begin_pos += 1
|
114
114
|
def range_with_comma_after(comment, start, begin_pos, end_pos)
|
115
|
-
begin_pos += 1 if comment.
|
115
|
+
begin_pos += 1 if comment.source[end_pos + 1] != ' '
|
116
116
|
|
117
117
|
range_between(start + begin_pos, start + end_pos + 1)
|
118
118
|
end
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
if node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
|
57
57
|
corrector.insert_after(node.parent, "\nend")
|
58
58
|
|
59
|
-
range = range_with_surrounding_space(node.
|
59
|
+
range = range_with_surrounding_space(node.source_range, side: :right)
|
60
60
|
else
|
61
61
|
range = range_by_whole_lines(node.source_range, include_final_newline: true)
|
62
62
|
end
|
@@ -141,7 +141,7 @@ module RuboCop
|
|
141
141
|
expression = loc.expression
|
142
142
|
|
143
143
|
if array_new?(variable)
|
144
|
-
expression = node.parent.
|
144
|
+
expression = node.parent.source_range if node.parent.array_type?
|
145
145
|
[expression, variable.source]
|
146
146
|
elsif !variable.array_type?
|
147
147
|
[expression, "[#{variable.source}]"]
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
return if invalid_exceptions.empty?
|
51
51
|
|
52
52
|
add_offense(
|
53
|
-
node.loc.keyword.join(rescued.
|
53
|
+
node.loc.keyword.join(rescued.source_range),
|
54
54
|
message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
|
55
55
|
) do |corrector|
|
56
56
|
autocorrect(corrector, node)
|
@@ -59,9 +59,9 @@ module RuboCop
|
|
59
59
|
|
60
60
|
def autocorrect(corrector, node)
|
61
61
|
rescued, _, _body = *node
|
62
|
-
range = Parser::Source::Range.new(node.
|
62
|
+
range = Parser::Source::Range.new(node.source_range.source_buffer,
|
63
63
|
node.loc.keyword.end_pos,
|
64
|
-
rescued.
|
64
|
+
rescued.source_range.end_pos)
|
65
65
|
|
66
66
|
corrector.replace(range, correction(*rescued))
|
67
67
|
end
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
|
84
84
|
def offense_range(rescues)
|
85
85
|
shadowing_rescue = find_shadowing_rescue(rescues)
|
86
|
-
expression = shadowing_rescue.
|
86
|
+
expression = shadowing_rescue.source_range
|
87
87
|
range_between(expression.begin_pos, expression.end_pos)
|
88
88
|
end
|
89
89
|
|
@@ -137,7 +137,7 @@ module RuboCop
|
|
137
137
|
alias on_sclass on_class
|
138
138
|
|
139
139
|
def on_block(node)
|
140
|
-
return unless eval_call?(node)
|
140
|
+
return unless eval_call?(node) || included_block?(node)
|
141
141
|
|
142
142
|
check_node(node.body)
|
143
143
|
end
|
@@ -192,10 +192,13 @@ module RuboCop
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
195
196
|
def check_child_nodes(node, unused, cur_vis)
|
196
197
|
node.child_nodes.each do |child|
|
197
198
|
if child.send_type? && access_modifier?(child)
|
198
199
|
cur_vis, unused = check_send_node(child, cur_vis, unused)
|
200
|
+
elsif child.block_type? && included_block?(child)
|
201
|
+
next
|
199
202
|
elsif method_definition?(child)
|
200
203
|
unused = nil
|
201
204
|
elsif start_of_new_scope?(child)
|
@@ -207,6 +210,7 @@ module RuboCop
|
|
207
210
|
|
208
211
|
[cur_vis, unused]
|
209
212
|
end
|
213
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
210
214
|
|
211
215
|
def check_send_node(node, cur_vis, unused)
|
212
216
|
if node.bare_access_modifier?
|
@@ -240,6 +244,10 @@ module RuboCop
|
|
240
244
|
[new_vis, unused]
|
241
245
|
end
|
242
246
|
|
247
|
+
def included_block?(block_node)
|
248
|
+
active_support_extensions_enabled? && block_node.method?(:included)
|
249
|
+
end
|
250
|
+
|
243
251
|
def method_definition?(child)
|
244
252
|
static_method_definition?(child) ||
|
245
253
|
dynamic_method_definition?(child) ||
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def remove_node(corrector, node)
|
77
|
-
corrector.remove(range_by_whole_lines(node.
|
77
|
+
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
|
78
78
|
end
|
79
79
|
|
80
80
|
def autocorrect_block_pass(corrector, node, proc_name)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Metrics
|
6
|
+
# Checks for literals with extremely many entries. This is indicative of
|
7
|
+
# configuration or data that may be better extracted somewhere else, like
|
8
|
+
# a database, fetched from an API, or read from a non-code file (CSV,
|
9
|
+
# JSON, YAML, etc.).
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# # Huge Array literal
|
14
|
+
# [1, 2, '...', 999_999_999]
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# # Huge Hash literal
|
18
|
+
# { 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}
|
19
|
+
#
|
20
|
+
# # bad
|
21
|
+
# # Huge Set "literal"
|
22
|
+
# Set[1, 2, '...', 999_999_999]
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# # Reasonably sized Array literal
|
26
|
+
# [1, 2, '...', 10]
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# # Reading huge Array from external data source
|
30
|
+
# # File.readlines('numbers.txt', chomp: true).map!(&:to_i)
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# # Reasonably sized Hash literal
|
34
|
+
# { 1 => 1, 2 => 2, '...' => '...', 10 => 10}
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # Reading huge Hash from external data source
|
38
|
+
# CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
|
39
|
+
# hash[row["key"].to_i] = row["value"].to_i
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# # Reasonably sized Set "literal"
|
44
|
+
# Set[1, 2, '...', 10]
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# # Reading huge Set from external data source
|
48
|
+
# SomeFramework.config_for(:something)[:numbers].to_set
|
49
|
+
#
|
50
|
+
class CollectionLiteralLength < Base
|
51
|
+
MSG = 'Avoid hard coding large quantities of data in code. ' \
|
52
|
+
'Prefer reading the data from an external source.'
|
53
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
54
|
+
|
55
|
+
def on_array(node)
|
56
|
+
add_offense(node) if node.children.length >= collection_threshold
|
57
|
+
end
|
58
|
+
alias on_hash on_array
|
59
|
+
|
60
|
+
def on_index(node)
|
61
|
+
add_offense(node) if node.arguments.length >= collection_threshold
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_send(node)
|
65
|
+
on_index(node) if node.method?(:[])
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def collection_threshold
|
71
|
+
cop_config.fetch('LengthThreshold', Float::INFINITY)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -163,8 +163,8 @@ module RuboCop
|
|
163
163
|
return 0 unless parenthesized?(parent)
|
164
164
|
|
165
165
|
[
|
166
|
-
parent.loc.begin.end_pos != descendant.
|
167
|
-
parent.loc.end.begin_pos != descendant.
|
166
|
+
parent.loc.begin.end_pos != descendant.source_range.begin_pos,
|
167
|
+
parent.loc.end.begin_pos != descendant.source_range.end_pos
|
168
168
|
].count(true)
|
169
169
|
end
|
170
170
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def check_cop_name(name, comment, offset)
|
48
|
-
start = comment.
|
48
|
+
start = comment.source_range.begin_pos + offset
|
49
49
|
range = range_between(start, start + name.length)
|
50
50
|
|
51
51
|
add_offense(range) do |corrector|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
# Returns the range bounds for just the annotation
|
31
31
|
def bounds
|
32
|
-
start = comment.
|
32
|
+
start = comment.source_range.begin_pos + margin.length
|
33
33
|
length = [keyword, colon, space].reduce(0) { |len, elem| len + elem.to_s.length }
|
34
34
|
[start, start + length]
|
35
35
|
end
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
length = calculator.calculate
|
37
37
|
return if length <= max_length
|
38
38
|
|
39
|
-
location = node.casgn_type? ? node.loc.name : node.
|
39
|
+
location = node.casgn_type? ? node.loc.name : node.source_range
|
40
40
|
|
41
41
|
add_offense(location, message: message(length, max_length)) { self.max = length }
|
42
42
|
end
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def end_position_for(node)
|
40
|
-
end_line = buffer.line_for_position(node.
|
40
|
+
end_line = buffer.line_for_position(node.source_range.end_pos)
|
41
41
|
buffer.line_range(end_line).end_pos
|
42
42
|
end
|
43
43
|
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
node.loc.else.line
|
69
69
|
elsif node.if_type? && node.ternary?
|
70
70
|
node.else_branch.loc.line
|
71
|
-
elsif (next_sibling = node.right_sibling)
|
71
|
+
elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
|
72
72
|
next_sibling.loc.line
|
73
73
|
elsif (parent = node.parent)
|
74
74
|
parent.loc.end ? parent.loc.end.line : parent.loc.line
|