rubocop 0.93.1 → 1.6.1
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 +36 -16
- data/config/default.yml +276 -82
- data/config/obsoletion.yml +196 -0
- data/exe/rubocop +1 -1
- data/lib/rubocop.rb +31 -2
- data/lib/rubocop/cli.rb +5 -1
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
- data/lib/rubocop/cli/command/execute_runner.rb +26 -11
- data/lib/rubocop/cli/command/suggest_extensions.rb +80 -0
- 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 +34 -8
- data/lib/rubocop/config_loader_resolver.rb +12 -6
- data/lib/rubocop/config_obsoletion.rb +65 -247
- data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
- data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
- data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
- data/lib/rubocop/config_obsoletion/rule.rb +41 -0
- data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
- data/lib/rubocop/config_regeneration.rb +1 -1
- data/lib/rubocop/config_validator.rb +25 -10
- data/lib/rubocop/cop/autocorrect_logic.rb +21 -6
- data/lib/rubocop/cop/badge.rb +9 -24
- data/lib/rubocop/cop/base.rb +33 -16
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +26 -6
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/commissioner.rb +37 -23
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/corrector.rb +3 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/force.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -3
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +4 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +3 -10
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/class_structure.rb +22 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +80 -10
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +6 -1
- 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/end_of_line.rb +5 -5
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +12 -0
- data/lib/rubocop/cop/layout/line_length.rb +10 -13
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +7 -3
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- 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_regexp_literal.rb +2 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +26 -2
- data/lib/rubocop/cop/lint/debugger.rb +17 -28
- data/lib/rubocop/cop/lint/duplicate_branch.rb +93 -0
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +2 -12
- 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 +82 -0
- data/lib/rubocop/cop/lint/empty_class.rb +93 -0
- data/lib/rubocop/cop/lint/flip_flop.rb +8 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +39 -7
- data/lib/rubocop/cop/lint/loop.rb +4 -4
- data/lib/rubocop/cop/lint/missing_super.rb +7 -4
- 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/redundant_cop_enable_directive.rb +19 -16
- data/lib/rubocop/cop/lint/shadowed_exception.rb +4 -5
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +86 -0
- data/lib/rubocop/cop/lint/to_json.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +85 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +199 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_method_definition.rb +2 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
- data/lib/rubocop/cop/metrics/abc_size.rb +25 -1
- data/lib/rubocop/cop/metrics/block_length.rb +13 -7
- data/lib/rubocop/cop/metrics/method_length.rb +7 -2
- data/lib/rubocop/cop/metrics/parameter_lists.rb +68 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +20 -10
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +146 -0
- data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +6 -1
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +4 -3
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +9 -1
- data/lib/rubocop/cop/mixin/ignored_methods.rb +36 -3
- data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +6 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -4
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +1 -3
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -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 +100 -8
- data/lib/rubocop/cop/offense.rb +3 -3
- data/lib/rubocop/cop/security/open.rb +12 -10
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +11 -3
- 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 +0 -4
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +8 -3
- data/lib/rubocop/cop/style/collection_compact.rb +91 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +169 -0
- data/lib/rubocop/cop/style/documentation.rb +12 -1
- data/lib/rubocop/cop/style/double_negation.rb +6 -1
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/format_string.rb +8 -3
- data/lib/rubocop/cop/style/format_string_token.rb +47 -2
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +7 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +37 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +39 -4
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- 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 +8 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +55 -7
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +106 -0
- data/lib/rubocop/cop/style/nil_lambda.rb +52 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +14 -11
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +21 -6
- data/lib/rubocop/cop/style/redundant_argument.rb +88 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +24 -8
- 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/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +65 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/static_class.rb +97 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +39 -2
- data/lib/rubocop/cop/style/string_literals.rb +14 -8
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
- data/lib/rubocop/cop/style/swap_values.rb +108 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -3
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +9 -0
- data/lib/rubocop/cop/team.rb +6 -1
- data/lib/rubocop/cop/util.rb +6 -2
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/core_ext/hash.rb +20 -0
- data/lib/rubocop/ext/regexp_node.rb +36 -11
- data/lib/rubocop/ext/regexp_parser.rb +95 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -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/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/magic_comment.rb +2 -2
- data/lib/rubocop/options.rb +11 -1
- data/lib/rubocop/rake_task.rb +2 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +65 -1
- data/lib/rubocop/version.rb +56 -6
- metadata +50 -9
- data/bin/console +0 -10
- data/bin/rubocop-profile +0 -32
- data/bin/setup +0 -7
@@ -26,9 +26,10 @@ module RuboCop
|
|
26
26
|
# "Just some text"
|
27
27
|
# "No special chars or interpolation"
|
28
28
|
# "Every string in #{project} uses double_quotes"
|
29
|
-
class StringLiterals <
|
29
|
+
class StringLiterals < Base
|
30
30
|
include ConfigurableEnforcedStyle
|
31
31
|
include StringLiteralsHelp
|
32
|
+
extend AutoCorrector
|
32
33
|
|
33
34
|
MSG_INCONSISTENT = 'Inconsistent quote style.'
|
34
35
|
|
@@ -46,7 +47,7 @@ module RuboCop
|
|
46
47
|
quote_styles = detect_quote_styles(node)
|
47
48
|
|
48
49
|
if quote_styles.size > 1
|
49
|
-
|
50
|
+
register_offense(node, message: MSG_INCONSISTENT)
|
50
51
|
else
|
51
52
|
check_multiline_quote_style(node, quote_styles[0])
|
52
53
|
end
|
@@ -54,11 +55,17 @@ module RuboCop
|
|
54
55
|
ignore_node(node)
|
55
56
|
end
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
private
|
59
|
+
|
60
|
+
def autocorrect(corrector, node)
|
61
|
+
StringLiteralCorrector.correct(corrector, node, style)
|
59
62
|
end
|
60
63
|
|
61
|
-
|
64
|
+
def register_offense(node, message: nil)
|
65
|
+
add_offense(node, message: message || message(node)) do |corrector|
|
66
|
+
autocorrect(corrector, node)
|
67
|
+
end
|
68
|
+
end
|
62
69
|
|
63
70
|
def all_string_literals?(nodes)
|
64
71
|
nodes.all? { |n| n.str_type? || n.dstr_type? }
|
@@ -99,14 +106,13 @@ module RuboCop
|
|
99
106
|
end
|
100
107
|
|
101
108
|
def check_multiline_quote_style(node, quote)
|
102
|
-
range = node.source_range
|
103
109
|
children = node.children
|
104
110
|
if unexpected_single_quotes?(quote)
|
105
111
|
all_children_with_quotes = children.all? { |c| wrong_quotes?(c) }
|
106
|
-
|
112
|
+
register_offense(node) if all_children_with_quotes
|
107
113
|
elsif unexpected_double_quotes?(quote) &&
|
108
114
|
!accept_child_double_quotes?(children)
|
109
|
-
|
115
|
+
register_offense(node)
|
110
116
|
end
|
111
117
|
end
|
112
118
|
|
@@ -19,12 +19,13 @@ module RuboCop
|
|
19
19
|
#
|
20
20
|
# # good
|
21
21
|
# result = "Tests #{success ? "PASS" : "FAIL"}"
|
22
|
-
class StringLiteralsInInterpolation <
|
22
|
+
class StringLiteralsInInterpolation < Base
|
23
23
|
include ConfigurableEnforcedStyle
|
24
24
|
include StringLiteralsHelp
|
25
|
+
extend AutoCorrector
|
25
26
|
|
26
|
-
def autocorrect(node)
|
27
|
-
StringLiteralCorrector.correct(node, style)
|
27
|
+
def autocorrect(corrector, node)
|
28
|
+
StringLiteralCorrector.correct(corrector, node, style)
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop enforces the use of shorthand-style swapping of 2 variables.
|
7
|
+
# Its autocorrection is marked as unsafe, because it can erroneously remove
|
8
|
+
# the temporary variable which is used later.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# tmp = x
|
13
|
+
# x = y
|
14
|
+
# y = tmp
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# x, y = y, x
|
18
|
+
#
|
19
|
+
class SwapValues < Base
|
20
|
+
include RangeHelp
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Replace this and assignments at lines %<x_line>d '\
|
24
|
+
'and %<y_line>d with `%<replacement>s`.'
|
25
|
+
|
26
|
+
SIMPLE_ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn casgn].to_set.freeze
|
27
|
+
|
28
|
+
def on_asgn(node)
|
29
|
+
return if allowed_assignment?(node)
|
30
|
+
|
31
|
+
tmp_assign = node
|
32
|
+
x_assign, y_assign = *node.right_siblings.take(2)
|
33
|
+
return unless x_assign && y_assign && swapping_values?(tmp_assign, x_assign, y_assign)
|
34
|
+
|
35
|
+
add_offense(node, message: message(x_assign, y_assign)) do |corrector|
|
36
|
+
range = correction_range(tmp_assign, y_assign)
|
37
|
+
corrector.replace(range, replacement(x_assign))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
SIMPLE_ASSIGNMENT_TYPES.each { |asgn_type| alias_method :"on_#{asgn_type}", :on_asgn }
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def allowed_assignment?(node)
|
46
|
+
node.parent&.mlhs_type? || node.parent&.shorthand_asgn?
|
47
|
+
end
|
48
|
+
|
49
|
+
def swapping_values?(tmp_assign, x_assign, y_assign)
|
50
|
+
simple_assignment?(tmp_assign) &&
|
51
|
+
simple_assignment?(x_assign) &&
|
52
|
+
simple_assignment?(y_assign) &&
|
53
|
+
lhs(x_assign) == rhs(tmp_assign) &&
|
54
|
+
lhs(y_assign) == rhs(x_assign) &&
|
55
|
+
rhs(y_assign) == lhs(tmp_assign)
|
56
|
+
end
|
57
|
+
|
58
|
+
def simple_assignment?(node)
|
59
|
+
SIMPLE_ASSIGNMENT_TYPES.include?(node.type)
|
60
|
+
end
|
61
|
+
|
62
|
+
def message(x_assign, y_assign)
|
63
|
+
format(
|
64
|
+
MSG,
|
65
|
+
x_line: x_assign.first_line,
|
66
|
+
y_line: y_assign.first_line,
|
67
|
+
replacement: replacement(x_assign)
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def replacement(x_assign)
|
72
|
+
x = lhs(x_assign)
|
73
|
+
y = rhs(x_assign)
|
74
|
+
"#{x}, #{y} = #{y}, #{x}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def lhs(node)
|
78
|
+
case node.type
|
79
|
+
when :casgn
|
80
|
+
namespace, name, = *node
|
81
|
+
if namespace
|
82
|
+
"#{namespace.const_name}::#{name}"
|
83
|
+
else
|
84
|
+
name.to_s
|
85
|
+
end
|
86
|
+
else
|
87
|
+
node.children[0].to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def rhs(node)
|
92
|
+
case node.type
|
93
|
+
when :casgn
|
94
|
+
node.children[2].source
|
95
|
+
else
|
96
|
+
node.children[1].source
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def correction_range(tmp_assign, y_assign)
|
101
|
+
range_by_whole_lines(
|
102
|
+
range_between(tmp_assign.source_range.begin_pos, y_assign.source_range.end_pos)
|
103
|
+
)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -8,6 +8,7 @@ module RuboCop
|
|
8
8
|
# @example
|
9
9
|
# # bad
|
10
10
|
# something.map { |s| s.upcase }
|
11
|
+
# something.map { _1.upcase }
|
11
12
|
#
|
12
13
|
# # good
|
13
14
|
# something.map(&:upcase)
|
@@ -22,9 +23,9 @@ module RuboCop
|
|
22
23
|
|
23
24
|
def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
|
24
25
|
def_node_matcher :symbol_proc?, <<~PATTERN
|
25
|
-
(block
|
26
|
+
({block numblock}
|
26
27
|
${(send ...) (super ...) zsuper}
|
27
|
-
$(args (arg
|
28
|
+
${(args (arg _)) %Integer}
|
28
29
|
(send (lvar _var) $_))
|
29
30
|
PATTERN
|
30
31
|
|
@@ -40,11 +41,12 @@ module RuboCop
|
|
40
41
|
return if proc_node?(dispatch_node)
|
41
42
|
return if %i[lambda proc].include?(dispatch_node.method_name)
|
42
43
|
return if ignored_method?(dispatch_node.method_name)
|
43
|
-
return if destructuring_block_argument?(arguments_node)
|
44
|
+
return if node.block_type? && destructuring_block_argument?(arguments_node)
|
44
45
|
|
45
46
|
register_offense(node, method_name, dispatch_node.method_name)
|
46
47
|
end
|
47
48
|
end
|
49
|
+
alias on_numblock on_block
|
48
50
|
|
49
51
|
def destructuring_block_argument?(argument_node)
|
50
52
|
argument_node.one? && argument_node.source.include?(',')
|
@@ -36,6 +36,8 @@ module RuboCop
|
|
36
36
|
MSG = 'Do not use trailing `_`s in parallel assignment. ' \
|
37
37
|
'Prefer `%<code>s`.'
|
38
38
|
UNDERSCORE = '_'
|
39
|
+
DISALLOW = %i[lvasgn splat].freeze
|
40
|
+
private_constant :DISALLOW
|
39
41
|
|
40
42
|
def on_masgn(node)
|
41
43
|
ranges = unneeded_ranges(node)
|
@@ -64,7 +66,7 @@ module RuboCop
|
|
64
66
|
|
65
67
|
def find_first_possible_offense(variables)
|
66
68
|
variables.reduce(nil) do |offense, variable|
|
67
|
-
break offense unless
|
69
|
+
break offense unless DISALLOW.include?(variable.type)
|
68
70
|
|
69
71
|
var, = *variable
|
70
72
|
var, = *var
|
@@ -24,6 +24,15 @@ module RuboCop
|
|
24
24
|
#
|
25
25
|
# # good
|
26
26
|
# x += 1 until x > 10
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# # bad
|
30
|
+
# x += 100 while x < 500 # a long comment that makes code too long if it were a single line
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# while x < 500 # a long comment that makes code too long if it were a single line
|
34
|
+
# x += 100
|
35
|
+
# end
|
27
36
|
class WhileUntilModifier < Base
|
28
37
|
include StatementModifier
|
29
38
|
extend AutoCorrector
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -99,7 +99,12 @@ module RuboCop
|
|
99
99
|
def self.forces_for(cops)
|
100
100
|
needed = Hash.new { |h, k| h[k] = [] }
|
101
101
|
cops.each do |cop|
|
102
|
-
|
102
|
+
forces = cop.class.joining_forces
|
103
|
+
if forces.is_a?(Array)
|
104
|
+
forces.each { |force| needed[force] << cop }
|
105
|
+
elsif forces
|
106
|
+
needed[forces] << cop
|
107
|
+
end
|
103
108
|
end
|
104
109
|
|
105
110
|
needed.map do |force_class, joining_cops|
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def on_node(syms, sexp, excludes = [], &block)
|
56
|
-
return to_enum(:on_node, syms, sexp, excludes) unless
|
56
|
+
return to_enum(:on_node, syms, sexp, excludes) unless block
|
57
57
|
|
58
58
|
yield sexp if Array(syms).include?(sexp.type)
|
59
59
|
return if Array(excludes).include?(sexp.type)
|
@@ -62,7 +62,7 @@ module RuboCop
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def begins_its_line?(range)
|
65
|
-
|
65
|
+
range.source_line.index(/\S/) == range.column
|
66
66
|
end
|
67
67
|
|
68
68
|
# Returns, for example, a bare `if` node if the given node is an `if`
|
@@ -123,6 +123,10 @@ module RuboCop
|
|
123
123
|
node1.loc.line == node2.loc.line
|
124
124
|
end
|
125
125
|
|
126
|
+
def indent(node)
|
127
|
+
' ' * node.loc.column
|
128
|
+
end
|
129
|
+
|
126
130
|
def to_supported_styles(enforced_style)
|
127
131
|
enforced_style
|
128
132
|
.sub(/^Enforced/, 'Supported')
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def each_ancestor(include_self: false, &block)
|
81
|
-
return to_enum(__method__, include_self: include_self) unless
|
81
|
+
return to_enum(__method__, include_self: include_self) unless block
|
82
82
|
|
83
83
|
yield self if include_self
|
84
84
|
scan_ancestors(&block)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extensions to the core Hash class
|
4
|
+
class Hash
|
5
|
+
unless method_defined?(:slice)
|
6
|
+
# Adds `Hash#slice` for Ruby 2.4.
|
7
|
+
# Returns a hash containing a subset of keys. If a given key is not
|
8
|
+
# in the hash, it will not be returned.
|
9
|
+
#
|
10
|
+
# @return [Hash] hash containing only the keys given.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# { one: 1, two: 2 }.slice(:two, :three) #=> { two: 2 }
|
14
|
+
def slice(*keys)
|
15
|
+
h = {}
|
16
|
+
keys.each { |k| h[k] = self[k] if key?(k) }
|
17
|
+
h
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -10,18 +10,43 @@ module RuboCop
|
|
10
10
|
end
|
11
11
|
private_constant :ANY
|
12
12
|
|
13
|
-
class << self
|
14
|
-
attr_reader :parsed_cache
|
15
|
-
end
|
16
|
-
@parsed_cache = {}
|
17
|
-
|
18
13
|
# @return [Regexp::Expression::Root, nil]
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
# Note: we extend Regexp nodes to provide `loc` and `expression`
|
15
|
+
# see `ext/regexp_parser`.
|
16
|
+
attr_reader :parsed_tree
|
17
|
+
|
18
|
+
if Gem::Version.new(Regexp::Parser::VERSION) >= Gem::Version.new('2.0')
|
19
|
+
def assign_properties(*)
|
20
|
+
super
|
21
|
+
|
22
|
+
str = with_interpolations_blanked
|
23
|
+
@parsed_tree = begin
|
24
|
+
Regexp::Parser.parse(str, options: options)
|
25
|
+
rescue StandardError
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
origin = loc.begin.end
|
29
|
+
@parsed_tree&.each_expression(true) { |e| e.origin = origin }
|
30
|
+
end
|
31
|
+
# Please remove this `else` branch when support for regexp_parser 1.8 will be dropped.
|
32
|
+
# It's for compatibility with regexp_arser 1.8 and will never be maintained.
|
33
|
+
else
|
34
|
+
def assign_properties(*)
|
35
|
+
super
|
36
|
+
|
37
|
+
str = with_interpolations_blanked
|
38
|
+
begin
|
39
|
+
@parsed_tree = Regexp::Parser.parse(str, options: options)
|
40
|
+
rescue StandardError
|
41
|
+
@parsed_tree = nil
|
42
|
+
else
|
43
|
+
origin = loc.begin.end
|
44
|
+
source = @parsed_tree.to_s
|
45
|
+
@parsed_tree.each_expression(true) do |e|
|
46
|
+
e.origin = origin
|
47
|
+
e.source = source
|
48
|
+
end
|
49
|
+
end
|
25
50
|
end
|
26
51
|
end
|
27
52
|
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Ext
|
5
|
+
# Extensions for `regexp_parser` gem
|
6
|
+
module RegexpParser
|
7
|
+
# Source map for RegexpParser nodes
|
8
|
+
class Map < ::Parser::Source::Map
|
9
|
+
attr_reader :body, :quantifier, :begin, :end
|
10
|
+
|
11
|
+
def initialize(expression, body:, quantifier: nil, begin_l: nil, end_l: nil)
|
12
|
+
@begin = begin_l
|
13
|
+
@end = end_l
|
14
|
+
@body = body
|
15
|
+
@quantifier = quantifier
|
16
|
+
super(expression)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Expression
|
21
|
+
# Add `expression` and `loc` to all `regexp_parser` nodes
|
22
|
+
module Base
|
23
|
+
attr_accessor :origin
|
24
|
+
|
25
|
+
if Gem::Version.new(Regexp::Parser::VERSION) >= Gem::Version.new('2.0')
|
26
|
+
# Shortcut to `loc.expression`
|
27
|
+
def expression
|
28
|
+
@expression ||= origin.adjust(begin_pos: ts, end_pos: ts + full_length)
|
29
|
+
end
|
30
|
+
# Please remove this `else` branch when support for regexp_parser 1.8 will be dropped.
|
31
|
+
# It's for compatibility with regexp_arser 1.8 and will never be maintained.
|
32
|
+
else
|
33
|
+
attr_accessor :source
|
34
|
+
|
35
|
+
def start_index
|
36
|
+
# ts is a byte index; convert it to a character index
|
37
|
+
@start_index ||= source.byteslice(0, ts).length
|
38
|
+
end
|
39
|
+
|
40
|
+
# Shortcut to `loc.expression`
|
41
|
+
def expression
|
42
|
+
@expression ||= begin
|
43
|
+
origin.adjust(begin_pos: start_index, end_pos: start_index + full_length)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @returns a location map like `parser` does, with:
|
49
|
+
# - expression: complete expression
|
50
|
+
# - quantifier: for `+`, `{1,2}`, etc.
|
51
|
+
# - begin/end: for `[` and `]` (only CharacterSet for now)
|
52
|
+
#
|
53
|
+
# E.g.
|
54
|
+
# [a-z]{2,}
|
55
|
+
# ^^^^^^^^^ expression
|
56
|
+
# ^^^^ quantifier
|
57
|
+
# ^^^^^ body
|
58
|
+
# ^ begin
|
59
|
+
# ^ end
|
60
|
+
#
|
61
|
+
# Please open issue if you need other locations
|
62
|
+
def loc
|
63
|
+
@loc ||= begin
|
64
|
+
Map.new(expression, **build_location)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def build_location
|
71
|
+
return { body: expression } unless (q = quantifier)
|
72
|
+
|
73
|
+
body = expression.adjust(end_pos: -q.text.length)
|
74
|
+
q_loc = expression.with(begin_pos: body.end_pos)
|
75
|
+
{ body: body, quantifier: q_loc }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Provide `CharacterSet` with `begin` and `end` locations.
|
80
|
+
module CharacterSet
|
81
|
+
def build_location
|
82
|
+
h = super
|
83
|
+
body = h[:body]
|
84
|
+
h.merge!(
|
85
|
+
begin_l: body.with(end_pos: body.begin_pos + 1),
|
86
|
+
end_l: body.with(begin_pos: body.end_pos - 1)
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
::Regexp::Expression::Base.include Expression::Base
|
92
|
+
::Regexp::Expression::CharacterSet.include Expression::CharacterSet
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|