rubocop 0.34.2 → 0.35.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/CHANGELOG.md +86 -0
- data/README.md +103 -31
- data/config/default.yml +32 -2
- data/config/disabled.yml +24 -0
- data/config/enabled.yml +20 -2
- data/lib/rubocop.rb +13 -0
- data/lib/rubocop/ast_node.rb +48 -0
- data/lib/rubocop/cli.rb +9 -0
- data/lib/rubocop/config.rb +8 -6
- data/lib/rubocop/config_loader.rb +30 -8
- data/lib/rubocop/cop/commissioner.rb +1 -1
- data/lib/rubocop/cop/cop.rb +19 -6
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +33 -2
- data/lib/rubocop/cop/lint/debugger.rb +9 -56
- data/lib/rubocop/cop/lint/end_alignment.rb +29 -9
- data/lib/rubocop/cop/lint/eval.rb +6 -2
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +24 -6
- data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +10 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
- data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
- data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
- data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/performance/detect.rb +5 -1
- data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
- data/lib/rubocop/cop/performance/size.rb +1 -1
- data/lib/rubocop/cop/performance/string_replacement.rb +14 -8
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
- data/lib/rubocop/cop/style/align_hash.rb +1 -12
- data/lib/rubocop/cop/style/align_parameters.rb +19 -7
- data/lib/rubocop/cop/style/and_or.rb +42 -13
- data/lib/rubocop/cop/style/block_comments.rb +4 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +57 -18
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
- data/lib/rubocop/cop/style/command_literal.rb +2 -10
- data/lib/rubocop/cop/style/copyright.rb +5 -3
- data/lib/rubocop/cop/style/documentation.rb +9 -6
- data/lib/rubocop/cop/style/dot_position.rb +6 -0
- data/lib/rubocop/cop/style/double_negation.rb +4 -15
- data/lib/rubocop/cop/style/each_with_object.rb +17 -4
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -5
- data/lib/rubocop/cop/style/encoding.rb +10 -4
- data/lib/rubocop/cop/style/extra_spacing.rb +23 -13
- data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
- data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
- data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
- data/lib/rubocop/cop/style/for.rb +2 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +31 -0
- data/lib/rubocop/cop/style/indent_hash.rb +67 -37
- data/lib/rubocop/cop/style/indentation_width.rb +1 -1
- data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
- data/lib/rubocop/cop/style/method_call_parentheses.rb +8 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
- data/lib/rubocop/cop/style/multiline_operation_indentation.rb +8 -13
- data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
- data/lib/rubocop/cop/style/next.rb +18 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +57 -15
- data/lib/rubocop/cop/style/predicate_name.rb +7 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -5
- data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
- data/lib/rubocop/cop/style/trailing_comma.rb +9 -6
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
- data/lib/rubocop/cop/style/variable_name.rb +5 -0
- data/lib/rubocop/cop/style/word_array.rb +2 -1
- data/lib/rubocop/cop/team.rb +17 -4
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force/locatable.rb +1 -1
- data/lib/rubocop/formatter/base_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +22 -10
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/node_pattern.rb +390 -0
- data/lib/rubocop/options.rb +48 -36
- data/lib/rubocop/processed_source.rb +3 -1
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +60 -0
- data/lib/rubocop/result_cache.rb +4 -2
- data/lib/rubocop/runner.rb +33 -10
- data/lib/rubocop/token.rb +2 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/warning.rb +11 -0
- data/relnotes/v0.35.0.md +210 -0
- data/rubocop.gemspec +2 -2
- metadata +20 -6
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
# This cop looks for uses of block comments (=begin...=end).
|
7
7
|
class BlockComments < Cop
|
8
8
|
MSG = 'Do not use block comments.'
|
9
|
+
BEGIN_LENGTH = "=begin\n".length
|
10
|
+
END_LENGTH = "\n=end".length
|
9
11
|
|
10
12
|
def investigate(processed_source)
|
11
13
|
processed_source.comments.each do |comment|
|
@@ -33,9 +35,9 @@ module RuboCop
|
|
33
35
|
|
34
36
|
def parts(comment)
|
35
37
|
expr = comment.loc.expression
|
36
|
-
eq_begin = expr.resize(
|
38
|
+
eq_begin = expr.resize(BEGIN_LENGTH)
|
37
39
|
eq_end = Parser::Source::Range.new(expr.source_buffer,
|
38
|
-
expr.end_pos -
|
40
|
+
expr.end_pos - END_LENGTH,
|
39
41
|
expr.end_pos)
|
40
42
|
contents = Parser::Source::Range.new(expr.source_buffer,
|
41
43
|
eq_begin.end_pos,
|
@@ -25,32 +25,55 @@ module RuboCop
|
|
25
25
|
def on_block(node)
|
26
26
|
return if ignored_node?(node)
|
27
27
|
|
28
|
-
if proper_block_style?(node)
|
29
|
-
|
30
|
-
|
31
|
-
add_offense(node, :begin) { opposite_style_detected }
|
32
|
-
end
|
28
|
+
return if proper_block_style?(node)
|
29
|
+
|
30
|
+
add_offense(node, :begin)
|
33
31
|
end
|
34
32
|
|
35
33
|
private
|
36
34
|
|
37
|
-
def
|
35
|
+
def line_count_based_message(node)
|
36
|
+
block_length = Util.block_length(node)
|
37
|
+
|
38
|
+
if block_length > 0
|
39
|
+
'Avoid using `{...}` for multi-line blocks.'
|
40
|
+
else
|
41
|
+
'Prefer `{...}` over `do...end` for single-line blocks.'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def semantic_message(node)
|
38
46
|
block_begin = node.loc.begin.source
|
47
|
+
|
48
|
+
if block_begin == '{'
|
49
|
+
'Prefer `do...end` over `{...}` for procedural blocks.'
|
50
|
+
else
|
51
|
+
'Prefer `{...}` over `do...end` for functional blocks.'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def braces_for_chaining_message(node)
|
39
56
|
block_length = Util.block_length(node)
|
40
57
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
'Avoid using `{...}` for multi-line blocks.'
|
58
|
+
if block_length > 0
|
59
|
+
if return_value_chaining?(node)
|
60
|
+
'Prefer `{...}` over `do...end` for multi-line chained blocks.'
|
45
61
|
else
|
46
|
-
'Prefer `
|
62
|
+
'Prefer `do...end` for multi-line blocks without chaining.'
|
47
63
|
end
|
64
|
+
else
|
65
|
+
'Prefer `{...}` over `do...end` for single-line blocks.'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def message(node)
|
70
|
+
case style
|
71
|
+
when :line_count_based
|
72
|
+
line_count_based_message(node)
|
48
73
|
when :semantic
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
'Prefer `{...}` over `do...end` for functional blocks.'
|
53
|
-
end
|
74
|
+
semantic_message(node)
|
75
|
+
when :braces_for_chaining
|
76
|
+
braces_for_chaining_message(node)
|
54
77
|
end
|
55
78
|
end
|
56
79
|
|
@@ -90,6 +113,8 @@ module RuboCop
|
|
90
113
|
line_count_based_block_style?(node)
|
91
114
|
when :semantic
|
92
115
|
semantic_block_style?(node)
|
116
|
+
when :braces_for_chaining
|
117
|
+
braces_for_chaining_style?(node)
|
93
118
|
end
|
94
119
|
end
|
95
120
|
|
@@ -117,6 +142,21 @@ module RuboCop
|
|
117
142
|
end
|
118
143
|
end
|
119
144
|
|
145
|
+
def braces_for_chaining_style?(node)
|
146
|
+
block_length = Util.block_length(node)
|
147
|
+
block_begin = node.loc.begin.source
|
148
|
+
|
149
|
+
if block_length > 0
|
150
|
+
block_begin == (return_value_chaining?(node) ? '{' : 'do')
|
151
|
+
else
|
152
|
+
block_begin == '{'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def return_value_chaining?(node)
|
157
|
+
node.parent && node.parent.send_type? && node.parent.loc.dot
|
158
|
+
end
|
159
|
+
|
120
160
|
def extract_method_name_from_block(block)
|
121
161
|
node, _args, _body = *block
|
122
162
|
_receiver, method_name, *_args = *node
|
@@ -148,8 +188,7 @@ module RuboCop
|
|
148
188
|
if node.parent.begin_type?
|
149
189
|
return_value_used?(node.parent)
|
150
190
|
else
|
151
|
-
|
152
|
-
node.parent.send_type?
|
191
|
+
node.parent.assignment? || node.parent.send_type?
|
153
192
|
end
|
154
193
|
end
|
155
194
|
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
def check_backtick_literal(node)
|
48
48
|
return if style == :backticks && !contains_disallowed_backtick?(node)
|
49
49
|
return if style == :mixed &&
|
50
|
-
single_line?
|
50
|
+
node.single_line? &&
|
51
51
|
!contains_disallowed_backtick?(node)
|
52
52
|
|
53
53
|
add_offense(node, :expression, MSG_USE_PERCENT_X)
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
def check_percent_x_literal(node)
|
57
57
|
return if style == :backticks && contains_disallowed_backtick?(node)
|
58
58
|
return if style == :percent_x
|
59
|
-
return if style == :mixed &&
|
59
|
+
return if style == :mixed && node.multiline?
|
60
60
|
return if style == :mixed && contains_disallowed_backtick?(node)
|
61
61
|
|
62
62
|
add_offense(node, :expression, MSG_USE_BACKTICKS)
|
@@ -87,14 +87,6 @@ module RuboCop
|
|
87
87
|
node.loc.begin.source == '`'
|
88
88
|
end
|
89
89
|
|
90
|
-
def single_line?(node)
|
91
|
-
!multi_line?(node)
|
92
|
-
end
|
93
|
-
|
94
|
-
def multi_line?(node)
|
95
|
-
block_length(node) > 1
|
96
|
-
end
|
97
|
-
|
98
90
|
def preferred_delimiters
|
99
91
|
config.for_cop('Style/PercentLiteralDelimiters') \
|
100
92
|
['PreferredDelimiters']['%x'].split(//)
|
@@ -68,10 +68,12 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def autocorrect(token)
|
71
|
-
fail 'An AutocorrectNotice must be defined in ' \
|
71
|
+
fail Warning, 'An AutocorrectNotice must be defined in ' \
|
72
72
|
'your RuboCop config' if autocorrect_notice.empty?
|
73
|
-
|
74
|
-
|
73
|
+
regex = Regexp.new(notice)
|
74
|
+
fail Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
|
75
|
+
"match Notice /#{notice}/" unless autocorrect_notice =~ regex
|
76
|
+
|
75
77
|
lambda do |corrector|
|
76
78
|
if token.nil?
|
77
79
|
range = Parser::Source::Range.new('', 0, 0)
|
@@ -47,18 +47,21 @@ module RuboCop
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
# 'Const = Class.new' or 'Const = Module.new' are module definitions
|
51
|
+
mod_new = '(send (const nil {:Class :Module}) :new ...)'
|
52
|
+
def_node_matcher :module_definition?,
|
53
|
+
"{class
|
54
|
+
module
|
55
|
+
(casgn _ _ {#{mod_new} (block #{mod_new} ...)})}"
|
56
|
+
|
50
57
|
def namespace?(body_node)
|
51
58
|
return false unless body_node
|
52
59
|
|
53
60
|
case body_node.type
|
54
61
|
when :begin
|
55
|
-
body_node.children.all?
|
56
|
-
[:class, :module].include?(node.type)
|
57
|
-
end
|
58
|
-
when :class, :module
|
59
|
-
true
|
62
|
+
body_node.children.all? { |node| module_definition?(node) }
|
60
63
|
else
|
61
|
-
|
64
|
+
module_definition?(body_node)
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
@@ -46,6 +46,12 @@ module RuboCop
|
|
46
46
|
|
47
47
|
dot_line = node.loc.dot.line
|
48
48
|
|
49
|
+
# don't register an offense if there is a line comment between
|
50
|
+
# the dot and the selector
|
51
|
+
# otherwise, we might break the code while "correcting" it
|
52
|
+
# (even if there is just an extra blank line, treat it the same)
|
53
|
+
return true if (selector_line - dot_line) > 1
|
54
|
+
|
49
55
|
case style
|
50
56
|
when :leading then dot_line == selector_line
|
51
57
|
when :trailing then dot_line != selector_line
|
@@ -22,22 +22,11 @@ module RuboCop
|
|
22
22
|
class DoubleNegation < Cop
|
23
23
|
MSG = 'Avoid the use of double negation (`!!`).'
|
24
24
|
|
25
|
-
|
26
|
-
return unless not_node?(node)
|
27
|
-
|
28
|
-
receiver, _method_name, *_args = *node
|
29
|
-
|
30
|
-
add_offense(node, :selector) if not_node?(receiver)
|
31
|
-
end
|
25
|
+
def_node_matcher :double_negative?, '(send (send _ :!) :!)'
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
_receiver, method_name, *args = *node
|
37
|
-
|
38
|
-
# ! does not take any arguments
|
39
|
-
args.empty? && method_name == :! &&
|
40
|
-
node.loc.selector.is?('!')
|
27
|
+
def on_send(node)
|
28
|
+
return unless double_negative?(node) && node.loc.selector.is?('!')
|
29
|
+
add_offense(node, :selector)
|
41
30
|
end
|
42
31
|
end
|
43
32
|
end
|
@@ -7,6 +7,9 @@ module RuboCop
|
|
7
7
|
# returned at the end and so could be replace by each_with_object without
|
8
8
|
# the need to return the object at the end.
|
9
9
|
#
|
10
|
+
# However, we can't replace with each_with_object if the accumulator
|
11
|
+
# parameter is assigned to within the block.
|
12
|
+
#
|
10
13
|
# @example
|
11
14
|
# # bad
|
12
15
|
# [1, 2].inject({}) { |a, e| a[e] = e; a }
|
@@ -23,16 +26,26 @@ module RuboCop
|
|
23
26
|
# filter out super and zsuper nodes
|
24
27
|
return unless method.type == :send
|
25
28
|
|
26
|
-
_, method_name,
|
29
|
+
_, method_name, method_arg = *method
|
27
30
|
|
28
31
|
return unless METHODS.include? method_name
|
29
|
-
return if
|
32
|
+
return if method_arg && BASIC_LITERALS.include?(method_arg.type)
|
30
33
|
|
31
34
|
return_value = return_value(body)
|
32
35
|
return unless return_value
|
33
36
|
|
34
37
|
return unless first_argument_returned?(args, return_value)
|
35
38
|
|
39
|
+
# if the accumulator parameter is assigned to in the block,
|
40
|
+
# then we can't convert to each_with_object
|
41
|
+
first_arg, = *args
|
42
|
+
accumulator_var, = *first_arg
|
43
|
+
return if body.each_descendant.any? do |n|
|
44
|
+
next unless n.assignment?
|
45
|
+
lhs, _rhs = *n
|
46
|
+
lhs.equal?(accumulator_var)
|
47
|
+
end
|
48
|
+
|
36
49
|
add_offense(method, :selector, format(MSG, method_name))
|
37
50
|
end
|
38
51
|
|
@@ -47,8 +60,8 @@ module RuboCop
|
|
47
60
|
|
48
61
|
def first_argument_returned?(args, return_value)
|
49
62
|
first_arg, = *args
|
50
|
-
accumulator_var = *first_arg
|
51
|
-
return_var = *return_value
|
63
|
+
accumulator_var, = *first_arg
|
64
|
+
return_var, = *return_value
|
52
65
|
|
53
66
|
accumulator_var == return_var
|
54
67
|
end
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
|
17
17
|
return unless nodes.all?(&method(:def_node?))
|
18
18
|
return if blank_lines_between?(*nodes)
|
19
|
-
return if nodes.all?(
|
19
|
+
return if nodes.all?(&:single_line?) &&
|
20
20
|
cop_config['AllowAdjacentOneLineDefs']
|
21
21
|
|
22
22
|
add_offense(node, :keyword)
|
@@ -45,10 +45,6 @@ module RuboCop
|
|
45
45
|
processed_source.lines[line_range]
|
46
46
|
end
|
47
47
|
|
48
|
-
def single_line_def?(node)
|
49
|
-
def_start(node) == def_end(node)
|
50
|
-
end
|
51
|
-
|
52
48
|
def def_start(node)
|
53
49
|
node.loc.keyword.line
|
54
50
|
end
|
@@ -16,7 +16,9 @@ module RuboCop
|
|
16
16
|
|
17
17
|
MSG_MISSING = 'Missing utf-8 encoding comment.'
|
18
18
|
MSG_UNNECESSARY = 'Unnecessary utf-8 encoding comment.'
|
19
|
-
ENCODING_PATTERN = /#.*coding\s?[:=]\s?(?:UTF|utf)-8
|
19
|
+
ENCODING_PATTERN = /#.*coding\s?[:=]\s?(?:UTF|utf)-8/.freeze
|
20
|
+
AUTO_CORRECT_ENCODING_COMMENT = 'AutoCorrectEncodingComment'.freeze
|
21
|
+
SHEBANG = '#!'.freeze
|
20
22
|
|
21
23
|
def investigate(processed_source)
|
22
24
|
return if processed_source.buffer.source.empty?
|
@@ -31,10 +33,14 @@ module RuboCop
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def autocorrect(node)
|
34
|
-
encoding = cop_config[
|
36
|
+
encoding = cop_config[AUTO_CORRECT_ENCODING_COMMENT]
|
35
37
|
if encoding && encoding =~ ENCODING_PATTERN
|
36
38
|
lambda do |corrector|
|
37
|
-
|
39
|
+
if encoding_line_number(processed_source) == 0
|
40
|
+
corrector.insert_before(node.pos, "#{encoding}\n")
|
41
|
+
else
|
42
|
+
corrector.insert_after(node.pos, "\n#{encoding}")
|
43
|
+
end
|
38
44
|
end
|
39
45
|
else
|
40
46
|
fail "#{encoding} does not match #{ENCODING_PATTERN}"
|
@@ -58,7 +64,7 @@ module RuboCop
|
|
58
64
|
|
59
65
|
def encoding_line_number(processed_source)
|
60
66
|
line_number = 0
|
61
|
-
line_number += 1 if processed_source[line_number].start_with?(
|
67
|
+
line_number += 1 if processed_source[line_number].start_with?(SHEBANG)
|
62
68
|
line_number
|
63
69
|
end
|
64
70
|
end
|
@@ -22,7 +22,6 @@ module RuboCop
|
|
22
22
|
|
23
23
|
def investigate(processed_source)
|
24
24
|
ast = processed_source.ast
|
25
|
-
ignored_ranges = ast ? ignored_ranges(ast) : []
|
26
25
|
|
27
26
|
processed_source.tokens.each_cons(2) do |t1, t2|
|
28
27
|
next if t2.type == :tNL
|
@@ -30,10 +29,15 @@ module RuboCop
|
|
30
29
|
next if t2.pos.begin_pos - 1 <= t1.pos.end_pos
|
31
30
|
next if allow_for_alignment? && aligned_with_something?(t2)
|
32
31
|
start_pos = t1.pos.end_pos
|
32
|
+
next if ignored_ranges(ast).find { |r| r.include?(start_pos) }
|
33
|
+
|
33
34
|
end_pos = t2.pos.begin_pos - 1
|
34
35
|
range = Parser::Source::Range.new(processed_source.buffer,
|
35
36
|
start_pos, end_pos)
|
36
|
-
|
37
|
+
# Unary + doesn't appear as a token and needs special handling.
|
38
|
+
next if unary_plus_non_offense?(range)
|
39
|
+
|
40
|
+
add_offense(range, range, MSG)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
@@ -43,19 +47,25 @@ module RuboCop
|
|
43
47
|
|
44
48
|
private
|
45
49
|
|
50
|
+
def unary_plus_non_offense?(range)
|
51
|
+
range.resize(range.size + 1).source =~ /^ ?\+$/
|
52
|
+
end
|
53
|
+
|
46
54
|
# Returns an array of ranges that should not be reported. It's the
|
47
|
-
# extra spaces between the
|
48
|
-
#
|
55
|
+
# extra spaces between the keys and values in a hash, since those are
|
56
|
+
# handled by the Style/AlignHash cop.
|
49
57
|
def ignored_ranges(ast)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ranges
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
return [] unless ast
|
59
|
+
|
60
|
+
@ignored_ranges ||= begin
|
61
|
+
ranges = []
|
62
|
+
on_node(:pair, ast) do |pair|
|
63
|
+
key, value = *pair
|
64
|
+
r = key.loc.expression.end_pos...value.loc.expression.begin_pos
|
65
|
+
ranges << r
|
66
|
+
end
|
67
|
+
ranges
|
57
68
|
end
|
58
|
-
ranges
|
59
69
|
end
|
60
70
|
|
61
71
|
def allow_for_alignment?
|
@@ -122,7 +132,7 @@ module RuboCop
|
|
122
132
|
whole_line_comments = processed_source.comments.select do |c|
|
123
133
|
begins_its_line?(c.loc.expression)
|
124
134
|
end
|
125
|
-
whole_line_comments.map
|
135
|
+
whole_line_comments.map { |c| c.loc.line }
|
126
136
|
end
|
127
137
|
end
|
128
138
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for a line break before the first element in a
|
7
|
+
# multi-line array.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# [ :a,
|
13
|
+
# :b]
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# [
|
17
|
+
# :a,
|
18
|
+
# :b]
|
19
|
+
#
|
20
|
+
class FirstArrayElementLineBreak < Cop
|
21
|
+
include FirstElementLineBreak
|
22
|
+
|
23
|
+
MSG = 'Add a line break before the first element of a ' \
|
24
|
+
'multi-line array.'
|
25
|
+
|
26
|
+
def on_array(node)
|
27
|
+
return if !node.loc.begin && !assignment_on_same_line?(node)
|
28
|
+
|
29
|
+
check_children_line_break(node, node.children)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def assignment_on_same_line?(node)
|
35
|
+
source = node.loc.expression.source_line[0...node.loc.column]
|
36
|
+
source =~ /\s*\=\s*$/
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|