rubocop 0.75.1 → 0.80.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/config/default.yml +374 -335
- data/lib/rubocop.rb +53 -32
- data/lib/rubocop/ast/builder.rb +43 -41
- data/lib/rubocop/ast/node.rb +5 -13
- data/lib/rubocop/ast/node/block_node.rb +2 -0
- data/lib/rubocop/ast/node/def_node.rb +11 -0
- data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
- data/lib/rubocop/ast/node/regexp_node.rb +2 -4
- data/lib/rubocop/ast/node/return_node.rb +24 -0
- data/lib/rubocop/ast/traversal.rb +20 -3
- data/lib/rubocop/cli.rb +11 -227
- data/lib/rubocop/cli/command.rb +21 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
- data/lib/rubocop/cli/command/base.rb +33 -0
- data/lib/rubocop/cli/command/execute_runner.rb +76 -0
- data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
- data/lib/rubocop/cli/command/show_cops.rb +80 -0
- data/lib/rubocop/cli/command/version.rb +17 -0
- data/lib/rubocop/cli/environment.rb +21 -0
- data/lib/rubocop/comment_config.rb +8 -3
- data/lib/rubocop/config.rb +8 -1
- data/lib/rubocop/config_loader.rb +20 -20
- data/lib/rubocop/config_loader_resolver.rb +2 -1
- data/lib/rubocop/config_obsoletion.rb +73 -10
- data/lib/rubocop/config_validator.rb +77 -110
- data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
- data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
- data/lib/rubocop/cop/commissioner.rb +15 -7
- data/lib/rubocop/cop/cop.rb +31 -6
- data/lib/rubocop/cop/corrector.rb +8 -7
- data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/generator.rb +3 -4
- data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
- data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
- data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
- data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +14 -12
- data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
- data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
- data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
- data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +16 -8
- data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
- data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
- data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/{metrics → layout}/line_length.rb +68 -112
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +50 -7
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -4
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
- data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
- data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -8
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
- data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
- data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +26 -26
- data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +18 -15
- data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
- data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +6 -6
- data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
- data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
- data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
- data/lib/rubocop/cop/lint/void.rb +4 -4
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
- data/lib/rubocop/cop/migration/department_name.rb +30 -2
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
- data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +172 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
- data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -4
- data/lib/rubocop/cop/mixin/trailing_comma.rb +16 -18
- data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
- data/lib/rubocop/cop/naming/file_name.rb +12 -5
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
- data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
- data/lib/rubocop/cop/offense.rb +11 -0
- data/lib/rubocop/cop/registry.rb +8 -3
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/array_join.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +10 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/copyright.rb +11 -7
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +2 -2
- data/lib/rubocop/cop/style/empty_method.rb +5 -5
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/even_odd.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +10 -7
- data/lib/rubocop/cop/style/format_string_token.rb +2 -0
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +99 -11
- data/lib/rubocop/cop/style/guard_clause.rb +3 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +87 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_keys.rb +79 -0
- data/lib/rubocop/cop/style/hash_transform_values.rb +79 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +45 -3
- data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
- data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
- data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +6 -2
- data/lib/rubocop/cop/style/nested_modifier.rb +4 -2
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
- data/lib/rubocop/cop/style/next.rb +5 -5
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
- data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
- data/lib/rubocop/cop/style/option_hash.rb +3 -3
- data/lib/rubocop/cop/style/or_assignment.rb +3 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
- data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
- data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
- data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +27 -29
- data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -10
- data/lib/rubocop/cop/style/semicolon.rb +2 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
- data/lib/rubocop/cop/style/symbol_array.rb +2 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +0 -22
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
- data/lib/rubocop/cop/team.rb +5 -0
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +10 -18
- data/lib/rubocop/cop/variable_force.rb +11 -6
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
- data/lib/rubocop/formatter/formatter_set.rb +1 -0
- data/lib/rubocop/formatter/json_formatter.rb +6 -5
- data/lib/rubocop/formatter/junit_formatter.rb +63 -0
- data/lib/rubocop/formatter/tap_formatter.rb +1 -3
- data/lib/rubocop/node_pattern.rb +100 -12
- data/lib/rubocop/options.rb +17 -11
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -0
- data/lib/rubocop/result_cache.rb +24 -8
- data/lib/rubocop/rspec/shared_contexts.rb +5 -0
- data/lib/rubocop/runner.rb +50 -29
- data/lib/rubocop/target_finder.rb +12 -6
- data/lib/rubocop/target_ruby.rb +151 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +69 -35
- data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop checks for uses of "
|
6
|
+
# This cop checks for uses of "\*" as a substitute for *join*.
|
7
7
|
#
|
8
8
|
# Not all cases can reliably checked, due to Ruby's dynamic
|
9
9
|
# types, so we consider only cases when the first argument is an
|
@@ -21,6 +21,10 @@ module RuboCop
|
|
21
21
|
|
22
22
|
def on_send(node)
|
23
23
|
return unless node.command?(:attr) && node.arguments?
|
24
|
+
# check only for method definitions in class/module body
|
25
|
+
return if node.parent &&
|
26
|
+
!node.parent.class_type? &&
|
27
|
+
!class_eval?(node.parent)
|
24
28
|
|
25
29
|
add_offense(node, location: :selector)
|
26
30
|
end
|
@@ -31,7 +35,7 @@ module RuboCop
|
|
31
35
|
node_expr = node.source_range
|
32
36
|
attr_expr = attr_name.source_range
|
33
37
|
|
34
|
-
if setter
|
38
|
+
if setter&.boolean_type?
|
35
39
|
remove = range_between(attr_expr.end_pos, node_expr.end_pos)
|
36
40
|
end
|
37
41
|
|
@@ -50,12 +54,16 @@ module RuboCop
|
|
50
54
|
def replacement_method(node)
|
51
55
|
setter = node.last_argument
|
52
56
|
|
53
|
-
if setter
|
57
|
+
if setter&.boolean_type?
|
54
58
|
setter.true_type? ? 'attr_accessor' : 'attr_reader'
|
55
59
|
else
|
56
60
|
'attr_reader'
|
57
61
|
end
|
58
62
|
end
|
63
|
+
|
64
|
+
def_node_matcher :class_eval?, <<~PATTERN
|
65
|
+
(block (send _ {:class_eval :module_eval}) ...)
|
66
|
+
PATTERN
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
3
4
|
module RuboCop
|
4
5
|
module Cop
|
5
6
|
module Style
|
@@ -106,12 +107,41 @@ module RuboCop
|
|
106
107
|
# word.flip.flop
|
107
108
|
# }
|
108
109
|
#
|
110
|
+
# @example BracesRequiredMethods: ['sig']
|
111
|
+
#
|
112
|
+
# # Methods listed in the BracesRequiredMethods list, such as 'sig'
|
113
|
+
# # in this example, will require `{...}` braces. This option takes
|
114
|
+
# # precedence over all other configurations except IgnoredMethods.
|
115
|
+
#
|
116
|
+
# # bad
|
117
|
+
# sig do
|
118
|
+
# params(
|
119
|
+
# foo: string,
|
120
|
+
# ).void
|
121
|
+
# end
|
122
|
+
# def bar(foo)
|
123
|
+
# puts foo
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# # good
|
127
|
+
# sig {
|
128
|
+
# params(
|
129
|
+
# foo: string,
|
130
|
+
# ).void
|
131
|
+
# }
|
132
|
+
# def bar(foo)
|
133
|
+
# puts foo
|
134
|
+
# end
|
135
|
+
#
|
109
136
|
class BlockDelimiters < Cop
|
110
137
|
include ConfigurableEnforcedStyle
|
111
138
|
include IgnoredMethods
|
112
139
|
|
113
140
|
ALWAYS_BRACES_MESSAGE = 'Prefer `{...}` over `do...end` for blocks.'
|
114
141
|
|
142
|
+
BRACES_REQUIRED_MESSAGE = 'Brace delimiters `{...}` required for ' \
|
143
|
+
"'%<method_name>s' method."
|
144
|
+
|
115
145
|
def on_send(node)
|
116
146
|
return unless node.arguments?
|
117
147
|
return if node.parenthesized?
|
@@ -175,7 +205,15 @@ module RuboCop
|
|
175
205
|
end
|
176
206
|
end
|
177
207
|
|
208
|
+
def braces_required_message(node)
|
209
|
+
format(BRACES_REQUIRED_MESSAGE, method_name: node.method_name.to_s)
|
210
|
+
end
|
211
|
+
|
178
212
|
def message(node)
|
213
|
+
if braces_required_method?(node.method_name)
|
214
|
+
return braces_required_message(node)
|
215
|
+
end
|
216
|
+
|
179
217
|
case style
|
180
218
|
when :line_count_based then line_count_based_message(node)
|
181
219
|
when :semantic then semantic_message(node)
|
@@ -238,7 +276,9 @@ module RuboCop
|
|
238
276
|
# rubocop:enable Metrics/CyclomaticComplexity
|
239
277
|
|
240
278
|
def proper_block_style?(node)
|
241
|
-
|
279
|
+
if special_method?(node.method_name)
|
280
|
+
return special_method_proper_block_style?(node)
|
281
|
+
end
|
242
282
|
|
243
283
|
case style
|
244
284
|
when :line_count_based then line_count_based_block_style?(node)
|
@@ -248,6 +288,24 @@ module RuboCop
|
|
248
288
|
end
|
249
289
|
end
|
250
290
|
|
291
|
+
def special_method?(method_name)
|
292
|
+
ignored_method?(method_name) || braces_required_method?(method_name)
|
293
|
+
end
|
294
|
+
|
295
|
+
def special_method_proper_block_style?(node)
|
296
|
+
method_name = node.method_name
|
297
|
+
return true if ignored_method?(method_name)
|
298
|
+
return node.braces? if braces_required_method?(method_name)
|
299
|
+
end
|
300
|
+
|
301
|
+
def braces_required_method?(method_name)
|
302
|
+
braces_required_methods.include?(method_name.to_s)
|
303
|
+
end
|
304
|
+
|
305
|
+
def braces_required_methods
|
306
|
+
cop_config.fetch('BracesRequiredMethods', [])
|
307
|
+
end
|
308
|
+
|
251
309
|
def line_count_based_block_style?(node)
|
252
310
|
node.multiline? ^ node.braces?
|
253
311
|
end
|
@@ -329,3 +387,4 @@ module RuboCop
|
|
329
387
|
end
|
330
388
|
end
|
331
389
|
end
|
390
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -49,10 +49,10 @@ module RuboCop
|
|
49
49
|
next unless annotation?(comment) &&
|
50
50
|
!correct_annotation?(first_word, colon, space, note)
|
51
51
|
|
52
|
-
length = concat_length(first_word, colon, space)
|
53
52
|
add_offense(
|
54
53
|
comment,
|
55
|
-
location: annotation_range(comment, margin,
|
54
|
+
location: annotation_range(comment, margin,
|
55
|
+
first_word, colon, space),
|
56
56
|
message: format(note ? MSG : MISSING_NOTE, keyword: first_word)
|
57
57
|
)
|
58
58
|
end
|
@@ -62,8 +62,7 @@ module RuboCop
|
|
62
62
|
margin, first_word, colon, space, note = split_comment(comment)
|
63
63
|
return if note.nil?
|
64
64
|
|
65
|
-
|
66
|
-
range = annotation_range(comment, margin, length)
|
65
|
+
range = annotation_range(comment, margin, first_word, colon, space)
|
67
66
|
|
68
67
|
->(corrector) { corrector.replace(range, "#{first_word.upcase}: ") }
|
69
68
|
end
|
@@ -79,8 +78,9 @@ module RuboCop
|
|
79
78
|
!comment_line?(comment.loc.expression.source_line)
|
80
79
|
end
|
81
80
|
|
82
|
-
def annotation_range(comment, margin,
|
81
|
+
def annotation_range(comment, margin, first_word, colon, space)
|
83
82
|
start = comment.loc.expression.begin_pos + margin.length
|
83
|
+
length = concat_length(first_word, colon, space)
|
84
84
|
range_between(start, start + length)
|
85
85
|
end
|
86
86
|
|
@@ -212,7 +212,7 @@ module RuboCop
|
|
212
212
|
%i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
|
213
213
|
ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES +
|
214
214
|
%i[and_asgn or_asgn op_asgn masgn].freeze
|
215
|
-
LINE_LENGTH = '
|
215
|
+
LINE_LENGTH = 'Layout/LineLength'
|
216
216
|
INDENTATION_WIDTH = 'Layout/IndentationWidth'
|
217
217
|
ENABLED = 'Enabled'
|
218
218
|
MAX = 'Max'
|
@@ -376,7 +376,7 @@ module RuboCop
|
|
376
376
|
assignment_types_match?(*statements)
|
377
377
|
end
|
378
378
|
|
379
|
-
# If `
|
379
|
+
# If `Layout/LineLength` is enabled, we do not want to introduce an
|
380
380
|
# offense by auto-correcting this cop. Find the max configured line
|
381
381
|
# length. Find the longest line of condition. Remove the assignment
|
382
382
|
# from lines that contain the offending assignment because after
|
@@ -33,13 +33,7 @@ module RuboCop
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def autocorrect(token)
|
36
|
-
|
37
|
-
|
38
|
-
regex = Regexp.new(notice)
|
39
|
-
unless autocorrect_notice =~ regex
|
40
|
-
raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
|
41
|
-
"match Notice /#{notice}/"
|
42
|
-
end
|
36
|
+
verify_autocorrect_notice!
|
43
37
|
|
44
38
|
lambda do |corrector|
|
45
39
|
range = token.nil? ? range_between(0, 0) : token.pos
|
@@ -57,6 +51,16 @@ module RuboCop
|
|
57
51
|
cop_config['AutocorrectNotice']
|
58
52
|
end
|
59
53
|
|
54
|
+
def verify_autocorrect_notice!
|
55
|
+
raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
|
56
|
+
|
57
|
+
regex = Regexp.new(notice)
|
58
|
+
return if autocorrect_notice =~ regex
|
59
|
+
|
60
|
+
raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
|
61
|
+
"match Notice /#{notice}/"
|
62
|
+
end
|
63
|
+
|
60
64
|
def insert_notice_before(processed_source)
|
61
65
|
token_index = 0
|
62
66
|
token_index += 1 if shebang_token?(processed_source, token_index)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# rubocop:disable Lint/
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective
|
4
4
|
# rubocop:disable Style/DoubleCopDisableDirective
|
5
5
|
|
6
6
|
module RuboCop
|
@@ -26,7 +26,7 @@ module RuboCop
|
|
26
26
|
#
|
27
27
|
class DoubleCopDisableDirective < Cop
|
28
28
|
# rubocop:enable Style/For, Style/DoubleCopDisableDirective
|
29
|
-
# rubocop:enable Lint/
|
29
|
+
# rubocop:enable Lint/RedundantCopDisableDirective, Metrics/AbcSize
|
30
30
|
MSG = 'More than one disable comment on one line.'
|
31
31
|
|
32
32
|
def investigate(processed_source)
|
@@ -84,8 +84,8 @@ module RuboCop
|
|
84
84
|
|
85
85
|
next unless conditions.size > 1
|
86
86
|
|
87
|
-
range = range_between(conditions.first.
|
88
|
-
conditions.last.
|
87
|
+
range = range_between(conditions.first.source_range.begin_pos,
|
88
|
+
conditions.last.source_range.end_pos)
|
89
89
|
|
90
90
|
corrector.replace(range, conditions.map(&:source).join(' || '))
|
91
91
|
end
|
@@ -84,8 +84,8 @@ module RuboCop
|
|
84
84
|
# to rewrite the arguments to wrap them in parenthesis.
|
85
85
|
args = node.parent.arguments
|
86
86
|
|
87
|
-
range_between(args[0].
|
88
|
-
args[-1].
|
87
|
+
range_between(args[0].source_range.begin_pos - 1,
|
88
|
+
args[-1].source_range.end_pos)
|
89
89
|
else
|
90
90
|
node.source_range
|
91
91
|
end
|
@@ -73,11 +73,11 @@ module RuboCop
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def corrected(node)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
scope
|
76
|
+
if node.arguments?
|
77
|
+
arguments = node.arguments.source
|
78
|
+
extra_space = ' ' unless parentheses?(node.arguments)
|
79
|
+
end
|
80
|
+
scope = node.receiver ? "#{node.receiver.source}." : ''
|
81
81
|
|
82
82
|
signature = [scope, node.method_name, extra_space, arguments].join
|
83
83
|
|
@@ -85,7 +85,7 @@ module RuboCop
|
|
85
85
|
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
86
86
|
# rubocop:disable Style/ConditionalAssignment
|
87
87
|
def with_lineno?(node)
|
88
|
-
if node.
|
88
|
+
if node.method?(:eval)
|
89
89
|
node.arguments.size == 4
|
90
90
|
else
|
91
91
|
node.arguments.size == 3
|
@@ -94,10 +94,12 @@ module RuboCop
|
|
94
94
|
private
|
95
95
|
|
96
96
|
def autocorrect_from_percent(corrector, node)
|
97
|
-
|
98
|
-
|
97
|
+
percent_rhs = node.first_argument
|
98
|
+
args = case percent_rhs.type
|
99
|
+
when :array, :hash
|
100
|
+
percent_rhs.children.map(&:source).join(', ')
|
99
101
|
else
|
100
|
-
|
102
|
+
percent_rhs.source
|
101
103
|
end
|
102
104
|
|
103
105
|
corrected = "#{style}(#{node.receiver.source}, #{args})"
|
@@ -106,14 +108,15 @@ module RuboCop
|
|
106
108
|
end
|
107
109
|
|
108
110
|
def autocorrect_to_percent(corrector, node)
|
109
|
-
|
111
|
+
format_arg, *param_args = node.arguments
|
112
|
+
format = format_arg.source
|
110
113
|
|
111
|
-
args = if
|
112
|
-
arg =
|
114
|
+
args = if param_args.one?
|
115
|
+
arg = param_args.last
|
113
116
|
|
114
117
|
arg.hash_type? ? "{ #{arg.source} }" : arg.source
|
115
118
|
else
|
116
|
-
"[#{
|
119
|
+
"[#{param_args.map(&:source).join(', ')}]"
|
117
120
|
end
|
118
121
|
|
119
122
|
corrector.replace(node.loc.expression, "#{format} % #{args}")
|
@@ -104,6 +104,8 @@ module RuboCop
|
|
104
104
|
format_string = RuboCop::Cop::Utils::FormatString.new(contents.source)
|
105
105
|
|
106
106
|
format_string.format_sequences.each do |seq|
|
107
|
+
next if seq.percent?
|
108
|
+
|
107
109
|
detected_style = seq.style
|
108
110
|
token = contents.begin.adjust(
|
109
111
|
begin_pos: seq.begin_pos,
|
@@ -11,6 +11,9 @@ module RuboCop
|
|
11
11
|
# encoding comment. The frozen string literal comment is only valid in
|
12
12
|
# Ruby 2.3+.
|
13
13
|
#
|
14
|
+
# Note that the cop will ignore files where the comment exists but is set
|
15
|
+
# to `false` instead of `true`.
|
16
|
+
#
|
14
17
|
# @example EnforcedStyle: always (default)
|
15
18
|
# # The `always` style will always add the frozen string literal comment
|
16
19
|
# # to a file, regardless of the Ruby version or if `freeze` or `<<` are
|
@@ -27,6 +30,13 @@ module RuboCop
|
|
27
30
|
# # ...
|
28
31
|
# end
|
29
32
|
#
|
33
|
+
# # good
|
34
|
+
# # frozen_string_literal: false
|
35
|
+
#
|
36
|
+
# module Bar
|
37
|
+
# # ...
|
38
|
+
# end
|
39
|
+
#
|
30
40
|
# @example EnforcedStyle: never
|
31
41
|
# # The `never` will enforce that the frozen string literal comment does
|
32
42
|
# # not exist in a file.
|
@@ -41,29 +51,65 @@ module RuboCop
|
|
41
51
|
# module Baz
|
42
52
|
# # ...
|
43
53
|
# end
|
54
|
+
#
|
55
|
+
# @example EnforcedStyle: always_true
|
56
|
+
# # The `always_true` style enforces that the frozen string literal
|
57
|
+
# # comment is set to `true`. This is a stricter option than `always`
|
58
|
+
# # and forces projects to use frozen string literals.
|
59
|
+
# # bad
|
60
|
+
# # frozen_string_literal: false
|
61
|
+
#
|
62
|
+
# module Baz
|
63
|
+
# # ...
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# # bad
|
67
|
+
# module Baz
|
68
|
+
# # ...
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# # good
|
72
|
+
# # frozen_string_literal: true
|
73
|
+
#
|
74
|
+
# module Bar
|
75
|
+
# # ...
|
76
|
+
# end
|
44
77
|
class FrozenStringLiteralComment < Cop
|
45
78
|
include ConfigurableEnforcedStyle
|
46
79
|
include FrozenStringLiteral
|
47
80
|
include RangeHelp
|
48
81
|
|
49
|
-
|
82
|
+
MSG_MISSING_TRUE = 'Missing magic comment `# frozen_string_literal: '\
|
83
|
+
'true`.'
|
84
|
+
MSG_MISSING = 'Missing frozen string literal comment.'
|
50
85
|
MSG_UNNECESSARY = 'Unnecessary frozen string literal comment.'
|
86
|
+
MSG_DISABLED = 'Frozen string literal comment must be set to `true`.'
|
51
87
|
SHEBANG = '#!'
|
52
88
|
|
53
89
|
def investigate(processed_source)
|
54
90
|
return if processed_source.tokens.empty?
|
55
91
|
|
56
|
-
|
57
|
-
|
92
|
+
case style
|
93
|
+
when :never
|
94
|
+
ensure_no_comment(processed_source)
|
95
|
+
when :always_true
|
96
|
+
ensure_enabled_comment(processed_source)
|
58
97
|
else
|
59
|
-
|
98
|
+
ensure_comment(processed_source)
|
60
99
|
end
|
61
100
|
end
|
62
101
|
|
63
102
|
def autocorrect(node)
|
64
103
|
lambda do |corrector|
|
65
|
-
|
104
|
+
case style
|
105
|
+
when :never
|
66
106
|
remove_comment(corrector, node)
|
107
|
+
when :always_true
|
108
|
+
if frozen_string_literal_specified?
|
109
|
+
enable_comment(corrector)
|
110
|
+
else
|
111
|
+
insert_comment(corrector)
|
112
|
+
end
|
67
113
|
else
|
68
114
|
insert_comment(corrector)
|
69
115
|
end
|
@@ -72,12 +118,27 @@ module RuboCop
|
|
72
118
|
|
73
119
|
private
|
74
120
|
|
75
|
-
def
|
76
|
-
|
121
|
+
def ensure_no_comment(processed_source)
|
122
|
+
return unless frozen_string_literal_comment_exists?
|
123
|
+
|
124
|
+
unnecessary_comment_offense(processed_source)
|
125
|
+
end
|
126
|
+
|
127
|
+
def ensure_comment(processed_source)
|
128
|
+
return if frozen_string_literal_comment_exists?
|
129
|
+
|
130
|
+
missing_offense(processed_source)
|
77
131
|
end
|
78
132
|
|
79
|
-
def
|
80
|
-
|
133
|
+
def ensure_enabled_comment(processed_source)
|
134
|
+
if frozen_string_literal_specified?
|
135
|
+
return if frozen_string_literals_enabled?
|
136
|
+
|
137
|
+
# The comment exists, but is not enabled.
|
138
|
+
disabled_offense(processed_source)
|
139
|
+
else # The comment doesn't exist at all.
|
140
|
+
missing_true_offense(processed_source)
|
141
|
+
end
|
81
142
|
end
|
82
143
|
|
83
144
|
def last_special_comment(processed_source)
|
@@ -101,11 +162,22 @@ module RuboCop
|
|
101
162
|
end
|
102
163
|
end
|
103
164
|
|
104
|
-
def
|
165
|
+
def missing_offense(processed_source)
|
105
166
|
last_special_comment = last_special_comment(processed_source)
|
106
167
|
range = source_range(processed_source.buffer, 0, 0)
|
107
168
|
|
108
|
-
add_offense(last_special_comment,
|
169
|
+
add_offense(last_special_comment,
|
170
|
+
location: range,
|
171
|
+
message: MSG_MISSING)
|
172
|
+
end
|
173
|
+
|
174
|
+
def missing_true_offense(processed_source)
|
175
|
+
last_special_comment = last_special_comment(processed_source)
|
176
|
+
range = source_range(processed_source.buffer, 0, 0)
|
177
|
+
|
178
|
+
add_offense(last_special_comment,
|
179
|
+
location: range,
|
180
|
+
message: MSG_MISSING_TRUE)
|
109
181
|
end
|
110
182
|
|
111
183
|
def unnecessary_comment_offense(processed_source)
|
@@ -117,11 +189,27 @@ module RuboCop
|
|
117
189
|
message: MSG_UNNECESSARY)
|
118
190
|
end
|
119
191
|
|
192
|
+
def disabled_offense(processed_source)
|
193
|
+
frozen_string_literal_comment =
|
194
|
+
frozen_string_literal_comment(processed_source)
|
195
|
+
|
196
|
+
add_offense(frozen_string_literal_comment,
|
197
|
+
location: frozen_string_literal_comment.pos,
|
198
|
+
message: MSG_DISABLED)
|
199
|
+
end
|
200
|
+
|
120
201
|
def remove_comment(corrector, node)
|
121
202
|
corrector.remove(range_with_surrounding_space(range: node.pos,
|
122
203
|
side: :right))
|
123
204
|
end
|
124
205
|
|
206
|
+
def enable_comment(corrector)
|
207
|
+
comment = frozen_string_literal_comment(processed_source)
|
208
|
+
|
209
|
+
corrector.replace(line_range(comment.line),
|
210
|
+
FROZEN_STRING_LITERAL_ENABLED)
|
211
|
+
end
|
212
|
+
|
125
213
|
def insert_comment(corrector)
|
126
214
|
comment = last_special_comment(processed_source)
|
127
215
|
|