rubocop 0.92.0 → 1.2.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 +21 -7
- data/config/default.yml +169 -59
- data/exe/rubocop +1 -1
- data/lib/rubocop.rb +15 -3
- data/lib/rubocop/cached_data.rb +2 -1
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
- data/lib/rubocop/cli/command/version.rb +1 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_loader.rb +19 -2
- data/lib/rubocop/config_loader_resolver.rb +7 -5
- data/lib/rubocop/config_validator.rb +7 -6
- data/lib/rubocop/cop/badge.rb +9 -24
- data/lib/rubocop/cop/base.rb +16 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +23 -3
- data/lib/rubocop/cop/commissioner.rb +36 -22
- data/lib/rubocop/cop/corrector.rb +3 -1
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/force.rb +1 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
- data/lib/rubocop/cop/layout/class_structure.rb +7 -0
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +6 -9
- data/lib/rubocop/cop/layout/else_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -7
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -11
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
- data/lib/rubocop/cop/layout/space_inside_parens.rb +35 -13
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +37 -13
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -3
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +77 -0
- data/lib/rubocop/cop/lint/else_layout.rb +29 -3
- data/lib/rubocop/cop/lint/empty_block.rb +59 -0
- data/lib/rubocop/cop/lint/flip_flop.rb +8 -2
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +17 -3
- data/lib/rubocop/cop/lint/loop.rb +0 -4
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +14 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +58 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +46 -13
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +27 -8
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +95 -0
- data/lib/rubocop/cop/lint/to_json.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +185 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
- data/lib/rubocop/cop/metrics/block_length.rb +3 -1
- data/lib/rubocop/cop/metrics/class_length.rb +14 -6
- data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -1
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +12 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +11 -5
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +67 -18
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -1
- data/lib/rubocop/cop/naming/variable_number.rb +82 -8
- data/lib/rubocop/cop/offense.rb +18 -5
- data/lib/rubocop/cop/security/open.rb +12 -10
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +6 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +142 -0
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -4
- data/lib/rubocop/cop/style/case_like_if.rb +18 -6
- data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
- data/lib/rubocop/cop/style/collection_compact.rb +85 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +8 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +67 -0
- data/lib/rubocop/cop/style/double_negation.rb +6 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +6 -2
- data/lib/rubocop/cop/style/for.rb +0 -4
- data/lib/rubocop/cop/style/format_string_token.rb +48 -3
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -3
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +10 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -11
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
- data/lib/rubocop/cop/style/mixin_grouping.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +54 -7
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +99 -0
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
- data/lib/rubocop/cop/style/raise_args.rb +21 -9
- data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +45 -24
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
- data/lib/rubocop/cop/style/redundant_self.rb +3 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +16 -4
- data/lib/rubocop/cop/style/semicolon.rb +3 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +14 -2
- data/lib/rubocop/cop/style/swap_values.rb +108 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
- data/lib/rubocop/cop/team.rb +6 -1
- data/lib/rubocop/cop/util.rb +5 -1
- data/lib/rubocop/cop/variable_force/branch.rb +0 -4
- data/lib/rubocop/ext/regexp_node.rb +35 -11
- data/lib/rubocop/ext/regexp_parser.rb +84 -0
- data/lib/rubocop/formatter/formatter_set.rb +2 -1
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +47 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +2 -2
- data/lib/rubocop/options.rb +6 -1
- data/lib/rubocop/result_cache.rb +8 -2
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +4 -4
- data/lib/rubocop/target_finder.rb +23 -25
- data/lib/rubocop/version.rb +56 -6
- metadata +22 -8
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop enforces the use of `Object#instance_of?` instead of class comparison
|
7
|
+
# for equality.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# var.class == Date
|
12
|
+
# var.class.equal?(Date)
|
13
|
+
# var.class.eql?(Date)
|
14
|
+
# var.class.name == 'Date'
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# var.instance_of?(Date)
|
18
|
+
#
|
19
|
+
class ClassEqualityComparison < Base
|
20
|
+
include RangeHelp
|
21
|
+
include IgnoredMethods
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Use `instance_of?(%<class_name>s)` instead of comparing classes.'
|
25
|
+
|
26
|
+
RESTRICT_ON_SEND = %i[== equal? eql?].freeze
|
27
|
+
|
28
|
+
def_node_matcher :class_comparison_candidate?, <<~PATTERN
|
29
|
+
(send
|
30
|
+
{$(send _ :class) (send $(send _ :class) :name)}
|
31
|
+
{:== :equal? :eql?} $_)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
def_node = node.each_ancestor(:def, :defs).first
|
36
|
+
return if def_node && ignored_method?(def_node.method_name)
|
37
|
+
|
38
|
+
class_comparison_candidate?(node) do |receiver_node, class_node|
|
39
|
+
range = offense_range(receiver_node, node)
|
40
|
+
class_name = class_name(class_node, node)
|
41
|
+
|
42
|
+
add_offense(range, message: format(MSG, class_name: class_name)) do |corrector|
|
43
|
+
corrector.replace(range, "instance_of?(#{class_name})")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def class_name(class_node, node)
|
51
|
+
if node.children.first.method?(:name)
|
52
|
+
class_node.source.delete('"').delete("'")
|
53
|
+
else
|
54
|
+
class_node.source
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def offense_range(receiver_node, node)
|
59
|
+
range_between(receiver_node.loc.selector.begin_pos, node.source_range.end_pos)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for places where custom logic on rejection nils from arrays
|
7
|
+
# and hashes can be replaced with `{Array,Hash}#{compact,compact!}`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# array.reject { |e| e.nil? }
|
12
|
+
# array.select { |e| !e.nil? }
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# array.compact
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# hash.reject! { |k, v| v.nil? }
|
19
|
+
# hash.select! { |k, v| !v.nil? }
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# hash.compact!
|
23
|
+
#
|
24
|
+
class CollectionCompact < Base
|
25
|
+
include RangeHelp
|
26
|
+
extend AutoCorrector
|
27
|
+
|
28
|
+
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
29
|
+
|
30
|
+
RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
|
31
|
+
|
32
|
+
def_node_matcher :reject_method?, <<~PATTERN
|
33
|
+
(block
|
34
|
+
(send
|
35
|
+
_ ${:reject :reject!})
|
36
|
+
$(args ...)
|
37
|
+
(send
|
38
|
+
$(lvar _) :nil?))
|
39
|
+
PATTERN
|
40
|
+
|
41
|
+
def_node_matcher :select_method?, <<~PATTERN
|
42
|
+
(block
|
43
|
+
(send
|
44
|
+
_ ${:select :select!})
|
45
|
+
$(args ...)
|
46
|
+
(send
|
47
|
+
(send
|
48
|
+
$(lvar _) :nil?) :!))
|
49
|
+
PATTERN
|
50
|
+
|
51
|
+
def on_send(node)
|
52
|
+
block_node = node.parent
|
53
|
+
return unless block_node&.block_type?
|
54
|
+
|
55
|
+
return unless (method_name, args, receiver =
|
56
|
+
reject_method?(block_node) || select_method?(block_node))
|
57
|
+
|
58
|
+
return unless args.last.source == receiver.source
|
59
|
+
|
60
|
+
range = offense_range(node, block_node)
|
61
|
+
good = good_method_name(method_name)
|
62
|
+
message = format(MSG, good: good, bad: range.source)
|
63
|
+
|
64
|
+
add_offense(range, message: message) do |corrector|
|
65
|
+
corrector.replace(range, good)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def good_method_name(method_name)
|
72
|
+
if method_name.to_s.end_with?('!')
|
73
|
+
'compact!'
|
74
|
+
else
|
75
|
+
'compact'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def offense_range(send_node, block_node)
|
80
|
+
range_between(send_node.loc.selector.begin_pos, block_node.loc.end.end_pos)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -49,6 +49,12 @@ module RuboCop
|
|
49
49
|
# end
|
50
50
|
# end
|
51
51
|
#
|
52
|
+
# # good
|
53
|
+
# def method
|
54
|
+
# each_slice(2) { |slice| do_something(slice) }
|
55
|
+
# each_slice(3) { |slice| do_something(slice) }
|
56
|
+
# end
|
57
|
+
#
|
52
58
|
class CombinableLoops < Base
|
53
59
|
MSG = 'Combine this loop with the previous loop.'
|
54
60
|
|
@@ -76,7 +82,8 @@ module RuboCop
|
|
76
82
|
def same_collection_looping?(node, sibling)
|
77
83
|
sibling&.block_type? &&
|
78
84
|
sibling.send_node.method?(node.method_name) &&
|
79
|
-
sibling.send_node.receiver == node.send_node.receiver
|
85
|
+
sibling.send_node.receiver == node.send_node.receiver &&
|
86
|
+
sibling.send_node.arguments == node.send_node.arguments
|
80
87
|
end
|
81
88
|
end
|
82
89
|
end
|
@@ -6,6 +6,12 @@ module RuboCop
|
|
6
6
|
# This cop checks that comment annotation keywords are written according
|
7
7
|
# to guidelines.
|
8
8
|
#
|
9
|
+
# NOTE: With a multiline comment block (where each line is only a
|
10
|
+
# comment), only the first line will be able to register an offense, even
|
11
|
+
# if an annotation keyword starts another line. This is done to prevent
|
12
|
+
# incorrect registering of keywords (eg. `review`) inside a paragraph as an
|
13
|
+
# annotation.
|
14
|
+
#
|
9
15
|
# @example
|
10
16
|
# # bad
|
11
17
|
# # TODO make better
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# When using `class_eval` (or other `eval`) with string interpolation,
|
7
|
+
# add a comment block showing its appearance if interpolated (a practice used in Rails code).
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # from activesupport/lib/active_support/core_ext/string/output_safety.rb
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# UNSAFE_STRING_METHODS.each do |unsafe_method|
|
14
|
+
# if 'String'.respond_to?(unsafe_method)
|
15
|
+
# class_eval <<-EOT, __FILE__, __LINE__ + 1
|
16
|
+
# def #{unsafe_method}(*params, &block)
|
17
|
+
# to_str.#{unsafe_method}(*params, &block)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def #{unsafe_method}!(*params)
|
21
|
+
# @dirty = true
|
22
|
+
# super
|
23
|
+
# end
|
24
|
+
# EOT
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# UNSAFE_STRING_METHODS.each do |unsafe_method|
|
30
|
+
# if 'String'.respond_to?(unsafe_method)
|
31
|
+
# class_eval <<-EOT, __FILE__, __LINE__ + 1
|
32
|
+
# def #{unsafe_method}(*params, &block) # def capitalize(*params, &block)
|
33
|
+
# to_str.#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block)
|
34
|
+
# end # end
|
35
|
+
#
|
36
|
+
# def #{unsafe_method}!(*params) # def capitalize!(*params)
|
37
|
+
# @dirty = true # @dirty = true
|
38
|
+
# super # super
|
39
|
+
# end # end
|
40
|
+
# EOT
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
class DocumentDynamicEvalDefinition < Base
|
45
|
+
MSG = 'Add a comment block showing its appearance if interpolated.'
|
46
|
+
|
47
|
+
RESTRICT_ON_SEND = %i[eval class_eval module_eval instance_eval].freeze
|
48
|
+
|
49
|
+
def on_send(node)
|
50
|
+
arg_node = node.first_argument
|
51
|
+
return unless arg_node&.dstr_type?
|
52
|
+
|
53
|
+
add_offense(node.loc.selector) unless comment_docs?(arg_node)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def comment_docs?(node)
|
59
|
+
node.each_child_node(:begin).all? do |begin_node|
|
60
|
+
source_line = processed_source.lines[begin_node.first_line - 1]
|
61
|
+
source_line.match?(/\s*#[^{]+/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -34,6 +34,7 @@ module RuboCop
|
|
34
34
|
# this is rarely a problem in practice.
|
35
35
|
class DoubleNegation < Base
|
36
36
|
include ConfigurableEnforcedStyle
|
37
|
+
extend AutoCorrector
|
37
38
|
|
38
39
|
MSG = 'Avoid the use of double negation (`!!`).'
|
39
40
|
RESTRICT_ON_SEND = %i[!].freeze
|
@@ -44,7 +45,11 @@ module RuboCop
|
|
44
45
|
return unless double_negative?(node) && node.prefix_bang?
|
45
46
|
return if style == :allowed_in_returns && allowed_in_returns?(node)
|
46
47
|
|
47
|
-
|
48
|
+
location = node.loc.selector
|
49
|
+
add_offense(location) do |corrector|
|
50
|
+
corrector.remove(location)
|
51
|
+
corrector.insert_after(node, '.nil?')
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
private
|
@@ -57,12 +57,16 @@ module RuboCop
|
|
57
57
|
yielding_block?(block_node) do |send_node, block_args, yield_args|
|
58
58
|
return unless yielding_arguments?(block_args, yield_args)
|
59
59
|
|
60
|
+
def_node = block_node.each_ancestor(:def, :defs).first
|
61
|
+
# if `yield` is being called outside of a method context, ignore
|
62
|
+
# this is not a valid ruby pattern, but can happen in haml or erb,
|
63
|
+
# so this can cause crashes in haml_lint
|
64
|
+
return unless def_node
|
65
|
+
|
60
66
|
add_offense(block_node) do |corrector|
|
61
67
|
corrector.remove(block_body_range(block_node, send_node))
|
62
68
|
|
63
69
|
add_block_argument(send_node, corrector)
|
64
|
-
|
65
|
-
def_node = block_node.each_ancestor(:def, :defs).first
|
66
70
|
add_block_argument(def_node, corrector) if @def_nodes.add?(def_node)
|
67
71
|
end
|
68
72
|
end
|
@@ -49,8 +49,6 @@ module RuboCop
|
|
49
49
|
|
50
50
|
def on_for(node)
|
51
51
|
if style == :each
|
52
|
-
return unless opposite_style_detected
|
53
|
-
|
54
52
|
add_offense(node, message: PREFER_EACH) do |corrector|
|
55
53
|
ForToEachCorrector.new(node).call(corrector)
|
56
54
|
end
|
@@ -63,8 +61,6 @@ module RuboCop
|
|
63
61
|
return unless suspect_enumerable?(node)
|
64
62
|
|
65
63
|
if style == :for
|
66
|
-
return unless opposite_style_detected
|
67
|
-
|
68
64
|
add_offense(node, message: PREFER_FOR) do |corrector|
|
69
65
|
EachToForCorrector.new(node).call(corrector)
|
70
66
|
end
|
@@ -33,10 +33,31 @@ module RuboCop
|
|
33
33
|
#
|
34
34
|
# # bad
|
35
35
|
# format('%<greeting>s', greeting: 'Hello')
|
36
|
-
# format('%{greeting}', 'Hello')
|
36
|
+
# format('%{greeting}', greeting: 'Hello')
|
37
37
|
#
|
38
38
|
# # good
|
39
39
|
# format('%s', 'Hello')
|
40
|
+
#
|
41
|
+
# It is allowed to contain unannotated token
|
42
|
+
# if the number of them is less than or equals to
|
43
|
+
# `MaxUnannotatedPlaceholdersAllowed`.
|
44
|
+
#
|
45
|
+
# @example MaxUnannotatedPlaceholdersAllowed: 0
|
46
|
+
#
|
47
|
+
# # bad
|
48
|
+
# format('%06d', 10)
|
49
|
+
# format('%s %s.', 'Hello', 'world')
|
50
|
+
#
|
51
|
+
# # good
|
52
|
+
# format('%<number>06d', number: 10)
|
53
|
+
#
|
54
|
+
# @example MaxUnannotatedPlaceholdersAllowed: 1 (default)
|
55
|
+
#
|
56
|
+
# # bad
|
57
|
+
# format('%s %s.', 'Hello', 'world')
|
58
|
+
#
|
59
|
+
# # good
|
60
|
+
# format('%06d', 10)
|
40
61
|
class FormatStringToken < Base
|
41
62
|
include ConfigurableEnforcedStyle
|
42
63
|
|
@@ -44,8 +65,12 @@ module RuboCop
|
|
44
65
|
return unless node.value.include?('%')
|
45
66
|
return if node.each_ancestor(:xstr, :regexp).any?
|
46
67
|
|
47
|
-
|
48
|
-
|
68
|
+
detections = collect_detections(node)
|
69
|
+
return if detections.empty?
|
70
|
+
return if allowed_unannotated?(detections)
|
71
|
+
|
72
|
+
detections.each do |detected_style, token_range|
|
73
|
+
if detected_style == style
|
49
74
|
correct_style_detected
|
50
75
|
else
|
51
76
|
style_detected(detected_style)
|
@@ -112,6 +137,26 @@ module RuboCop
|
|
112
137
|
yield(detected_style, token)
|
113
138
|
end
|
114
139
|
end
|
140
|
+
|
141
|
+
def collect_detections(node)
|
142
|
+
detections = []
|
143
|
+
tokens(node) do |detected_style, token_range|
|
144
|
+
unless unannotated_format?(node, detected_style)
|
145
|
+
detections << [detected_style, token_range]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
detections
|
149
|
+
end
|
150
|
+
|
151
|
+
def allowed_unannotated?(detections)
|
152
|
+
return false if detections.size > max_unannotated_placeholders_allowed
|
153
|
+
|
154
|
+
detections.all? { |detected_style,| detected_style == :unannotated }
|
155
|
+
end
|
156
|
+
|
157
|
+
def max_unannotated_placeholders_allowed
|
158
|
+
cop_config['MaxUnannotatedPlaceholdersAllowed']
|
159
|
+
end
|
115
160
|
end
|
116
161
|
end
|
117
162
|
end
|
@@ -97,10 +97,10 @@ module RuboCop
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def no_mixed_keys_check(pairs)
|
100
|
-
if
|
101
|
-
check(pairs, ':', MSG_NO_MIXED_KEYS)
|
102
|
-
else
|
100
|
+
if sym_indices?(pairs)
|
103
101
|
check(pairs, pairs.first.inverse_delimiter, MSG_NO_MIXED_KEYS)
|
102
|
+
else
|
103
|
+
check(pairs, ':', MSG_NO_MIXED_KEYS)
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -34,6 +34,10 @@ module RuboCop
|
|
34
34
|
add_offense(node) do |corrector|
|
35
35
|
if node.parent.find(&:kwoptarg_type?) == node
|
36
36
|
corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
|
37
|
+
|
38
|
+
arguments = node.each_ancestor(:def, :defs).first.arguments
|
39
|
+
append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
|
40
|
+
|
37
41
|
remove_kwargs(kwarg_nodes, corrector)
|
38
42
|
end
|
39
43
|
end
|
@@ -41,6 +45,14 @@ module RuboCop
|
|
41
45
|
|
42
46
|
private
|
43
47
|
|
48
|
+
def append_newline_to_last_kwoptarg(arguments, corrector)
|
49
|
+
last_argument = arguments.last
|
50
|
+
return if last_argument.kwrestarg_type? || last_argument.blockarg_type?
|
51
|
+
|
52
|
+
last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
|
53
|
+
corrector.insert_after(last_kwoptarg, "\n")
|
54
|
+
end
|
55
|
+
|
44
56
|
def remove_kwargs(kwarg_nodes, corrector)
|
45
57
|
kwarg_nodes.each do |kwarg|
|
46
58
|
with_space = range_with_surrounding_space(range: kwarg.source_range)
|
@@ -144,25 +144,22 @@ module RuboCop
|
|
144
144
|
# # good
|
145
145
|
# Array 1
|
146
146
|
class MethodCallWithArgsParentheses < Base
|
147
|
+
require_relative 'method_call_with_args_parentheses/omit_parentheses'
|
148
|
+
require_relative 'method_call_with_args_parentheses/require_parentheses'
|
149
|
+
|
147
150
|
include ConfigurableEnforcedStyle
|
148
151
|
include IgnoredMethods
|
149
152
|
include IgnoredPattern
|
153
|
+
include RequireParentheses
|
154
|
+
include OmitParentheses
|
150
155
|
extend AutoCorrector
|
151
156
|
|
152
|
-
def
|
153
|
-
|
154
|
-
return unless style_configured?
|
155
|
-
|
156
|
-
case style
|
157
|
-
when :require_parentheses
|
158
|
-
extend RequireParentheses
|
159
|
-
when :omit_parentheses
|
160
|
-
extend OmitParentheses
|
161
|
-
end
|
157
|
+
def on_send(node)
|
158
|
+
send(style, node) # call require_parentheses or omit_parentheses
|
162
159
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
160
|
+
alias on_csend on_send
|
161
|
+
alias on_super on_send
|
162
|
+
alias on_yield on_send
|
166
163
|
|
167
164
|
private
|
168
165
|
|