rubocop 0.46.0 → 0.47.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/LICENSE.txt +1 -1
- data/README.md +77 -2
- data/config/default.yml +151 -74
- data/config/disabled.yml +9 -0
- data/config/enabled.yml +49 -9
- data/lib/rubocop.rb +36 -8
- data/lib/rubocop/ast/builder.rb +59 -0
- data/lib/rubocop/ast/node.rb +607 -0
- data/lib/rubocop/ast/node/array_node.rb +45 -0
- data/lib/rubocop/ast/node/case_node.rb +63 -0
- data/lib/rubocop/ast/node/for_node.rb +53 -0
- data/lib/rubocop/ast/node/hash_node.rb +102 -0
- data/lib/rubocop/ast/node/if_node.rb +136 -0
- data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
- data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
- data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
- data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
- data/lib/rubocop/ast/node/pair_node.rb +64 -0
- data/lib/rubocop/ast/node/until_node.rb +43 -0
- data/lib/rubocop/ast/node/when_node.rb +61 -0
- data/lib/rubocop/ast/node/while_node.rb +43 -0
- data/lib/rubocop/ast/sexp.rb +16 -0
- data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
- data/lib/rubocop/cli.rb +18 -14
- data/lib/rubocop/comment_config.rb +1 -3
- data/lib/rubocop/config.rb +93 -35
- data/lib/rubocop/config_loader.rb +1 -1
- data/lib/rubocop/cop/badge.rb +73 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
- data/lib/rubocop/cop/commissioner.rb +17 -6
- data/lib/rubocop/cop/cop.rb +25 -112
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
- data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
- data/lib/rubocop/cop/lint/condition_position.rb +14 -16
- data/lib/rubocop/cop/lint/debugger.rb +28 -0
- data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
- data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
- data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
- data/lib/rubocop/cop/lint/else_layout.rb +26 -29
- data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
- data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/empty_when.rb +14 -16
- data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
- data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
- data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
- data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
- data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
- data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
- data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/loop.rb +36 -0
- data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
- data/lib/rubocop/cop/lint/rand_one.rb +7 -3
- data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
- data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
- data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
- data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
- data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
- data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
- data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
- data/lib/rubocop/cop/lint/void.rb +52 -0
- data/lib/rubocop/cop/message_annotator.rb +102 -0
- data/lib/rubocop/cop/metrics/block_length.rb +6 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
- data/lib/rubocop/cop/metrics/line_length.rb +11 -4
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
- data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
- data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
- data/lib/rubocop/cop/mixin/duplication.rb +46 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
- data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
- data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
- data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
- data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
- data/lib/rubocop/cop/offense.rb +1 -1
- data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
- data/lib/rubocop/cop/performance/detect.rb +2 -2
- data/lib/rubocop/cop/performance/flat_map.rb +3 -3
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
- data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
- data/lib/rubocop/cop/rails/file_path.rb +80 -0
- data/lib/rubocop/cop/rails/find_each.rb +5 -14
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
- data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
- data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
- data/lib/rubocop/cop/rails/time_zone.rb +1 -1
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
- data/lib/rubocop/cop/registry.rb +170 -0
- data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
- data/lib/rubocop/cop/security/marshal_load.rb +33 -0
- data/lib/rubocop/cop/security/yaml_load.rb +37 -0
- data/lib/rubocop/cop/style/align_hash.rb +138 -169
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
- data/lib/rubocop/cop/style/case_indentation.rb +36 -27
- data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
- data/lib/rubocop/cop/style/each_with_object.rb +4 -1
- data/lib/rubocop/cop/style/else_alignment.rb +14 -20
- data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
- data/lib/rubocop/cop/style/empty_else.rb +20 -22
- data/lib/rubocop/cop/style/empty_literal.rb +4 -4
- data/lib/rubocop/cop/style/empty_method.rb +12 -6
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/file_name.rb +24 -4
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +17 -48
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
- data/lib/rubocop/cop/style/guard_clause.rb +11 -17
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
- data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
- data/lib/rubocop/cop/style/indent_array.rb +1 -1
- data/lib/rubocop/cop/style/indentation_width.rb +29 -60
- data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
- data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
- data/lib/rubocop/cop/style/missing_else.rb +40 -14
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
- data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
- data/lib/rubocop/cop/style/negated_if.rb +3 -19
- data/lib/rubocop/cop/style/negated_while.rb +2 -17
- data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
- data/lib/rubocop/cop/style/next.rb +23 -21
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
- data/lib/rubocop/cop/style/not.rb +1 -3
- data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
- data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
- data/lib/rubocop/cop/style/option_hash.rb +4 -15
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
- data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
- data/lib/rubocop/cop/style/redundant_return.rb +4 -8
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
- data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
- data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
- data/lib/rubocop/cop/style/string_methods.rb +1 -3
- data/lib/rubocop/cop/style/symbol_array.rb +1 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
- data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +1 -5
- data/lib/rubocop/cop/style/when_then.rb +4 -2
- data/lib/rubocop/cop/style/while_until_do.rb +9 -13
- data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
- data/lib/rubocop/cop/style/word_array.rb +5 -9
- data/lib/rubocop/cop/team.rb +16 -15
- data/lib/rubocop/cop/util.rb +13 -3
- data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/magic_comment.rb +196 -0
- data/lib/rubocop/options.rb +5 -4
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/shared_examples.rb +1 -1
- data/lib/rubocop/runner.rb +7 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +41 -14
- data/lib/rubocop/ast_node.rb +0 -624
- data/lib/rubocop/ast_node/builder.rb +0 -30
- data/lib/rubocop/ast_node/sexp.rb +0 -13
- data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
- data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -40,51 +40,42 @@ module RuboCop
|
|
40
40
|
'expression.'.freeze
|
41
41
|
|
42
42
|
def on_case(case_node)
|
43
|
-
|
43
|
+
return if case_node.condition
|
44
44
|
|
45
|
-
add_offense(case_node, :keyword, MSG)
|
45
|
+
add_offense(case_node, :keyword, MSG)
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
49
49
|
|
50
50
|
def autocorrect(case_node)
|
51
|
-
|
52
|
-
_cond_node, *when_nodes, _else_node = *case_node
|
53
|
-
|
54
|
-
correct_case_whens(corrector, case_node, when_nodes)
|
51
|
+
when_branches = case_node.when_branches
|
55
52
|
|
56
|
-
|
53
|
+
lambda do |corrector|
|
54
|
+
correct_case_when(corrector, case_node, when_branches)
|
55
|
+
correct_when_conditions(corrector, when_branches)
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
def
|
61
|
-
|
62
|
-
case_node.loc.keyword.join(when_nodes.first.loc.keyword)
|
59
|
+
def correct_case_when(corrector, case_node, when_nodes)
|
60
|
+
case_range = case_node.loc.keyword.join(when_nodes.shift.loc.keyword)
|
63
61
|
|
64
|
-
corrector.replace(
|
62
|
+
corrector.replace(case_range, 'if')
|
65
63
|
|
66
|
-
when_nodes.
|
64
|
+
when_nodes.each do |when_node|
|
67
65
|
corrector.replace(when_node.loc.keyword, 'elsif')
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
|
-
|
72
|
-
# correct `when x, y` to `if x || y`.
|
73
|
-
def correct_multiple_alternative_whens(corrector, when_nodes)
|
69
|
+
def correct_when_conditions(corrector, when_nodes)
|
74
70
|
when_nodes.each do |when_node|
|
75
|
-
|
76
|
-
# In `when a, b, c; r` we have 4.
|
77
|
-
# In `when a, b then r` we have 3.
|
78
|
-
*children, _ = when_node.children
|
71
|
+
conditions = when_node.conditions
|
79
72
|
|
80
|
-
next unless
|
73
|
+
next unless conditions.size > 1
|
81
74
|
|
82
|
-
|
83
|
-
|
84
|
-
range = range_between(first.loc.expression.begin_pos,
|
85
|
-
last.loc.expression.end_pos)
|
75
|
+
range = range_between(conditions.first.loc.expression.begin_pos,
|
76
|
+
conditions.last.loc.expression.end_pos)
|
86
77
|
|
87
|
-
corrector.replace(range,
|
78
|
+
corrector.replace(range, conditions.map(&:source).join(' || '))
|
88
79
|
end
|
89
80
|
end
|
90
81
|
end
|
@@ -76,38 +76,38 @@ module RuboCop
|
|
76
76
|
MSG = 'Redundant `else`-clause.'.freeze
|
77
77
|
|
78
78
|
def on_normal_if_unless(node)
|
79
|
-
check(node
|
79
|
+
check(node)
|
80
80
|
end
|
81
81
|
|
82
82
|
def on_case(node)
|
83
|
-
check(node
|
83
|
+
check(node)
|
84
84
|
end
|
85
85
|
|
86
86
|
private
|
87
87
|
|
88
|
-
def check(node
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
both_check(node, else_clause)
|
96
|
-
end
|
88
|
+
def check(node)
|
89
|
+
empty_check(node) if empty_style?
|
90
|
+
nil_check(node) if nil_style?
|
91
|
+
end
|
92
|
+
|
93
|
+
def nil_style?
|
94
|
+
style == :nil || style == :both
|
97
95
|
end
|
98
96
|
|
99
|
-
def
|
100
|
-
|
97
|
+
def empty_style?
|
98
|
+
style == :empty || style == :both
|
101
99
|
end
|
102
100
|
|
103
|
-
def
|
104
|
-
return unless
|
101
|
+
def empty_check(node)
|
102
|
+
return unless node.else? && !node.else_branch
|
103
|
+
|
105
104
|
add_offense(node, :else, MSG)
|
106
105
|
end
|
107
106
|
|
108
|
-
def
|
109
|
-
|
110
|
-
|
107
|
+
def nil_check(node)
|
108
|
+
return unless node.else_branch && node.else_branch.nil_type?
|
109
|
+
|
110
|
+
add_offense(node, :else, MSG)
|
111
111
|
end
|
112
112
|
|
113
113
|
def autocorrect(node)
|
@@ -121,13 +121,11 @@ module RuboCop
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def base_if_node(node)
|
124
|
-
|
125
|
-
parent_node = parent_node.parent until parent_node.loc.end
|
126
|
-
parent_node
|
124
|
+
node.each_ancestor(:if).find { |parent| parent.loc.end } || node
|
127
125
|
end
|
128
126
|
|
129
127
|
def autocorrect_forbidden?(type)
|
130
|
-
[type, 'both'].include?
|
128
|
+
[type, 'both'].include?(missing_else_style)
|
131
129
|
end
|
132
130
|
|
133
131
|
def missing_else_style
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
27
27
|
end
|
28
28
|
|
29
29
|
str_node(node) do
|
30
|
-
return if frozen_string_literals_enabled?
|
30
|
+
return if frozen_string_literals_enabled?
|
31
31
|
|
32
32
|
add_offense(node, :expression,
|
33
33
|
format(STR_MSG, preferred_string_literal))
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
config.for_cop('Style/StringLiterals')
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
57
|
+
def first_argument_unparenthesized?(node)
|
58
58
|
return false unless node.parent && node.parent.send_type?
|
59
59
|
|
60
60
|
_receiver, _method_name, *args = *node.parent
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
|
64
64
|
def replacement_range(node)
|
65
65
|
if hash_node(node) &&
|
66
|
-
|
66
|
+
first_argument_unparenthesized?(node)
|
67
67
|
# `some_method {}` is not same as `some_method Hash.new`
|
68
68
|
# because the braces are interpreted as a block. We will have
|
69
69
|
# to rewrite the arguments to wrap them in parenthesis.
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
elsif str_node(node)
|
84
84
|
preferred_string_literal
|
85
85
|
elsif hash_node(node)
|
86
|
-
if
|
86
|
+
if first_argument_unparenthesized?(node)
|
87
87
|
# `some_method {}` is not same as `some_method Hash.new`
|
88
88
|
# because the braces are interpreted as a block. We will have
|
89
89
|
# to rewrite the arguments to wrap them in parenthesis.
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop checks for the formatting of empty method definitions.
|
7
7
|
# By default it enforces empty method definitions to go on a single
|
8
|
-
# line (compact style), but it
|
8
|
+
# line (compact style), but it can be configured to enforce the `end`
|
9
9
|
# to go on its own line (expanded style.)
|
10
10
|
#
|
11
11
|
# Note: A method definition is not considered empty if it contains
|
@@ -18,31 +18,36 @@ module RuboCop
|
|
18
18
|
# @bad
|
19
19
|
# def foo(bar)
|
20
20
|
# end
|
21
|
+
# def self.foo(bar)
|
22
|
+
# end
|
21
23
|
#
|
22
24
|
# @good
|
23
25
|
# def foo(bar); end
|
24
26
|
# def foo(bar)
|
25
27
|
# # baz
|
26
28
|
# end
|
29
|
+
# def self.foo(bar); end
|
27
30
|
#
|
28
31
|
# EnforcedStyle: expanded
|
29
32
|
#
|
30
33
|
# @bad
|
31
34
|
# def foo(bar); end
|
35
|
+
# def self.foo(bar); end
|
32
36
|
#
|
33
37
|
# @good
|
34
38
|
# def foo(bar)
|
35
39
|
# end
|
40
|
+
# def self.foo(bar)
|
41
|
+
# end
|
36
42
|
class EmptyMethod < Cop
|
43
|
+
include OnMethodDef
|
37
44
|
include ConfigurableEnforcedStyle
|
38
45
|
|
39
46
|
MSG_COMPACT = 'Put empty method definitions on a single line.'.freeze
|
40
47
|
MSG_EXPANDED = 'Put the `end` of empty method definitions on the ' \
|
41
48
|
'next line.'.freeze
|
42
49
|
|
43
|
-
def
|
44
|
-
_method_name, _args, body = *node
|
45
|
-
|
50
|
+
def on_method_def(node, _method_name, _args, body)
|
46
51
|
return if body || comment_lines?(node)
|
47
52
|
return if compact_style? && compact?(node)
|
48
53
|
return if expanded_style? && expanded?(node)
|
@@ -63,12 +68,13 @@ module RuboCop
|
|
63
68
|
end
|
64
69
|
|
65
70
|
def corrected(node)
|
66
|
-
method_name, args, _body =
|
71
|
+
method_name, args, _body, scope = method_def_node_parts(node)
|
67
72
|
|
68
73
|
arguments = args.source unless args.children.empty?
|
69
74
|
joint = compact_style? ? '; ' : "\n"
|
75
|
+
scope = scope ? 'self.' : ''
|
70
76
|
|
71
|
-
["def #{method_name}#{arguments}", 'end'].join(joint)
|
77
|
+
["def #{scope}#{method_name}#{arguments}", 'end'].join(joint)
|
72
78
|
end
|
73
79
|
|
74
80
|
def comment_lines?(node)
|
@@ -34,10 +34,10 @@ module RuboCop
|
|
34
34
|
return unless expect_matching_definition?
|
35
35
|
return if find_class_or_module(processed_source.ast,
|
36
36
|
to_namespace(file_path))
|
37
|
+
|
37
38
|
no_definition_message(basename, file_path)
|
38
39
|
else
|
39
|
-
return if
|
40
|
-
shebang?(first_line)
|
40
|
+
return if ignore_executable_scripts? && shebang?(first_line)
|
41
41
|
other_message(basename)
|
42
42
|
end
|
43
43
|
|
@@ -66,6 +66,10 @@ module RuboCop
|
|
66
66
|
line && line.start_with?('#!')
|
67
67
|
end
|
68
68
|
|
69
|
+
def ignore_executable_scripts?
|
70
|
+
cop_config['IgnoreExecutableScripts']
|
71
|
+
end
|
72
|
+
|
69
73
|
def expect_matching_definition?
|
70
74
|
cop_config['ExpectMatchingDefinition']
|
71
75
|
end
|
@@ -74,6 +78,10 @@ module RuboCop
|
|
74
78
|
cop_config['Regex']
|
75
79
|
end
|
76
80
|
|
81
|
+
def allowed_acronyms
|
82
|
+
cop_config['AllowedAcronyms'] || []
|
83
|
+
end
|
84
|
+
|
77
85
|
def filename_good?(basename)
|
78
86
|
basename = basename.sub(/\.[^\.]+$/, '')
|
79
87
|
basename =~ (regex || SNAKE_CASE)
|
@@ -87,11 +95,12 @@ module RuboCop
|
|
87
95
|
next unless (const = child.defined_module)
|
88
96
|
|
89
97
|
const_namespace, const_name = *const
|
90
|
-
next
|
98
|
+
next if name != const_name && !match_acronym?(name, const_name)
|
91
99
|
|
92
100
|
return node if namespace.empty?
|
93
101
|
return node if match_namespace(child, const_namespace, namespace)
|
94
102
|
end
|
103
|
+
|
95
104
|
nil
|
96
105
|
end
|
97
106
|
|
@@ -115,7 +124,9 @@ module RuboCop
|
|
115
124
|
|
116
125
|
namespace, name = *namespace
|
117
126
|
|
118
|
-
|
127
|
+
if name == expected.last || match_acronym?(expected.last, name)
|
128
|
+
expected.pop
|
129
|
+
end
|
119
130
|
end
|
120
131
|
|
121
132
|
false
|
@@ -126,6 +137,15 @@ module RuboCop
|
|
126
137
|
expected.empty? || expected == [:Object]
|
127
138
|
end
|
128
139
|
|
140
|
+
def match_acronym?(expected, name)
|
141
|
+
expected = expected.to_s
|
142
|
+
name = name.to_s
|
143
|
+
|
144
|
+
allowed_acronyms.any? do |acronym|
|
145
|
+
expected.gsub(acronym.capitalize, acronym) == name
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
129
149
|
def to_namespace(path)
|
130
150
|
components = Pathname(path).each_filename.to_a
|
131
151
|
# To convert a pathname to a Ruby namespace, we need a starting point
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
# ...then each key/value pair is treated as a method 'argument'
|
37
37
|
# when determining where line breaks should appear.
|
38
38
|
if (last_arg = args.last)
|
39
|
-
if last_arg.hash_type? && !last_arg.
|
39
|
+
if last_arg.hash_type? && !last_arg.braces?
|
40
40
|
args = args.concat(args.pop.children)
|
41
41
|
end
|
42
42
|
end
|
@@ -13,62 +13,31 @@ module RuboCop
|
|
13
13
|
class FormatString < Cop
|
14
14
|
include ConfigurableEnforcedStyle
|
15
15
|
|
16
|
-
|
17
|
-
add_offense(node, :selector) if offending_node?(node)
|
18
|
-
end
|
16
|
+
MSG = 'Favor `%s` over `%s`.'.freeze
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
format?(node) || percent?(node)
|
28
|
-
when :percent
|
29
|
-
format?(node) || sprintf?(node)
|
30
|
-
end
|
31
|
-
end
|
18
|
+
def_node_matcher :formatter, <<-PATTERN
|
19
|
+
{
|
20
|
+
(send nil ${:sprintf :format} _ _ ...)
|
21
|
+
(send {str dstr} $:% ... )
|
22
|
+
(send !nil $:% {array hash})
|
23
|
+
}
|
24
|
+
PATTERN
|
32
25
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
# commands have no explicit receiver
|
37
|
-
return false unless !receiver && method_name == name
|
38
|
-
|
39
|
-
# we do an argument count check to reduce false positives
|
40
|
-
args.size >= 2
|
41
|
-
end
|
26
|
+
def on_send(node)
|
27
|
+
return unless (selector = formatter(node))
|
42
28
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
29
|
+
detected_style = selector == :% ? :percent : selector
|
30
|
+
return if detected_style == style
|
46
31
|
|
47
|
-
|
48
|
-
format_method?(:sprintf, node)
|
32
|
+
add_offense(node, :selector, message(detected_style))
|
49
33
|
end
|
50
34
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
method_name == :% &&
|
55
|
-
([:str, :dstr].include?(receiver_node.type) ||
|
56
|
-
arg_nodes.first.array_type?)
|
35
|
+
def message(detected_style)
|
36
|
+
format(MSG, method_name(style), method_name(detected_style))
|
57
37
|
end
|
58
38
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
preferred =
|
63
|
-
if style == :percent
|
64
|
-
'String#%'
|
65
|
-
else
|
66
|
-
style
|
67
|
-
end
|
68
|
-
|
69
|
-
method_name = 'String#%' if method_name == :%
|
70
|
-
|
71
|
-
"Favor `#{preferred}` over `#{method_name}`."
|
39
|
+
def method_name(style_name)
|
40
|
+
style_name == :percent ? 'String#%' : style_name
|
72
41
|
end
|
73
42
|
end
|
74
43
|
end
|
@@ -13,32 +13,47 @@ module RuboCop
|
|
13
13
|
include FrozenStringLiteral
|
14
14
|
|
15
15
|
MSG = 'Missing frozen string literal comment.'.freeze
|
16
|
+
MSG_UNNECESSARY = 'Unnecessary frozen string literal comment.'.freeze
|
16
17
|
SHEBANG = '#!'.freeze
|
17
18
|
|
18
19
|
def investigate(processed_source)
|
19
20
|
return if style == :when_needed && target_ruby_version < 2.3
|
20
21
|
return if processed_source.tokens.empty?
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
if frozen_string_literal_comment_exists?
|
24
|
+
check_for_no_comment(processed_source)
|
25
|
+
else
|
26
|
+
check_for_comment(processed_source)
|
27
|
+
end
|
25
28
|
end
|
26
29
|
|
27
|
-
def autocorrect(
|
30
|
+
def autocorrect(node)
|
28
31
|
lambda do |corrector|
|
29
|
-
|
30
|
-
|
31
|
-
corrector.insert_before(processed_source.tokens[0].pos,
|
32
|
-
"#{FROZEN_STRING_LITERAL_ENABLED}\n")
|
32
|
+
if style == :never
|
33
|
+
corrector.remove(range_with_surrounding_space(node.pos, :right))
|
33
34
|
else
|
34
|
-
|
35
|
-
|
35
|
+
last_special_comment = last_special_comment(processed_source)
|
36
|
+
if last_special_comment.nil?
|
37
|
+
corrector.insert_before(processed_source.tokens[0].pos,
|
38
|
+
"#{FROZEN_STRING_LITERAL_ENABLED}\n")
|
39
|
+
else
|
40
|
+
corrector.insert_after(last_special_comment.pos,
|
41
|
+
"\n#{FROZEN_STRING_LITERAL_ENABLED}")
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
40
47
|
private
|
41
48
|
|
49
|
+
def check_for_no_comment(processed_source)
|
50
|
+
unnecessary_comment_offense(processed_source) if style == :never
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_for_comment(processed_source)
|
54
|
+
offense(processed_source) unless style == :never
|
55
|
+
end
|
56
|
+
|
42
57
|
def last_special_comment(processed_source)
|
43
58
|
token_number = 0
|
44
59
|
if processed_source.tokens[token_number].text.start_with?(SHEBANG)
|
@@ -54,13 +69,27 @@ module RuboCop
|
|
54
69
|
token
|
55
70
|
end
|
56
71
|
|
72
|
+
def frozen_string_literal_comment(processed_source)
|
73
|
+
processed_source.tokens.find do |token|
|
74
|
+
token.text.start_with?(FrozenStringLiteral::FROZEN_STRING_LITERAL)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
57
78
|
def offense(processed_source)
|
58
79
|
last_special_comment = last_special_comment(processed_source)
|
59
|
-
last_special_comment ||= processed_source.tokens[0]
|
60
80
|
range = source_range(processed_source.buffer, 0, 0)
|
61
81
|
|
62
82
|
add_offense(last_special_comment, range, MSG)
|
63
83
|
end
|
84
|
+
|
85
|
+
def unnecessary_comment_offense(processed_source)
|
86
|
+
frozen_string_literal_comment =
|
87
|
+
frozen_string_literal_comment(processed_source)
|
88
|
+
|
89
|
+
add_offense(frozen_string_literal_comment,
|
90
|
+
frozen_string_literal_comment.pos,
|
91
|
+
MSG_UNNECESSARY)
|
92
|
+
end
|
64
93
|
end
|
65
94
|
end
|
66
95
|
end
|