rubocop 1.18.2 → 1.19.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 +1 -1
- data/config/default.yml +23 -6
- data/lib/rubocop.rb +4 -0
- data/lib/rubocop/cli.rb +18 -0
- data/lib/rubocop/config_loader.rb +1 -1
- data/lib/rubocop/config_loader_resolver.rb +22 -7
- data/lib/rubocop/config_validator.rb +18 -5
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/require_library_corrector.rb +23 -0
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +71 -0
- data/lib/rubocop/cop/layout/class_structure.rb +5 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +10 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +22 -18
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -7
- data/lib/rubocop/cop/layout/indentation_style.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +36 -22
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +22 -9
- data/lib/rubocop/cop/layout/space_around_operators.rb +12 -1
- data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +5 -5
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +24 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +105 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +5 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +8 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -1
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +6 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +7 -0
- data/lib/rubocop/cop/mixin/percent_array.rb +13 -7
- data/lib/rubocop/cop/mixin/require_library.rb +59 -0
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +18 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +31 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +19 -5
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +1 -7
- data/lib/rubocop/cop/style/double_negation.rb +12 -1
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +32 -7
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +8 -2
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +11 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +0 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +30 -5
- data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -1
- data/lib/rubocop/cop/style/missing_else.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +6 -8
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +83 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +32 -24
- data/lib/rubocop/cop/style/single_line_block_params.rb +3 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +25 -15
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +21 -0
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/word_array.rb +23 -5
- data/lib/rubocop/cop/util.rb +7 -2
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +15 -9
@@ -96,7 +96,7 @@ module RuboCop
|
|
96
96
|
MSG_MISSING = 'Use def with parentheses when there are parameters.'
|
97
97
|
|
98
98
|
def on_def(node)
|
99
|
-
return if node
|
99
|
+
return if forced_parentheses?(node)
|
100
100
|
|
101
101
|
args = node.arguments
|
102
102
|
|
@@ -129,6 +129,15 @@ module RuboCop
|
|
129
129
|
corrector.insert_after(arguments_range, ')')
|
130
130
|
end
|
131
131
|
|
132
|
+
def forced_parentheses?(node)
|
133
|
+
# Regardless of style, parentheses are necessary for:
|
134
|
+
# 1. Endless methods
|
135
|
+
# 2. Argument lists containing a `forward-arg` (`...`)
|
136
|
+
# Removing the parens would be a syntax error here.
|
137
|
+
|
138
|
+
node.endless? || node.arguments.any?(&:forward_arg_type?)
|
139
|
+
end
|
140
|
+
|
132
141
|
def require_parentheses?(args)
|
133
142
|
style == :require_parentheses ||
|
134
143
|
(style == :require_no_parentheses_except_multiline && args.multiline?)
|
@@ -5,6 +5,9 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for `if` expressions that do not have an `else` branch.
|
7
7
|
#
|
8
|
+
# NOTE: Pattern matching is allowed to have no `else` branch because unlike `if` and `case`,
|
9
|
+
# it raises `NoMatchingPatternError` if the pattern doesn't match and without having `else`.
|
10
|
+
#
|
8
11
|
# Supported styles are: if, case, both.
|
9
12
|
#
|
10
13
|
# @example EnforcedStyle: if
|
@@ -114,6 +117,10 @@ module RuboCop
|
|
114
117
|
check(node)
|
115
118
|
end
|
116
119
|
|
120
|
+
def on_case_match(node)
|
121
|
+
# do nothing.
|
122
|
+
end
|
123
|
+
|
117
124
|
private
|
118
125
|
|
119
126
|
def check(node)
|
@@ -61,13 +61,12 @@ module RuboCop
|
|
61
61
|
|
62
62
|
def on_casgn(node)
|
63
63
|
_scope, _const_name, value = *node
|
64
|
-
|
65
|
-
|
64
|
+
if value.nil? # This is only the case for `CONST += ...` or similarg66
|
65
|
+
parent = node.parent
|
66
|
+
return unless parent.or_asgn_type? # We only care about `CONST ||= ...`
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
return unless lhs&.casgn_type?
|
68
|
+
value = parent.children.last
|
69
|
+
end
|
71
70
|
|
72
71
|
on_assignment(value)
|
73
72
|
end
|
@@ -118,14 +117,13 @@ module RuboCop
|
|
118
117
|
end
|
119
118
|
|
120
119
|
def mutable_literal?(value)
|
121
|
-
return false if value.nil?
|
122
120
|
return false if frozen_regexp_or_range_literals?(value)
|
123
121
|
|
124
122
|
value.mutable_literal?
|
125
123
|
end
|
126
124
|
|
127
125
|
def immutable_literal?(node)
|
128
|
-
|
126
|
+
frozen_regexp_or_range_literals?(node) || node.immutable_literal?
|
129
127
|
end
|
130
128
|
|
131
129
|
def frozen_string_literal?(node)
|
@@ -84,6 +84,7 @@ module RuboCop
|
|
84
84
|
|
85
85
|
def on_kwbegin(node)
|
86
86
|
return if empty_begin?(node) ||
|
87
|
+
begin_block_has_multiline_statements?(node) ||
|
87
88
|
contain_rescue_or_ensure?(node) ||
|
88
89
|
valid_context_using_only_begin?(node)
|
89
90
|
|
@@ -102,6 +103,9 @@ module RuboCop
|
|
102
103
|
corrector.remove(offense_range)
|
103
104
|
end
|
104
105
|
|
106
|
+
if use_modifier_form_after_multiline_begin_block?(node)
|
107
|
+
correct_modifier_form_after_multiline_begin_block(corrector, node)
|
108
|
+
end
|
105
109
|
corrector.remove(node.loc.end)
|
106
110
|
end
|
107
111
|
end
|
@@ -127,10 +131,31 @@ module RuboCop
|
|
127
131
|
corrector.insert_before(node.parent, comments) unless comments.blank?
|
128
132
|
end
|
129
133
|
|
134
|
+
def use_modifier_form_after_multiline_begin_block?(node)
|
135
|
+
return unless (parent = node.parent)
|
136
|
+
|
137
|
+
node.multiline? && parent.if_type? && parent.modifier_form?
|
138
|
+
end
|
139
|
+
|
140
|
+
def correct_modifier_form_after_multiline_begin_block(corrector, node)
|
141
|
+
condition_range = condition_range(node.parent)
|
142
|
+
|
143
|
+
corrector.insert_after(node.children.first, " #{condition_range.source}")
|
144
|
+
corrector.remove(range_by_whole_lines(condition_range, include_final_newline: true))
|
145
|
+
end
|
146
|
+
|
147
|
+
def condition_range(node)
|
148
|
+
range_between(node.loc.keyword.begin_pos, node.condition.source_range.end_pos)
|
149
|
+
end
|
150
|
+
|
130
151
|
def empty_begin?(node)
|
131
152
|
node.children.empty?
|
132
153
|
end
|
133
154
|
|
155
|
+
def begin_block_has_multiline_statements?(node)
|
156
|
+
node.children.count >= 2
|
157
|
+
end
|
158
|
+
|
134
159
|
def contain_rescue_or_ensure?(node)
|
135
160
|
first_child = node.children.first
|
136
161
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for places where conditional branch makes redundant self-assignment.
|
7
|
+
#
|
8
|
+
# It only detects local variable because it may replace state of instance variable,
|
9
|
+
# class variable, and global variable that have state across methods with `nil`.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
# foo = condition ? bar : foo
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# foo = bar if condition
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
# foo = condition ? foo : bar
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# foo = bar unless condition
|
24
|
+
#
|
25
|
+
class RedundantSelfAssignmentBranch < Base
|
26
|
+
include RangeHelp
|
27
|
+
extend AutoCorrector
|
28
|
+
|
29
|
+
MSG = 'Remove the self-assignment branch.'
|
30
|
+
|
31
|
+
# @!method bad_method?(node)
|
32
|
+
def_node_matcher :bad_method?, <<~PATTERN
|
33
|
+
(send nil? :bad_method ...)
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def on_lvasgn(node)
|
37
|
+
variable, expression = *node
|
38
|
+
return unless use_if_and_else_branch?(expression)
|
39
|
+
|
40
|
+
if_branch = expression.if_branch
|
41
|
+
else_branch = expression.else_branch
|
42
|
+
return if inconvertible_to_modifier?(if_branch, else_branch)
|
43
|
+
|
44
|
+
if self_assign?(variable, if_branch)
|
45
|
+
register_offense(expression, if_branch, else_branch, 'unless')
|
46
|
+
elsif self_assign?(variable, else_branch)
|
47
|
+
register_offense(expression, else_branch, if_branch, 'if')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def use_if_and_else_branch?(expression)
|
54
|
+
return false unless expression&.if_type?
|
55
|
+
|
56
|
+
!expression.ternary? || !expression.else?
|
57
|
+
end
|
58
|
+
|
59
|
+
def inconvertible_to_modifier?(if_branch, else_branch)
|
60
|
+
multiple_statements?(if_branch) || multiple_statements?(else_branch) ||
|
61
|
+
else_branch.respond_to?(:elsif?) && else_branch.elsif?
|
62
|
+
end
|
63
|
+
|
64
|
+
def multiple_statements?(branch)
|
65
|
+
branch && branch.children.compact.count > 1
|
66
|
+
end
|
67
|
+
|
68
|
+
def self_assign?(variable, branch)
|
69
|
+
variable.to_s == branch&.source
|
70
|
+
end
|
71
|
+
|
72
|
+
def register_offense(if_node, offense_branch, opposite_branch, keyword)
|
73
|
+
add_offense(offense_branch) do |corrector|
|
74
|
+
assignment_value = opposite_branch ? opposite_branch.source : 'nil'
|
75
|
+
replacement = "#{assignment_value} #{keyword} #{if_node.condition.source}"
|
76
|
+
|
77
|
+
corrector.replace(if_node, replacement)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -60,8 +60,8 @@ module RuboCop
|
|
60
60
|
# @!method redundant_sort?(node)
|
61
61
|
def_node_matcher :redundant_sort?, <<~MATCHER
|
62
62
|
{
|
63
|
-
(send $(send _ $:sort
|
64
|
-
(send $(send _ $:sort
|
63
|
+
(send $(send _ $:sort) ${:last :first})
|
64
|
+
(send $(send _ $:sort) ${:[] :at :slice} {(int 0) (int -1)})
|
65
65
|
|
66
66
|
(send $(send _ $:sort_by _) ${:last :first})
|
67
67
|
(send $(send _ $:sort_by _) ${:[] :at :slice} {(int 0) (int -1)})
|
@@ -32,38 +32,29 @@ module RuboCop
|
|
32
32
|
|
33
33
|
MSG = 'Do not use semicolons to terminate expressions.'
|
34
34
|
|
35
|
+
def self.autocorrect_incompatible_with
|
36
|
+
[Style::SingleLineMethods]
|
37
|
+
end
|
38
|
+
|
35
39
|
def on_new_investigation
|
36
40
|
return if processed_source.blank?
|
37
41
|
|
38
|
-
@processed_source = processed_source
|
39
|
-
|
40
42
|
check_for_line_terminator_or_opener
|
41
43
|
end
|
42
44
|
|
43
|
-
def on_begin(node)
|
45
|
+
def on_begin(node)
|
44
46
|
return if cop_config['AllowAsExpressionSeparator']
|
45
47
|
|
46
48
|
exprs = node.children
|
47
49
|
|
48
50
|
return if exprs.size < 2
|
49
51
|
|
50
|
-
|
51
|
-
exprs_lines = exprs.map(&:first_line)
|
52
|
-
lines = exprs_lines.group_by(&:itself)
|
53
|
-
|
54
|
-
lines.each do |line, expr_on_line|
|
52
|
+
expressions_per_line(exprs).each do |line, expr_on_line|
|
55
53
|
# Every line with more than one expression on it is a
|
56
54
|
# potential offense
|
57
55
|
next unless expr_on_line.size > 1
|
58
56
|
|
59
|
-
|
60
|
-
# if the first semicolon on the line is a separator of
|
61
|
-
# expressions. It's just a guess.
|
62
|
-
column = @processed_source[line - 1].index(';')
|
63
|
-
|
64
|
-
next unless column
|
65
|
-
|
66
|
-
convention_on(line, column, false)
|
57
|
+
find_semicolon_positions(line) { |pos| register_semicolon(line, pos, true) }
|
67
58
|
end
|
68
59
|
end
|
69
60
|
|
@@ -71,9 +62,9 @@ module RuboCop
|
|
71
62
|
|
72
63
|
def check_for_line_terminator_or_opener
|
73
64
|
# Make the obvious check first
|
74
|
-
return unless
|
65
|
+
return unless processed_source.raw_source.include?(';')
|
75
66
|
|
76
|
-
each_semicolon { |line, column|
|
67
|
+
each_semicolon { |line, column| register_semicolon(line, column, false) }
|
77
68
|
end
|
78
69
|
|
79
70
|
def each_semicolon
|
@@ -84,15 +75,32 @@ module RuboCop
|
|
84
75
|
end
|
85
76
|
|
86
77
|
def tokens_for_lines
|
87
|
-
|
78
|
+
processed_source.tokens.group_by(&:line)
|
88
79
|
end
|
89
80
|
|
90
|
-
def
|
91
|
-
range = source_range(
|
92
|
-
|
93
|
-
# on the same line
|
81
|
+
def register_semicolon(line, column, after_expression)
|
82
|
+
range = source_range(processed_source.buffer, line, column)
|
83
|
+
|
94
84
|
add_offense(range) do |corrector|
|
95
|
-
|
85
|
+
if after_expression
|
86
|
+
corrector.replace(range, "\n")
|
87
|
+
else
|
88
|
+
corrector.remove(range)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def expressions_per_line(exprs)
|
94
|
+
# create a map matching lines to the number of expressions on them
|
95
|
+
exprs_lines = exprs.map(&:first_line)
|
96
|
+
exprs_lines.group_by(&:itself)
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_semicolon_positions(line)
|
100
|
+
# Scan for all the semicolons on the line
|
101
|
+
semicolons = processed_source[line - 1].enum_for(:scan, ';')
|
102
|
+
semicolons.each do
|
103
|
+
yield Regexp.last_match.begin(0)
|
96
104
|
end
|
97
105
|
end
|
98
106
|
end
|
@@ -109,7 +109,9 @@ module RuboCop
|
|
109
109
|
# we remove any leading underscores before comparing.
|
110
110
|
actual_args_no_underscores = actual_args.map { |arg| arg.to_s.sub(/^_+/, '') }
|
111
111
|
|
112
|
-
|
112
|
+
# Allow the arguments if the names match but not all are given
|
113
|
+
expected_args = target_args(method_name).first(actual_args_no_underscores.size)
|
114
|
+
actual_args_no_underscores == expected_args
|
113
115
|
end
|
114
116
|
end
|
115
117
|
end
|
@@ -36,6 +36,7 @@ module RuboCop
|
|
36
36
|
extend AutoCorrector
|
37
37
|
|
38
38
|
MSG = 'Avoid single-line method definitions.'
|
39
|
+
NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES = %i[return break next].freeze
|
39
40
|
|
40
41
|
def on_def(node)
|
41
42
|
return unless node.single_line?
|
@@ -62,29 +63,24 @@ module RuboCop
|
|
62
63
|
|
63
64
|
def correct_to_endless?(body_node)
|
64
65
|
return false if target_ruby_version < 3.0
|
65
|
-
|
66
|
-
endless_method_config = config.for_cop('Style/EndlessMethod')
|
67
|
-
|
68
|
-
return false unless endless_method_config['Enabled']
|
69
|
-
return false if endless_method_config['EnforcedStyle'] == 'disallow'
|
66
|
+
return false if disallow_endless_method_style?
|
70
67
|
return false unless body_node
|
71
|
-
return false if body_node.parent.assignment_method?
|
68
|
+
return false if body_node.parent.assignment_method? ||
|
69
|
+
NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
|
72
70
|
|
73
71
|
!(body_node.begin_type? || body_node.kwbegin_type?)
|
74
72
|
end
|
75
73
|
|
76
74
|
def correct_to_multiline(corrector, node)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
if (body = node.body) && body.begin_type? && body.parenthesized_call?
|
76
|
+
break_line_before(corrector, node, body)
|
77
|
+
else
|
78
|
+
each_part(body) do |part|
|
79
|
+
break_line_before(corrector, node, part)
|
80
|
+
end
|
82
81
|
end
|
83
82
|
|
84
|
-
|
85
|
-
range: node.loc.end, node: node, corrector: corrector,
|
86
|
-
indent_steps: 0, configured_width: configured_indentation_width
|
87
|
-
)
|
83
|
+
break_line_before(corrector, node, node.loc.end, indent_steps: 0)
|
88
84
|
|
89
85
|
move_comment(node, corrector)
|
90
86
|
end
|
@@ -98,6 +94,13 @@ module RuboCop
|
|
98
94
|
corrector.replace(node, replacement)
|
99
95
|
end
|
100
96
|
|
97
|
+
def break_line_before(corrector, node, range, indent_steps: 1)
|
98
|
+
LineBreakCorrector.break_line_before(
|
99
|
+
range: range, node: node, corrector: corrector,
|
100
|
+
configured_width: configured_indentation_width, indent_steps: indent_steps
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
101
104
|
def each_part(body)
|
102
105
|
return unless body
|
103
106
|
|
@@ -129,6 +132,13 @@ module RuboCop
|
|
129
132
|
def require_parentheses?(method_body)
|
130
133
|
method_body.send_type? && !method_body.arguments.empty? && !method_body.comparison_method?
|
131
134
|
end
|
135
|
+
|
136
|
+
def disallow_endless_method_style?
|
137
|
+
endless_method_config = config.for_cop('Style/EndlessMethod')
|
138
|
+
return false unless endless_method_config['Enabled']
|
139
|
+
|
140
|
+
endless_method_config['EnforcedStyle'] == 'disallow'
|
141
|
+
end
|
132
142
|
end
|
133
143
|
end
|
134
144
|
end
|
@@ -38,6 +38,10 @@ module RuboCop
|
|
38
38
|
|
39
39
|
MSG = 'Consider merging nested conditions into outer `%<conditional_type>s` conditions.'
|
40
40
|
|
41
|
+
def self.autocorrect_incompatible_with
|
42
|
+
[Style::NegatedIf, Style::NegatedUnless]
|
43
|
+
end
|
44
|
+
|
41
45
|
def on_if(node)
|
42
46
|
return if node.ternary? || node.else? || node.elsif?
|
43
47
|
|
@@ -5,9 +5,14 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
#
|
7
7
|
# This cop looks for uses of Perl-style global variables.
|
8
|
+
# Correcting to global variables in the 'English' library
|
9
|
+
# will add a require statement to the top of the file if
|
10
|
+
# enabled by RequireEnglish config.
|
8
11
|
#
|
9
12
|
# @example EnforcedStyle: use_english_names (default)
|
10
13
|
# # good
|
14
|
+
# require 'English' # or this could be in another file.
|
15
|
+
#
|
11
16
|
# puts $LOAD_PATH
|
12
17
|
# puts $LOADED_FEATURES
|
13
18
|
# puts $PROGRAM_NAME
|
@@ -50,6 +55,8 @@ module RuboCop
|
|
50
55
|
#
|
51
56
|
class SpecialGlobalVars < Base
|
52
57
|
include ConfigurableEnforcedStyle
|
58
|
+
include RangeHelp
|
59
|
+
include RequireLibrary
|
53
60
|
extend AutoCorrector
|
54
61
|
|
55
62
|
MSG_BOTH = 'Prefer `%<prefer>s` from the stdlib \'English\' ' \
|
@@ -90,6 +97,8 @@ module RuboCop
|
|
90
97
|
# Anything *not* in this set is provided by the English library.
|
91
98
|
NON_ENGLISH_VARS = Set.new(%i[$LOAD_PATH $LOADED_FEATURES $PROGRAM_NAME ARGV]).freeze
|
92
99
|
|
100
|
+
LIBRARY_NAME = 'English'
|
101
|
+
|
93
102
|
def on_gvar(node)
|
94
103
|
global_var, = *node
|
95
104
|
|
@@ -117,6 +126,8 @@ module RuboCop
|
|
117
126
|
def autocorrect(corrector, node, global_var)
|
118
127
|
node = node.parent while node.parent&.begin_type? && node.parent.children.one?
|
119
128
|
|
129
|
+
ensure_required(corrector, node, LIBRARY_NAME) if should_require_english?(global_var)
|
130
|
+
|
120
131
|
corrector.replace(node, replacement(node, global_var))
|
121
132
|
end
|
122
133
|
|
@@ -172,6 +183,16 @@ module RuboCop
|
|
172
183
|
|
173
184
|
"{#{preferred_name}}"
|
174
185
|
end
|
186
|
+
|
187
|
+
def add_require_english?
|
188
|
+
cop_config['RequireEnglish']
|
189
|
+
end
|
190
|
+
|
191
|
+
def should_require_english?(global_var)
|
192
|
+
style == :use_english_names &&
|
193
|
+
add_require_english? &&
|
194
|
+
!NON_ENGLISH_VARS.include?(preferred_names(global_var).first)
|
195
|
+
end
|
175
196
|
end
|
176
197
|
end
|
177
198
|
end
|