rubocop 1.0.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -16
- data/config/default.yml +141 -14
- data/exe/rubocop +1 -1
- data/lib/rubocop.rb +16 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config_loader.rb +7 -6
- 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 +10 -10
- data/lib/rubocop/cop/corrector.rb +3 -1
- 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 +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -4
- 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_lines_around_access_modifier.rb +1 -0
- 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/line_length.rb +8 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
- data/lib/rubocop/cop/layout/space_inside_parens.rb +35 -13
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +23 -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/literal_in_interpolation.rb +38 -6
- data/lib/rubocop/cop/lint/loop.rb +4 -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/to_enum_arguments.rb +95 -0
- 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_method_definition.rb +2 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -4
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +11 -1
- 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 +98 -8
- data/lib/rubocop/cop/offense.rb +3 -3
- data/lib/rubocop/cop/style/and_or.rb +1 -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/collection_compact.rb +91 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +162 -0
- data/lib/rubocop/cop/style/double_negation.rb +6 -1
- 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 +7 -3
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -0
- 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 +104 -0
- data/lib/rubocop/cop/style/nil_lambda.rb +52 -0
- data/lib/rubocop/cop/style/raise_args.rb +21 -6
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +3 -0
- data/lib/rubocop/cop/style/static_class.rb +97 -0
- data/lib/rubocop/cop/style/swap_values.rb +108 -0
- 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 +5 -1
- data/lib/rubocop/ext/regexp_node.rb +17 -9
- 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/magic_comment.rb +2 -2
- data/lib/rubocop/options.rb +2 -0
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/target_ruby.rb +57 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +21 -5
@@ -31,22 +31,12 @@ module RuboCop
|
|
31
31
|
MSG = 'Duplicate `when` condition detected.'
|
32
32
|
|
33
33
|
def on_case(case_node)
|
34
|
-
case_node.when_branches.each_with_object(
|
34
|
+
case_node.when_branches.each_with_object(Set.new) do |when_node, previous|
|
35
35
|
when_node.each_condition do |condition|
|
36
|
-
|
37
|
-
|
38
|
-
add_offense(condition)
|
36
|
+
add_offense(condition) unless previous.add?(condition)
|
39
37
|
end
|
40
|
-
|
41
|
-
previous.push(when_node.conditions)
|
42
38
|
end
|
43
39
|
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def repeated_condition?(previous, condition)
|
48
|
-
previous.any? { |c| c.include?(condition) }
|
49
|
-
end
|
50
40
|
end
|
51
41
|
end
|
52
42
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for duplicate elements in Regexp character classes.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# r = /[xyx]/
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
# r = /[0-9x0-9]/
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# r = /[xy]/
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# r = /[0-9x]/
|
21
|
+
class DuplicateRegexpCharacterClassElement < Base
|
22
|
+
include RangeHelp
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG_REPEATED_ELEMENT = 'Duplicate element inside regexp character class'
|
26
|
+
|
27
|
+
def on_regexp(node)
|
28
|
+
each_repeated_character_class_element_loc(node) do |loc|
|
29
|
+
add_offense(loc, message: MSG_REPEATED_ELEMENT) do |corrector|
|
30
|
+
corrector.remove(loc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def each_repeated_character_class_element_loc(node)
|
36
|
+
node.parsed_tree&.each_expression do |expr|
|
37
|
+
next if expr.type != :set || expr.token == :intersection
|
38
|
+
|
39
|
+
seen = Set.new
|
40
|
+
|
41
|
+
expr.expressions.each do |child|
|
42
|
+
next if within_interpolation?(node, child)
|
43
|
+
|
44
|
+
child_source = child.to_s
|
45
|
+
|
46
|
+
yield child.expression if seen.include?(child_source)
|
47
|
+
|
48
|
+
seen << child_source
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Since we blank interpolations with a space for every char of the interpolation, we would
|
56
|
+
# mark every space (except the first) as duplicate if we do not skip regexp_parser nodes
|
57
|
+
# that are within an interpolation.
|
58
|
+
def within_interpolation?(node, child)
|
59
|
+
parse_tree_child_loc = child.expression
|
60
|
+
|
61
|
+
interpolation_locs(node).any? { |il| il.overlaps?(parse_tree_child_loc) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def interpolation_locs(node)
|
65
|
+
@interpolation_locs ||= {}
|
66
|
+
|
67
|
+
# Cache by loc, not by regexp content, as content can be repeated in multiple patterns
|
68
|
+
key = node.loc
|
69
|
+
|
70
|
+
@interpolation_locs[key] ||= node.children.select(&:begin_type?).map do |interpolation|
|
71
|
+
interpolation.loc.expression
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -3,10 +3,14 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop checks for odd else block layout - like
|
7
|
-
# having an expression on the same line as the else keyword,
|
6
|
+
# This cop checks for odd `else` block layout - like
|
7
|
+
# having an expression on the same line as the `else` keyword,
|
8
8
|
# which is usually a mistake.
|
9
9
|
#
|
10
|
+
# Its auto-correction tweaks layout to keep the syntax. So, this auto-correction
|
11
|
+
# is compatible correction for bad case syntax, but if your code makes a mistake
|
12
|
+
# with `elsif` and `else`, you will have to correct it manually.
|
13
|
+
#
|
10
14
|
# @example
|
11
15
|
#
|
12
16
|
# # bad
|
@@ -21,13 +25,25 @@ module RuboCop
|
|
21
25
|
#
|
22
26
|
# # good
|
23
27
|
#
|
28
|
+
# # This code is compatible with the bad case. It will be auto-corrected like this.
|
24
29
|
# if something
|
25
30
|
# # ...
|
26
31
|
# else
|
27
32
|
# do_this
|
28
33
|
# do_that
|
29
34
|
# end
|
35
|
+
#
|
36
|
+
# # This code is incompatible with the bad case.
|
37
|
+
# # If `do_this` is a condition, `elsif` should be used instead of `else`.
|
38
|
+
# if something
|
39
|
+
# # ...
|
40
|
+
# elsif do_this
|
41
|
+
# do_that
|
42
|
+
# end
|
30
43
|
class ElseLayout < Base
|
44
|
+
include RangeHelp
|
45
|
+
extend AutoCorrector
|
46
|
+
|
31
47
|
MSG = 'Odd `else` layout detected. Did you mean to use `elsif`?'
|
32
48
|
|
33
49
|
def on_if(node)
|
@@ -58,7 +74,17 @@ module RuboCop
|
|
58
74
|
return unless first_else
|
59
75
|
return unless first_else.source_range.line == node.loc.else.line
|
60
76
|
|
61
|
-
add_offense(first_else)
|
77
|
+
add_offense(first_else) do |corrector|
|
78
|
+
autocorrect(corrector, node, first_else)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def autocorrect(corrector, node, first_else)
|
83
|
+
corrector.insert_after(node.loc.else, "\n")
|
84
|
+
|
85
|
+
blank_range = range_between(node.loc.else.end_pos, first_else.loc.expression.begin_pos)
|
86
|
+
indentation = indent(node.else_branch.children[1])
|
87
|
+
corrector.replace(blank_range, indentation)
|
62
88
|
end
|
63
89
|
end
|
64
90
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for blocks without a body.
|
7
|
+
# Such empty blocks are typically an oversight or we should provide a comment
|
8
|
+
# be clearer what we're aiming for.
|
9
|
+
#
|
10
|
+
# Empty lambdas are ignored by default.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# items.each { |item| }
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# items.each { |item| puts item }
|
18
|
+
#
|
19
|
+
# @example AllowComments: true (default)
|
20
|
+
# # good
|
21
|
+
# items.each do |item|
|
22
|
+
# # TODO: implement later (inner comment)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# items.each { |item| } # TODO: implement later (inline comment)
|
26
|
+
#
|
27
|
+
# @example AllowComments: false
|
28
|
+
# # bad
|
29
|
+
# items.each do |item|
|
30
|
+
# # TODO: implement later (inner comment)
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# items.each { |item| } # TODO: implement later (inline comment)
|
34
|
+
#
|
35
|
+
# @example AllowEmptyLambdas: true (default)
|
36
|
+
# # good
|
37
|
+
# allow(subject).to receive(:callable).and_return(-> {})
|
38
|
+
#
|
39
|
+
# placeholder = lambda do
|
40
|
+
# end
|
41
|
+
# (callable || placeholder).call
|
42
|
+
#
|
43
|
+
# @example AllowEmptyLambdas: false
|
44
|
+
# # bad
|
45
|
+
# allow(subject).to receive(:callable).and_return(-> {})
|
46
|
+
#
|
47
|
+
# placeholder = lambda do
|
48
|
+
# end
|
49
|
+
# (callable || placeholder).call
|
50
|
+
#
|
51
|
+
class EmptyBlock < Base
|
52
|
+
MSG = 'Empty block detected.'
|
53
|
+
|
54
|
+
def on_block(node)
|
55
|
+
return if node.body
|
56
|
+
return if allow_empty_lambdas? && node.lambda?
|
57
|
+
return if cop_config['AllowComments'] && allow_comment?(node)
|
58
|
+
|
59
|
+
add_offense(node)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def allow_comment?(node)
|
65
|
+
return false unless processed_source.contains_comment?(node.source_range)
|
66
|
+
|
67
|
+
line_comment = processed_source.comment_at_line(node.source_range.line)
|
68
|
+
!line_comment || !comment_disables_cop?(line_comment.loc.expression.source)
|
69
|
+
end
|
70
|
+
|
71
|
+
def allow_empty_lambdas?
|
72
|
+
cop_config['AllowEmptyLambdas']
|
73
|
+
end
|
74
|
+
|
75
|
+
def comment_disables_cop?(comment)
|
76
|
+
regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
|
77
|
+
Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for classes and metaclasses without a body.
|
7
|
+
# Such empty classes and metaclasses are typically an oversight or we should provide a comment
|
8
|
+
# to be clearer what we're aiming for.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# class Foo
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# class Bar
|
16
|
+
# class << self
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# class << obj
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# class Foo
|
25
|
+
# def do_something
|
26
|
+
# # ... code
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# class Bar
|
31
|
+
# class << self
|
32
|
+
# attr_reader :bar
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# class << obj
|
37
|
+
# attr_reader :bar
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# @example AllowComments: false (default)
|
41
|
+
# # bad
|
42
|
+
# class Foo
|
43
|
+
# # TODO: implement later
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# class Bar
|
47
|
+
# class << self
|
48
|
+
# # TODO: implement later
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# class << obj
|
53
|
+
# # TODO: implement later
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# @example AllowComments: true
|
57
|
+
# # good
|
58
|
+
# class Foo
|
59
|
+
# # TODO: implement later
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# class Bar
|
63
|
+
# class << self
|
64
|
+
# # TODO: implement later
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# class << obj
|
69
|
+
# # TODO: implement later
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
class EmptyClass < Base
|
73
|
+
CLASS_MSG = 'Empty class detected.'
|
74
|
+
METACLASS_MSG = 'Empty metaclass detected.'
|
75
|
+
|
76
|
+
def on_class(node)
|
77
|
+
add_offense(node, message: CLASS_MSG) unless body_or_allowed_comment_lines?(node) ||
|
78
|
+
node.parent_class
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_sclass(node)
|
82
|
+
add_offense(node, message: METACLASS_MSG) unless body_or_allowed_comment_lines?(node)
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def body_or_allowed_comment_lines?(node)
|
88
|
+
node.body || (cop_config['AllowComments'] && comment_lines?(node))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -3,8 +3,14 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop looks for uses of flip-flop operator
|
7
|
-
#
|
6
|
+
# This cop looks for uses of flip-flop operator
|
7
|
+
# based on the Ruby Style Guide.
|
8
|
+
#
|
9
|
+
# Here is the history of flip-flops in Ruby.
|
10
|
+
# flip-flop operator is deprecated in Ruby 2.6.0 and
|
11
|
+
# the deprecation has been reverted by Ruby 2.7.0 and
|
12
|
+
# backported to Ruby 2.6.
|
13
|
+
# See: https://bugs.ruby-lang.org/issues/5400
|
8
14
|
#
|
9
15
|
# @example
|
10
16
|
# # bad
|
@@ -27,21 +27,33 @@ module RuboCop
|
|
27
27
|
|
28
28
|
def on_interpolation(begin_node)
|
29
29
|
final_node = begin_node.children.last
|
30
|
-
return unless final_node
|
31
|
-
|
32
|
-
|
30
|
+
return unless offending?(final_node)
|
31
|
+
|
32
|
+
# %W and %I split the content into words before expansion
|
33
|
+
# treating each interpolation as a word component, so
|
34
|
+
# interpolation should not be removed if the expanded value
|
35
|
+
# contains a space character.
|
36
|
+
expanded_value = autocorrected_value(final_node)
|
37
|
+
return if in_array_percent_literal?(begin_node) &&
|
38
|
+
/\s/.match?(expanded_value)
|
33
39
|
|
34
40
|
add_offense(final_node) do |corrector|
|
35
41
|
return if final_node.dstr_type? # nested, fixed in next iteration
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
corrector.replace(final_node.parent, value)
|
43
|
+
corrector.replace(final_node.parent, expanded_value)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
47
|
private
|
44
48
|
|
49
|
+
def offending?(node)
|
50
|
+
node &&
|
51
|
+
!special_keyword?(node) &&
|
52
|
+
prints_as_self?(node) &&
|
53
|
+
# Special case for Layout/TrailingWhitespace
|
54
|
+
!(space_literal?(node) && ends_heredoc_line?(node))
|
55
|
+
end
|
56
|
+
|
45
57
|
def special_keyword?(node)
|
46
58
|
# handle strings like __FILE__
|
47
59
|
(node.str_type? && !node.loc.respond_to?(:begin)) ||
|
@@ -92,6 +104,26 @@ module RuboCop
|
|
92
104
|
(COMPOSITE.include?(node.type) &&
|
93
105
|
node.children.all? { |child| prints_as_self?(child) })
|
94
106
|
end
|
107
|
+
|
108
|
+
def space_literal?(node)
|
109
|
+
node.str_type? && node.value.blank?
|
110
|
+
end
|
111
|
+
|
112
|
+
def ends_heredoc_line?(node)
|
113
|
+
grandparent = node.parent.parent
|
114
|
+
return false unless grandparent&.dstr_type? && grandparent&.heredoc?
|
115
|
+
|
116
|
+
line = processed_source.lines[node.last_line - 1]
|
117
|
+
line.size == node.loc.last_column + 1
|
118
|
+
end
|
119
|
+
|
120
|
+
def in_array_percent_literal?(node)
|
121
|
+
parent = node.parent
|
122
|
+
return false unless parent.dstr_type? || parent.dsym_type?
|
123
|
+
|
124
|
+
grandparent = parent.parent
|
125
|
+
grandparent&.array_type? && grandparent&.percent_literal?
|
126
|
+
end
|
95
127
|
end
|
96
128
|
end
|
97
129
|
end
|
@@ -5,6 +5,10 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for uses of `begin...end while/until something`.
|
7
7
|
#
|
8
|
+
# The cop is marked as unsafe because behaviour can change in some cases, including
|
9
|
+
# if a local variable inside the loop body is accessed outside of it, or if the
|
10
|
+
# loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).
|
11
|
+
#
|
8
12
|
# @example
|
9
13
|
#
|
10
14
|
# # bad
|
@@ -76,10 +80,6 @@ module RuboCop
|
|
76
80
|
conditional_keyword = node.while_post_type? ? 'unless' : 'if'
|
77
81
|
"break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
|
78
82
|
end
|
79
|
-
|
80
|
-
def indent(node)
|
81
|
-
' ' * node.loc.column
|
82
|
-
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|