rubocop 0.16.0 → 0.17.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/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +44 -0
- data/CONTRIBUTING.md +40 -8
- data/Gemfile +6 -0
- data/README.md +65 -20
- data/Rakefile +0 -1
- data/config/default.yml +15 -3
- data/config/enabled.yml +143 -109
- data/lib/rubocop.rb +45 -26
- data/lib/rubocop/cli.rb +26 -27
- data/lib/rubocop/config.rb +0 -1
- data/lib/rubocop/config_loader.rb +16 -23
- data/lib/rubocop/cop/commissioner.rb +2 -7
- data/lib/rubocop/cop/cop.rb +24 -51
- data/lib/rubocop/cop/ignored_node.rb +31 -0
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +50 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +36 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -11
- data/lib/rubocop/cop/lint/block_alignment.rb +6 -20
- data/lib/rubocop/cop/lint/condition_position.rb +52 -0
- data/lib/rubocop/cop/lint/else_layout.rb +57 -0
- data/lib/rubocop/cop/lint/end_alignment.rb +33 -8
- data/lib/rubocop/cop/lint/invalid_character_literal.rb +37 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -4
- data/lib/rubocop/cop/lint/syntax.rb +6 -12
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +25 -0
- data/lib/rubocop/cop/mixin/array_syntax.rb +20 -0
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +76 -0
- data/lib/rubocop/cop/mixin/check_assignment.rb +26 -0
- data/lib/rubocop/cop/{check_methods.rb → mixin/check_methods.rb} +0 -0
- data/lib/rubocop/cop/mixin/code_length.rb +33 -0
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +53 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +19 -0
- data/lib/rubocop/cop/mixin/configurable_naming.rb +45 -0
- data/lib/rubocop/cop/{style → mixin}/if_node.rb +0 -0
- data/lib/rubocop/cop/mixin/if_then_else.rb +23 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +24 -0
- data/lib/rubocop/cop/mixin/parser_diagnostic.rb +34 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +19 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +32 -0
- data/lib/rubocop/cop/mixin/space_inside.rb +31 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +59 -0
- data/lib/rubocop/cop/mixin/string_help.rb +32 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +42 -0
- data/lib/rubocop/cop/rails/default_scope.rb +3 -1
- data/lib/rubocop/cop/style/accessor_method_name.rb +4 -12
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +16 -1
- data/lib/rubocop/cop/style/case_indentation.rb +33 -16
- data/lib/rubocop/cop/style/character_literal.rb +10 -0
- data/lib/rubocop/cop/style/dot_position.rb +23 -6
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +5 -5
- data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -32
- data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +20 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +5 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
- data/lib/rubocop/cop/style/indentation_consistency.rb +51 -0
- data/lib/rubocop/cop/style/indentation_width.rb +0 -26
- data/lib/rubocop/cop/style/lambda_call.rb +12 -5
- data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -11
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -9
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +22 -0
- data/lib/rubocop/cop/style/{ternary_operator.rb → nested_ternary_operator.rb} +0 -15
- data/lib/rubocop/cop/style/numeric_literals.rb +30 -2
- data/lib/rubocop/cop/style/one_line_conditional.rb +2 -1
- data/lib/rubocop/cop/style/parameter_lists.rb +7 -3
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +9 -11
- data/lib/rubocop/cop/style/predicate_name.rb +4 -12
- data/lib/rubocop/cop/style/raise_args.rb +19 -11
- data/lib/rubocop/cop/style/regexp_literal.rb +19 -6
- data/lib/rubocop/cop/style/space_after_colon.rb +36 -0
- data/lib/rubocop/cop/style/space_after_comma.rb +16 -0
- data/lib/rubocop/cop/style/space_after_semicolon.rb +16 -0
- data/lib/rubocop/cop/style/space_around_block_braces.rb +38 -38
- data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +6 -2
- data/lib/rubocop/cop/style/string_literals.rb +5 -5
- data/lib/rubocop/cop/style/trailing_comma.rb +94 -0
- data/lib/rubocop/cop/style/unless_else.rb +2 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +32 -0
- data/lib/rubocop/cop/style/word_array.rb +9 -1
- data/lib/rubocop/cop/util.rb +14 -0
- data/lib/rubocop/cop/variable_inspector.rb +11 -6
- data/lib/rubocop/cop/variable_inspector/scope.rb +4 -3
- data/lib/rubocop/file_inspector.rb +22 -6
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/colorizable.rb +37 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +27 -6
- data/lib/rubocop/formatter/progress_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +9 -5
- data/lib/rubocop/options.rb +19 -4
- data/lib/rubocop/target_finder.rb +4 -0
- data/lib/rubocop/version.rb +1 -1
- data/rubocop-todo.yml +10 -2
- data/rubocop.gemspec +3 -2
- data/spec/project_spec.rb +12 -7
- data/spec/rubocop/cli_spec.rb +262 -99
- data/spec/rubocop/config_loader_spec.rb +5 -5
- data/spec/rubocop/config_spec.rb +3 -3
- data/spec/rubocop/config_store_spec.rb +12 -11
- data/spec/rubocop/cop/commissioner_spec.rb +21 -5
- data/spec/rubocop/cop/cop_spec.rb +1 -1
- data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
- data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +2 -2
- data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
- data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
- data/spec/rubocop/cop/lint/end_alignment_spec.rb +41 -1
- data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
- data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +3 -3
- data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +12 -12
- data/spec/rubocop/cop/lint/syntax_spec.rb +2 -2
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +72 -54
- data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
- data/spec/rubocop/cop/offence_spec.rb +1 -1
- data/spec/rubocop/cop/rails/default_scope_spec.rb +6 -0
- data/spec/rubocop/cop/rails/output_spec.rb +2 -1
- data/spec/rubocop/cop/style/align_hash_spec.rb +9 -9
- data/spec/rubocop/cop/style/align_parameters_spec.rb +1 -1
- data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +5 -0
- data/spec/rubocop/cop/style/case_indentation_spec.rb +53 -2
- data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +3 -3
- data/spec/rubocop/cop/style/documentation_spec.rb +0 -1
- data/spec/rubocop/cop/style/dot_position_spec.rb +18 -3
- data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +4 -4
- data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +13 -0
- data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
- data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +1 -1
- data/spec/rubocop/cop/style/hash_syntax_spec.rb +5 -0
- data/spec/rubocop/cop/style/{favor_modifier_spec.rb → if_unless_modifier_spec.rb} +4 -111
- data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
- data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -91
- data/spec/rubocop/cop/style/lambda_call_spec.rb +18 -0
- data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +2 -2
- data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +35 -1
- data/spec/rubocop/cop/style/method_length_spec.rb +1 -0
- data/spec/rubocop/cop/style/method_name_spec.rb +27 -5
- data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +4 -4
- data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
- data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
- data/spec/rubocop/cop/style/{ternary_operator_spec.rb → nested_ternary_operator_spec.rb} +0 -15
- data/spec/rubocop/cop/style/numeric_literals_spec.rb +18 -1
- data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -1
- data/spec/rubocop/cop/style/parameter_lists_spec.rb +1 -0
- data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +13 -4
- data/spec/rubocop/cop/style/raise_args_spec.rb +22 -0
- data/spec/rubocop/cop/style/redundant_self_spec.rb +4 -4
- data/spec/rubocop/cop/style/regexp_literal_spec.rb +4 -0
- data/spec/rubocop/cop/style/space_after_colon_spec.rb +12 -4
- data/spec/rubocop/cop/style/space_after_method_name_spec.rb +2 -2
- data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +30 -1
- data/spec/rubocop/cop/style/{space_around_equals_in_default_parameter_spec.rb → space_around_equals_in_parameter_default_spec.rb} +0 -0
- data/spec/rubocop/cop/style/space_around_operators_spec.rb +2 -1
- data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +20 -3
- data/spec/rubocop/cop/style/string_literals_spec.rb +33 -0
- data/spec/rubocop/cop/style/trailing_comma_spec.rb +200 -0
- data/spec/rubocop/cop/style/variable_name_spec.rb +27 -3
- data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
- data/spec/rubocop/cop/style/word_array_spec.rb +1 -0
- data/spec/rubocop/cop/team_spec.rb +1 -1
- data/spec/rubocop/cop/variable_inspector/scope_spec.rb +3 -4
- data/spec/rubocop/file_inspector_spec.rb +1 -1
- data/spec/rubocop/formatter/base_formatter_spec.rb +12 -11
- data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
- data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +2 -0
- data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
- data/spec/rubocop/formatter/json_formatter_spec.rb +4 -3
- data/spec/rubocop/formatter/progress_formatter_spec.rb +2 -2
- data/spec/rubocop/options_spec.rb +3 -1
- data/spec/rubocop/target_finder_spec.rb +13 -11
- data/spec/spec_helper.rb +5 -1
- data/spec/support/shared_examples.rb +2 -2
- data/spec/support/statement_modifier_helper.rb +41 -0
- metadata +88 -30
- data/lib/rubocop/cop/check_assignment.rb +0 -43
- data/lib/rubocop/cop/style/array_syntax.rb +0 -22
- data/lib/rubocop/cop/style/autocorrect_alignment.rb +0 -78
- data/lib/rubocop/cop/style/code_length.rb +0 -35
- data/lib/rubocop/cop/style/configurable_enforced_style.rb +0 -51
- data/lib/rubocop/cop/style/configurable_max.rb +0 -17
- data/lib/rubocop/cop/style/configurable_naming.rb +0 -41
- data/lib/rubocop/cop/style/favor_modifier.rb +0 -118
- data/lib/rubocop/cop/style/if_then_else.rb +0 -27
- data/lib/rubocop/cop/style/space_after_comma_etc.rb +0 -73
- data/lib/rubocop/cop/style/space_inside.rb +0 -33
- data/lib/rubocop/cop/style/string_help.rb +0 -30
- data/lib/rubocop/cop/style/surrounding_space.rb +0 -44
@@ -18,23 +18,15 @@ module Rubocop
|
|
18
18
|
# # good
|
19
19
|
# def value? ...
|
20
20
|
class PredicateName < Cop
|
21
|
-
|
22
|
-
method_name, args, _body = *node
|
23
|
-
check(node, method_name.to_s, args)
|
24
|
-
end
|
25
|
-
|
26
|
-
def on_defs(node)
|
27
|
-
_scope, method_name, args, _body = *node
|
28
|
-
check(node, method_name.to_s, args)
|
29
|
-
end
|
21
|
+
include CheckMethods
|
30
22
|
|
31
23
|
private
|
32
24
|
|
33
|
-
def check(node, method_name, args)
|
25
|
+
def check(node, method_name, args, _body)
|
34
26
|
prefix_blacklist.each do |prefix|
|
35
|
-
if method_name.start_with?(prefix)
|
27
|
+
if method_name.to_s.start_with?(prefix)
|
36
28
|
add_offence(node, :name,
|
37
|
-
message(method_name, prefix))
|
29
|
+
message(method_name.to_s, prefix))
|
38
30
|
end
|
39
31
|
end
|
40
32
|
end
|
@@ -23,25 +23,33 @@ module Rubocop
|
|
23
23
|
def check_compact(node)
|
24
24
|
_receiver, selector, *args = *node
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
if args.size > 1
|
27
|
+
add_offence(node, :expression, message(selector)) do
|
28
|
+
opposite_style_detected
|
29
|
+
end
|
30
|
+
else
|
31
|
+
correct_style_detected
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
def check_exploded(node)
|
32
36
|
_receiver, selector, *args = *node
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
arg, = *args
|
38
|
+
if args.size == 1
|
39
|
+
arg, = *args
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
if arg.type == :send && arg.loc.selector.is?('new')
|
42
|
+
_receiver, _selector, *constructor_args = *arg
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
# Allow code like `raise Ex.new(arg1, arg2)`.
|
45
|
+
if constructor_args.size <= 1
|
46
|
+
add_offence(node, :expression, message(selector)) do
|
47
|
+
opposite_style_detected
|
48
|
+
end
|
49
|
+
end
|
44
50
|
end
|
51
|
+
else
|
52
|
+
correct_style_detected
|
45
53
|
end
|
46
54
|
end
|
47
55
|
|
@@ -7,16 +7,25 @@ module Rubocop
|
|
7
7
|
# on how many escaped slashes there are in the regexp and on the
|
8
8
|
# value of the configuration parameter MaxSlashes.
|
9
9
|
class RegexpLiteral < Cop
|
10
|
+
include ConfigurableMax
|
11
|
+
|
10
12
|
def on_regexp(node)
|
11
13
|
string_parts = node.children.select { |child| child.type == :str }
|
12
14
|
total_string = string_parts.map { |s| s.loc.expression.source }.join
|
13
15
|
slashes = total_string.count('/')
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
if node.loc.begin.is?('/')
|
17
|
+
if slashes > max_slashes
|
18
|
+
msg = error_message('')
|
19
|
+
safe_setting = slashes
|
20
|
+
end
|
21
|
+
elsif slashes <= max_slashes
|
22
|
+
msg = error_message('only ')
|
23
|
+
safe_setting = slashes + 1
|
24
|
+
end
|
25
|
+
|
26
|
+
if msg
|
27
|
+
add_offence(node, :expression, msg) { self.max = safe_setting }
|
28
|
+
end
|
20
29
|
end
|
21
30
|
|
22
31
|
def max_slashes
|
@@ -25,6 +34,10 @@ module Rubocop
|
|
25
34
|
|
26
35
|
private
|
27
36
|
|
37
|
+
def parameter_name
|
38
|
+
'MaxSlashes'
|
39
|
+
end
|
40
|
+
|
28
41
|
def error_message(word)
|
29
42
|
sprintf('Use %%r %sfor regular expressions matching more ' +
|
30
43
|
"than %d '/' character%s.",
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for colon (:) not follwed by some kind of space.
|
7
|
+
class SpaceAfterColon < Cop
|
8
|
+
include IfNode
|
9
|
+
|
10
|
+
MSG = 'Space missing after colon.'
|
11
|
+
|
12
|
+
def on_pair(node)
|
13
|
+
oper = node.loc.operator
|
14
|
+
if oper.is?(':') && oper.source_buffer.source[oper.end_pos] =~ /\S/
|
15
|
+
add_offence(oper, oper)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_if(node)
|
20
|
+
if ternary_op?(node)
|
21
|
+
colon = node.loc.colon
|
22
|
+
if colon.source_buffer.source[colon.end_pos] =~ /\S/
|
23
|
+
add_offence(colon, colon)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def autocorrect(range)
|
29
|
+
@corrections << lambda do |corrector|
|
30
|
+
corrector.insert_after(range, ' ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for comma (,) not follwed by some kind of space.
|
7
|
+
class SpaceAfterComma < Cop
|
8
|
+
include SpaceAfterPunctuation
|
9
|
+
|
10
|
+
def kind(token)
|
11
|
+
'comma' if token.type == :tCOMMA
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for semicolon (;) not follwed by some kind of space.
|
7
|
+
class SpaceAfterSemicolon < Cop
|
8
|
+
include SpaceAfterPunctuation
|
9
|
+
|
10
|
+
def kind(token)
|
11
|
+
'semicolon' if token.type == :tSEMI
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -42,28 +42,29 @@ module Rubocop
|
|
42
42
|
sb = node.loc.expression.source_buffer
|
43
43
|
|
44
44
|
if left_brace.end_pos == right_brace.begin_pos
|
45
|
-
|
46
|
-
|
45
|
+
if style_for_empty_braces == :space
|
46
|
+
offence(sb, left_brace.begin_pos, right_brace.end_pos,
|
47
|
+
'Space missing inside empty braces.')
|
48
|
+
end
|
47
49
|
else
|
48
50
|
range = Parser::Source::Range.new(sb, left_brace.end_pos,
|
49
51
|
right_brace.begin_pos)
|
50
52
|
inner = range.source
|
51
53
|
unless inner =~ /\n/
|
52
54
|
if inner =~ /\S/
|
53
|
-
braces_with_contents_inside(node, inner)
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
braces_with_contents_inside(node, inner, sb)
|
56
|
+
elsif style_for_empty_braces == :no_space
|
57
|
+
offence(sb, range.begin_pos, range.end_pos,
|
58
|
+
'Space inside empty braces detected.')
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
def braces_with_contents_inside(node, inner)
|
64
|
+
def braces_with_contents_inside(node, inner, sb)
|
63
65
|
_method, args, _body = *node
|
64
66
|
left_brace, right_brace = node.loc.begin, node.loc.end
|
65
67
|
pipe = args.loc.begin
|
66
|
-
sb = node.loc.expression.source_buffer
|
67
68
|
|
68
69
|
if inner =~ /^\S/
|
69
70
|
no_space_inside_left_brace(left_brace, pipe, sb)
|
@@ -72,8 +73,8 @@ module Rubocop
|
|
72
73
|
end
|
73
74
|
|
74
75
|
if inner =~ /\S$/
|
75
|
-
no_space(
|
76
|
-
|
76
|
+
no_space(sb, right_brace.begin_pos, right_brace.end_pos,
|
77
|
+
'Space missing inside }.')
|
77
78
|
else
|
78
79
|
space_inside_right_brace(right_brace, sb)
|
79
80
|
end
|
@@ -81,55 +82,58 @@ module Rubocop
|
|
81
82
|
|
82
83
|
def no_space_inside_left_brace(left_brace, pipe, sb)
|
83
84
|
if pipe
|
84
|
-
if left_brace.end_pos == pipe.begin_pos
|
85
|
-
|
86
|
-
|
85
|
+
if left_brace.end_pos == pipe.begin_pos &&
|
86
|
+
cop_config['SpaceBeforeBlockParameters']
|
87
|
+
offence(sb, left_brace.begin_pos, pipe.end_pos,
|
88
|
+
'Space between { and | missing.')
|
87
89
|
end
|
88
90
|
else
|
89
91
|
# We indicate the position after the left brace. Otherwise it's
|
90
92
|
# difficult to distinguish between space missing to the left and to
|
91
93
|
# the right of the brace in autocorrect.
|
92
|
-
no_space(
|
93
|
-
|
94
|
+
no_space(sb, left_brace.end_pos, left_brace.end_pos + 1,
|
95
|
+
'Space missing inside {.')
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
97
99
|
def space_inside_left_brace(left_brace, pipe, sb)
|
98
100
|
if pipe
|
99
|
-
|
100
|
-
|
101
|
+
unless cop_config['SpaceBeforeBlockParameters']
|
102
|
+
offence(sb, left_brace.end_pos, pipe.begin_pos,
|
103
|
+
'Space between { and | detected.')
|
104
|
+
end
|
101
105
|
else
|
102
106
|
brace_with_space = range_with_surrounding_space(left_brace, :right)
|
103
|
-
space(
|
104
|
-
|
107
|
+
space(sb, brace_with_space.begin_pos + 1, brace_with_space.end_pos,
|
108
|
+
'Space inside { detected.')
|
105
109
|
end
|
106
110
|
end
|
107
111
|
|
108
112
|
def space_inside_right_brace(right_brace, sb)
|
109
113
|
brace_with_space = range_with_surrounding_space(right_brace, :left)
|
110
|
-
space(
|
111
|
-
|
114
|
+
space(sb, brace_with_space.begin_pos, brace_with_space.end_pos - 1,
|
115
|
+
'Space inside } detected.')
|
112
116
|
end
|
113
117
|
|
114
|
-
def no_space(
|
115
|
-
|
118
|
+
def no_space(sb, begin_pos, end_pos, msg)
|
119
|
+
if style == :space_inside_braces
|
120
|
+
offence(sb, begin_pos, end_pos, msg) { opposite_style_detected }
|
121
|
+
else
|
122
|
+
correct_style_detected
|
123
|
+
end
|
116
124
|
end
|
117
125
|
|
118
|
-
def space(
|
119
|
-
|
126
|
+
def space(sb, begin_pos, end_pos, msg)
|
127
|
+
if style == :no_space_inside_braces
|
128
|
+
offence(sb, begin_pos, end_pos, msg) { opposite_style_detected }
|
129
|
+
else
|
130
|
+
correct_style_detected
|
131
|
+
end
|
120
132
|
end
|
121
133
|
|
122
134
|
def offence(sb, begin_pos, end_pos, msg)
|
123
135
|
range = Parser::Source::Range.new(sb, begin_pos, end_pos)
|
124
|
-
add_offence(range, range, msg)
|
125
|
-
end
|
126
|
-
|
127
|
-
def available_styles
|
128
|
-
%w(space_inside_braces no_space_inside_braces)
|
129
|
-
end
|
130
|
-
|
131
|
-
def style_for_inside_braces
|
132
|
-
style == :space_inside_braces ? :space : :no_space
|
136
|
+
add_offence(range, range, msg) { yield if block_given? }
|
133
137
|
end
|
134
138
|
|
135
139
|
def style_for_empty_braces
|
@@ -140,10 +144,6 @@ module Rubocop
|
|
140
144
|
end
|
141
145
|
end
|
142
146
|
|
143
|
-
def style_for_block_parameters
|
144
|
-
cop_config['SpaceBeforeBlockParameters'] ? :space : :no_space
|
145
|
-
end
|
146
|
-
|
147
147
|
def autocorrect(range)
|
148
148
|
@corrections << lambda do |corrector|
|
149
149
|
case range.source
|
@@ -6,8 +6,7 @@ module Rubocop
|
|
6
6
|
# Checks that operators have space around them, except for **
|
7
7
|
# which should not have surrounding space.
|
8
8
|
class SpaceAroundOperators < Cop
|
9
|
-
TYPES = %w(and or class
|
10
|
-
op_asgn and_asgn or_asgn masgn casgn lvasgn ivasgn gvasgn)
|
9
|
+
TYPES = %w(and or class) + ASGN_NODES
|
11
10
|
|
12
11
|
TYPES.each { |t| define_method(:"on_#{t}") { |node| check(node) } }
|
13
12
|
|
@@ -40,8 +40,12 @@ module Rubocop
|
|
40
40
|
if offence?(t1, t2, expect_space)
|
41
41
|
brace = (t1.text == '{' ? t1 : t2).pos
|
42
42
|
range = expect_space ? brace : space_range(brace)
|
43
|
-
add_offence(range, range,
|
44
|
-
|
43
|
+
add_offence(range, range, message(brace, is_empty_braces,
|
44
|
+
expect_space)) do
|
45
|
+
opposite_style_detected
|
46
|
+
end
|
47
|
+
else
|
48
|
+
correct_style_detected
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
@@ -12,17 +12,17 @@ module Rubocop
|
|
12
12
|
|
13
13
|
def message(node)
|
14
14
|
if style == :single_quotes
|
15
|
-
"Prefer single-quoted strings when you don't need string "
|
16
|
-
|
15
|
+
"Prefer single-quoted strings when you don't need string " \
|
16
|
+
'interpolation or special symbols.'
|
17
17
|
else
|
18
|
-
'Prefer double-quoted strings unless you need single quotes to '
|
19
|
-
|
18
|
+
'Prefer double-quoted strings unless you need single quotes to ' \
|
19
|
+
'avoid extra backslashes for escaping.'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def offence?(node)
|
24
24
|
src = node.loc.expression.source
|
25
|
-
return false if src =~ /^(%
|
25
|
+
return false if src =~ /^(%[qQ]?|\?|<<-)/i
|
26
26
|
src !~ if style == :single_quotes
|
27
27
|
# regex matches IF there is a ' or there is a \\ in the
|
28
28
|
# string that is not preceeded/followed by another \\
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for trailing comma in parameter lists and literals.
|
7
|
+
class TrailingComma < Cop
|
8
|
+
include ConfigurableEnforcedStyle
|
9
|
+
|
10
|
+
MSG = '%s comma after the last %s.'
|
11
|
+
|
12
|
+
def on_array(node)
|
13
|
+
check_literal(node, 'item of %s array')
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_hash(node)
|
17
|
+
check_literal(node, 'item of %s hash')
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_send(node)
|
21
|
+
_receiver, _method_name, *args = *node
|
22
|
+
return if args.empty?
|
23
|
+
# It's impossible for a method call without parentheses to have
|
24
|
+
# a trailing comma.
|
25
|
+
return unless brackets?(node)
|
26
|
+
|
27
|
+
check(node, args, 'parameter of %s method call',
|
28
|
+
args.last.loc.expression.end_pos, node.loc.expression.end_pos)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def parameter_name
|
34
|
+
'EnforcedStyleForMultiline'
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_literal(node, kind)
|
38
|
+
return if node.children.empty?
|
39
|
+
# A braceless hash is the last parameter of a method call and will be
|
40
|
+
# checked as such.
|
41
|
+
return unless brackets?(node)
|
42
|
+
|
43
|
+
check(node, node.children, kind,
|
44
|
+
node.children.last.loc.expression.end_pos,
|
45
|
+
node.loc.end.begin_pos)
|
46
|
+
end
|
47
|
+
|
48
|
+
def check(node, items, kind, begin_pos, end_pos)
|
49
|
+
sb = items.first.loc.expression.source_buffer
|
50
|
+
after_last_item = Parser::Source::Range.new(sb, begin_pos, end_pos)
|
51
|
+
comma_offset = after_last_item.source =~ /,/
|
52
|
+
should_have_comma = style == :comma && multiline?(node)
|
53
|
+
if comma_offset
|
54
|
+
unless should_have_comma
|
55
|
+
avoid_comma(items, kind,
|
56
|
+
after_last_item.begin_pos + comma_offset, sb)
|
57
|
+
end
|
58
|
+
elsif should_have_comma
|
59
|
+
put_comma(items, kind, sb)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns true if the node has round/square/curly brackets.
|
64
|
+
def brackets?(node)
|
65
|
+
!node.loc.end.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns true if the round/square/curly brackets of the given node are
|
69
|
+
# on different lines.
|
70
|
+
def multiline?(node)
|
71
|
+
[node.loc.begin, node.loc.end].map(&:line).uniq.size > 1
|
72
|
+
end
|
73
|
+
|
74
|
+
def avoid_comma(items, kind, comma_begin_pos, sb)
|
75
|
+
range = Parser::Source::Range.new(sb, comma_begin_pos,
|
76
|
+
comma_begin_pos + 1)
|
77
|
+
article = kind =~ /array/ ? 'an' : 'a'
|
78
|
+
add_offence(nil, range,
|
79
|
+
sprintf(MSG, 'Avoid', sprintf(kind, article)))
|
80
|
+
end
|
81
|
+
|
82
|
+
def put_comma(items, kind, sb)
|
83
|
+
last_expr = items.last.loc.expression
|
84
|
+
ix = last_expr.source.rindex("\n") || 0
|
85
|
+
ix += last_expr.source[ix..-1] =~ /\S/
|
86
|
+
range = Parser::Source::Range.new(sb, last_expr.begin_pos + ix,
|
87
|
+
last_expr.end_pos)
|
88
|
+
add_offence(nil, range,
|
89
|
+
sprintf(MSG, 'Put a', sprintf(kind, 'a multiline')))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|