rubocop 0.7.2 → 0.8.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/.travis.yml +7 -1
- data/CHANGELOG.md +19 -0
- data/README.md +4 -8
- data/bin/rubocop +2 -2
- data/config/default.yml +8 -0
- data/config/enabled.yml +21 -24
- data/lib/rubocop.rb +9 -7
- data/lib/rubocop/cli.rb +73 -52
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/cop/access_control.rb +41 -0
- data/lib/rubocop/cop/alias.rb +7 -5
- data/lib/rubocop/cop/align_parameters.rb +20 -96
- data/lib/rubocop/cop/and_or.rb +26 -0
- data/lib/rubocop/cop/ascii_comments.rb +3 -8
- data/lib/rubocop/cop/ascii_identifiers.rb +6 -5
- data/lib/rubocop/cop/avoid_class_vars.rb +5 -10
- data/lib/rubocop/cop/avoid_for.rb +7 -5
- data/lib/rubocop/cop/avoid_global_vars.rb +19 -7
- data/lib/rubocop/cop/avoid_perl_backrefs.rb +7 -10
- data/lib/rubocop/cop/avoid_perlisms.rb +11 -10
- data/lib/rubocop/cop/block_comments.rb +4 -6
- data/lib/rubocop/cop/blocks.rb +11 -47
- data/lib/rubocop/cop/case_indentation.rb +9 -31
- data/lib/rubocop/cop/class_and_module_camel_case.rb +20 -11
- data/lib/rubocop/cop/class_methods.rb +5 -10
- data/lib/rubocop/cop/collection_methods.rb +16 -16
- data/lib/rubocop/cop/colon_method_call.rb +8 -32
- data/lib/rubocop/cop/constant_name.rb +24 -0
- data/lib/rubocop/cop/cop.rb +20 -78
- data/lib/rubocop/cop/def_parentheses.rb +43 -35
- data/lib/rubocop/cop/empty_line_between_defs.rb +11 -15
- data/lib/rubocop/cop/empty_lines.rb +20 -9
- data/lib/rubocop/cop/empty_literal.rb +47 -0
- data/lib/rubocop/cop/encoding.rb +3 -3
- data/lib/rubocop/cop/end_of_line.rb +3 -3
- data/lib/rubocop/cop/ensure_return.rb +6 -23
- data/lib/rubocop/cop/eval.rb +7 -10
- data/lib/rubocop/cop/favor_join.rb +9 -24
- data/lib/rubocop/cop/favor_modifier.rb +38 -48
- data/lib/rubocop/cop/favor_percent_r.rb +7 -7
- data/lib/rubocop/cop/favor_sprintf.rb +8 -24
- data/lib/rubocop/cop/favor_unless_over_negated_if.rb +19 -17
- data/lib/rubocop/cop/handle_exceptions.rb +7 -11
- data/lib/rubocop/cop/hash_syntax.rb +29 -14
- data/lib/rubocop/cop/if_then_else.rb +32 -29
- data/lib/rubocop/cop/leading_comment_space.rb +5 -8
- data/lib/rubocop/cop/line_continuation.rb +4 -7
- data/lib/rubocop/cop/line_length.rb +3 -3
- data/lib/rubocop/cop/loop.rb +33 -0
- data/lib/rubocop/cop/method_and_variable_snake_case.rb +42 -19
- data/lib/rubocop/cop/method_length.rb +34 -37
- data/lib/rubocop/cop/new_lambda_literal.rb +8 -6
- data/lib/rubocop/cop/not.rb +10 -4
- data/lib/rubocop/cop/numeric_literals.rb +9 -7
- data/lib/rubocop/cop/offence.rb +1 -1
- data/lib/rubocop/cop/op_method.rb +12 -22
- data/lib/rubocop/cop/parameter_lists.rb +12 -6
- data/lib/rubocop/cop/parentheses_around_condition.rb +11 -11
- data/lib/rubocop/cop/percent_r.rb +7 -7
- data/lib/rubocop/cop/reduce_arguments.rb +13 -51
- data/lib/rubocop/cop/rescue_exception.rb +13 -29
- data/lib/rubocop/cop/rescue_modifier.rb +5 -8
- data/lib/rubocop/cop/semicolon.rb +15 -74
- data/lib/rubocop/cop/single_line_methods.rb +28 -44
- data/lib/rubocop/cop/space_after_comma_etc.rb +29 -9
- data/lib/rubocop/cop/space_after_control_keyword.rb +16 -15
- data/lib/rubocop/cop/string_literals.rb +9 -35
- data/lib/rubocop/cop/surrounding_space.rb +213 -112
- data/lib/rubocop/cop/symbol_array.rb +9 -7
- data/lib/rubocop/cop/symbol_name.rb +23 -0
- data/lib/rubocop/cop/syntax.rb +14 -7
- data/lib/rubocop/cop/tab.rb +3 -3
- data/lib/rubocop/cop/ternary_operator.rb +26 -24
- data/lib/rubocop/cop/trailing_whitespace.rb +3 -5
- data/lib/rubocop/cop/trivial_accessors.rb +18 -95
- data/lib/rubocop/cop/unless_else.rb +11 -7
- data/lib/rubocop/cop/util.rb +26 -0
- data/lib/rubocop/cop/variable_interpolation.rb +18 -10
- data/lib/rubocop/cop/when_then.rb +6 -17
- data/lib/rubocop/cop/word_array.rb +18 -19
- data/lib/rubocop/version.rb +1 -1
- data/rubocop.gemspec +1 -0
- data/spec/project_spec.rb +1 -1
- data/spec/rubocop/cli_spec.rb +16 -9
- data/spec/rubocop/config_spec.rb +13 -3
- data/spec/rubocop/cops/access_control_spec.rb +129 -0
- data/spec/rubocop/cops/alias_spec.rb +2 -6
- data/spec/rubocop/cops/align_parameters_spec.rb +58 -71
- data/spec/rubocop/cops/and_or_spec.rb +37 -0
- data/spec/rubocop/cops/ascii_comments_spec.rb +3 -4
- data/spec/rubocop/cops/ascii_identifiers_spec.rb +3 -4
- data/spec/rubocop/cops/avoid_class_vars_spec.rb +7 -2
- data/spec/rubocop/cops/avoid_for_spec.rb +1 -4
- data/spec/rubocop/cops/{avoid_global_vars.rb → avoid_global_vars_spec.rb} +4 -4
- data/spec/rubocop/cops/avoid_perl_backrefs_spec.rb +1 -1
- data/spec/rubocop/cops/avoid_perlisms_spec.rb +5 -5
- data/spec/rubocop/cops/block_comments_spec.rb +0 -4
- data/spec/rubocop/cops/blocks_spec.rb +33 -0
- data/spec/rubocop/cops/case_indentation_spec.rb +5 -5
- data/spec/rubocop/cops/class_and_module_camel_case_spec.rb +15 -5
- data/spec/rubocop/cops/class_methods_spec.rb +4 -4
- data/spec/rubocop/cops/collection_methods_spec.rb +9 -4
- data/spec/rubocop/cops/colon_method_call_spec.rb +11 -5
- data/spec/rubocop/cops/constant_name_spec.rb +42 -0
- data/spec/rubocop/cops/def_with_parentheses_spec.rb +13 -8
- data/spec/rubocop/cops/def_without_parentheses_spec.rb +11 -5
- data/spec/rubocop/cops/empty_line_between_defs_spec.rb +38 -38
- data/spec/rubocop/cops/empty_lines_spec.rb +15 -3
- data/spec/rubocop/cops/empty_literal_spec.rb +90 -0
- data/spec/rubocop/cops/encoding_spec.rb +9 -9
- data/spec/rubocop/cops/end_of_line_spec.rb +2 -2
- data/spec/rubocop/cops/ensure_return_spec.rb +1 -3
- data/spec/rubocop/cops/eval_spec.rb +8 -5
- data/spec/rubocop/cops/favor_join_spec.rb +1 -5
- data/spec/rubocop/cops/favor_modifier_spec.rb +16 -14
- data/spec/rubocop/cops/{favor_percent_r.rb → favor_percent_r_spec.rb} +6 -6
- data/spec/rubocop/cops/favor_sprintf_spec.rb +3 -9
- data/spec/rubocop/cops/favor_unless_over_negated_if_spec.rb +4 -4
- data/spec/rubocop/cops/favor_until_over_negated_while_spec.rb +3 -3
- data/spec/rubocop/cops/handle_exceptions_spec.rb +1 -3
- data/spec/rubocop/cops/hash_syntax_spec.rb +11 -6
- data/spec/rubocop/cops/if_with_semicolon_spec.rb +7 -1
- data/spec/rubocop/cops/leading_comment_space_spec.rb +0 -7
- data/spec/rubocop/cops/line_continuation_spec.rb +2 -2
- data/spec/rubocop/cops/line_length_spec.rb +2 -2
- data/spec/rubocop/cops/loop_spec.rb +31 -0
- data/spec/rubocop/cops/method_and_variable_snake_case_spec.rb +38 -12
- data/spec/rubocop/cops/method_length_spec.rb +85 -85
- data/spec/rubocop/cops/multiline_if_then_spec.rb +15 -15
- data/spec/rubocop/cops/new_lambda_literal_spec.rb +3 -3
- data/spec/rubocop/cops/not_spec.rb +1 -4
- data/spec/rubocop/cops/numeric_literals_spec.rb +13 -13
- data/spec/rubocop/cops/one_line_conditional_spec.rb +1 -1
- data/spec/rubocop/cops/op_method_spec.rb +2 -9
- data/spec/rubocop/cops/parameter_lists_spec.rb +7 -7
- data/spec/rubocop/cops/parentheses_around_condition_spec.rb +41 -44
- data/spec/rubocop/cops/percent_r_spec.rb +6 -6
- data/spec/rubocop/cops/reduce_arguments_spec.rb +4 -4
- data/spec/rubocop/cops/rescue_exception_spec.rb +48 -8
- data/spec/rubocop/cops/rescue_modifier_spec.rb +2 -5
- data/spec/rubocop/cops/semicolon_spec.rb +2 -30
- data/spec/rubocop/cops/single_line_methods_spec.rb +13 -13
- data/spec/rubocop/cops/space_after_colon_spec.rb +3 -3
- data/spec/rubocop/cops/space_after_comma_spec.rb +14 -2
- data/spec/rubocop/cops/space_after_control_keyword_spec.rb +42 -3
- data/spec/rubocop/cops/space_after_semicolon_spec.rb +2 -2
- data/spec/rubocop/cops/space_around_braces_spec.rb +18 -3
- data/spec/rubocop/cops/space_around_equals_in_default_parameter_spec.rb +4 -4
- data/spec/rubocop/cops/space_around_operators_spec.rb +82 -27
- data/spec/rubocop/cops/space_inside_brackets_spec.rb +13 -7
- data/spec/rubocop/cops/space_inside_hash_literal_braces_spec.rb +14 -9
- data/spec/rubocop/cops/space_inside_parens_spec.rb +7 -3
- data/spec/rubocop/cops/string_literals_spec.rb +17 -5
- data/spec/rubocop/cops/symbol_array_spec.rb +18 -2
- data/spec/rubocop/cops/symbol_name_spec.rb +119 -0
- data/spec/rubocop/cops/syntax_spec.rb +25 -18
- data/spec/rubocop/cops/tab_spec.rb +2 -2
- data/spec/rubocop/cops/ternary_operator_spec.rb +13 -17
- data/spec/rubocop/cops/trailing_whitespace_spec.rb +3 -3
- data/spec/rubocop/cops/trivial_accessors_spec.rb +17 -20
- data/spec/rubocop/cops/unless_else_spec.rb +8 -8
- data/spec/rubocop/cops/variable_interpolation_spec.rb +0 -5
- data/spec/rubocop/cops/when_then_spec.rb +14 -21
- data/spec/rubocop/cops/word_array_spec.rb +12 -4
- data/spec/spec_helper.rb +12 -4
- metadata +40 -31
- data/.document +0 -5
- data/lib/rubocop/cop/ampersands_pipes_vs_and_or.rb +0 -25
- data/lib/rubocop/cop/array_literal.rb +0 -61
- data/lib/rubocop/cop/brace_after_percent.rb +0 -32
- data/lib/rubocop/cop/grammar.rb +0 -138
- data/lib/rubocop/cop/hash_literal.rb +0 -61
- data/lib/rubocop/cop/percent_literals.rb +0 -25
- data/lib/rubocop/cop/symbol_snake_case.rb +0 -47
- data/spec/rubocop/cops/ampersands_pipes_vs_and_or_spec.rb +0 -57
- data/spec/rubocop/cops/array_literal_spec.rb +0 -46
- data/spec/rubocop/cops/brace_after_percent_spec.rb +0 -33
- data/spec/rubocop/cops/grammar_spec.rb +0 -81
- data/spec/rubocop/cops/hash_literal_spec.rb +0 -46
- data/spec/rubocop/cops/multiline_blocks_spec.rb +0 -24
- data/spec/rubocop/cops/percent_literals_spec.rb +0 -47
- data/spec/rubocop/cops/single_line_blocks_spec.rb +0 -22
- data/spec/rubocop/cops/symbol_snake_case_spec.rb +0 -93
@@ -3,23 +3,25 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class SymbolArray < Cop
|
6
|
-
|
6
|
+
MSG = 'Use %i or %I for array of symbols.'
|
7
7
|
|
8
|
-
def inspect(
|
8
|
+
def inspect(source, tokens, ast, comments)
|
9
9
|
# %i and %I were introduced in Ruby 2.0
|
10
10
|
unless RUBY_VERSION < '2.0.0'
|
11
|
-
|
12
|
-
|
11
|
+
on_node(:array, ast) do |s|
|
12
|
+
next unless s.loc.begin && s.loc.begin.source == '['
|
13
|
+
|
14
|
+
array_elems = s.children
|
13
15
|
|
14
16
|
# no need to check empty arrays
|
15
17
|
next unless array_elems && array_elems.size > 1
|
16
18
|
|
17
|
-
symbol_array = array_elems.all? { |e| e
|
19
|
+
symbol_array = array_elems.all? { |e| e.type == :sym }
|
18
20
|
|
19
21
|
if symbol_array
|
20
22
|
add_offence(:convention,
|
21
|
-
|
22
|
-
|
23
|
+
s.loc.line,
|
24
|
+
MSG)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class SymbolName < Cop
|
6
|
+
MSG = 'Use snake_case for symbols.'
|
7
|
+
SNAKE_CASE = /^[\da-z_]+[!?=]?$/
|
8
|
+
CAMEL_CASE = /^[A-Z][A-Za-z\d]*$/
|
9
|
+
|
10
|
+
def allow_camel_case?
|
11
|
+
self.class.config['AllowCamelCase']
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_sym(node)
|
15
|
+
sym_name = node.to_a[0]
|
16
|
+
return unless sym_name =~ /^[a-zA-Z]/
|
17
|
+
return if sym_name =~ SNAKE_CASE
|
18
|
+
return if allow_camel_case? && sym_name =~ CAMEL_CASE
|
19
|
+
add_offence(:convention, node.loc.line, MSG)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/rubocop/cop/syntax.rb
CHANGED
@@ -5,26 +5,33 @@ require 'open3'
|
|
5
5
|
module Rubocop
|
6
6
|
module Cop
|
7
7
|
class Syntax < Cop
|
8
|
-
def
|
8
|
+
def inspect_file(file)
|
9
|
+
# Starting JRuby processes would be extremely slow
|
10
|
+
# We need to check if rbx returns nice warning messages
|
11
|
+
return unless RUBY_ENGINE == 'ruby'
|
12
|
+
|
9
13
|
stderr = nil
|
10
14
|
|
11
15
|
# it's extremely important to run the syntax check in a
|
12
16
|
# clean environment - otherwise it will be extremely slow
|
13
17
|
if defined? Bundler
|
14
18
|
Bundler.with_clean_env do
|
15
|
-
_, stderr, _ =
|
16
|
-
Open3.capture3('ruby -wc', stdin_data: source.join("\n"))
|
19
|
+
_, stderr, _ = Open3.capture3("ruby -wc #{file}")
|
17
20
|
end
|
18
21
|
else
|
19
|
-
_, stderr, _ =
|
20
|
-
Open3.capture3('ruby -wc', stdin_data: source.join("\n"))
|
22
|
+
_, stderr, _ = Open3.capture3("ruby -wc #{file}")
|
21
23
|
end
|
22
24
|
|
23
25
|
stderr.each_line do |line|
|
24
26
|
# discard lines that are not containing relevant info
|
25
27
|
if line =~ /.+:(\d+): (.+)/
|
26
|
-
|
27
|
-
|
28
|
+
# Assignment to unused variables beginning with underscore
|
29
|
+
# is reported by Ruby 1.9, but not 2.0. Make 1.9 behave
|
30
|
+
# like 2.0.
|
31
|
+
unless line =~ /assigned but unused variable - _\w+/
|
32
|
+
line_no, severity, message = process_line(line)
|
33
|
+
add_offence(severity, line_no, message)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
end
|
30
37
|
end
|
data/lib/rubocop/cop/tab.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class Tab < Cop
|
6
|
-
|
6
|
+
MSG = 'Tab detected.'
|
7
7
|
|
8
|
-
def inspect(
|
8
|
+
def inspect(source, tokens, ast, comments)
|
9
9
|
source.each_with_index do |line, index|
|
10
|
-
add_offence(:convention, index + 1,
|
10
|
+
add_offence(:convention, index + 1, MSG) if line =~ /^ *\t/
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -2,39 +2,41 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
module TernaryOperator
|
6
|
-
def inspect(file, source, tokens, sexp)
|
7
|
-
each(:ifop, sexp) do |ifop|
|
8
|
-
if offends?(ifop)
|
9
|
-
add_offence(:convention, all_positions(ifop).first.lineno,
|
10
|
-
error_message)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
5
|
class MultilineTernaryOperator < Cop
|
17
|
-
|
18
|
-
|
19
|
-
def error_message
|
6
|
+
MSG =
|
20
7
|
'Avoid multi-line ?: (the ternary operator); use if/unless instead.'
|
21
|
-
end
|
22
8
|
|
23
|
-
def
|
24
|
-
|
9
|
+
def on_if(node)
|
10
|
+
loc = node.loc
|
11
|
+
|
12
|
+
# discard non-ternary ops
|
13
|
+
return unless loc.respond_to?(:question)
|
14
|
+
|
15
|
+
add_offence(:convention, loc.line, MSG) if loc.line != loc.colon.line
|
16
|
+
|
17
|
+
super
|
25
18
|
end
|
26
19
|
end
|
27
20
|
|
28
21
|
class NestedTernaryOperator < Cop
|
29
|
-
|
22
|
+
MSG = 'Ternary operators must not be nested. Prefer if/else ' +
|
23
|
+
'constructs instead.'
|
30
24
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
def on_if(node)
|
26
|
+
loc = node.loc
|
27
|
+
|
28
|
+
# discard non-ternary ops
|
29
|
+
return unless loc.respond_to?(:question)
|
30
|
+
|
31
|
+
node.children.each do |child|
|
32
|
+
on_node(:if, child) do |c|
|
33
|
+
if c.loc.respond_to?(:question)
|
34
|
+
add_offence(:convention, c.loc.line, MSG)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
35
38
|
|
36
|
-
|
37
|
-
ifop.flatten[1..-1].include?(:ifop)
|
39
|
+
super
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -3,13 +3,11 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class TrailingWhitespace < Cop
|
6
|
-
|
6
|
+
MSG = 'Trailing whitespace detected.'
|
7
7
|
|
8
|
-
def inspect(
|
8
|
+
def inspect(source, tokens, ast, comments)
|
9
9
|
source.each_with_index do |line, index|
|
10
|
-
if line =~ /.*[ \t]+$/
|
11
|
-
add_offence(:convention, index + 1, ERROR_MESSAGE)
|
12
|
-
end
|
10
|
+
add_offence(:convention, index + 1, MSG) if line =~ /.*[ \t]+$/
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
@@ -3,101 +3,24 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class TrivialAccessors < Cop
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
lineno = sexp[1][2].lineno
|
21
|
-
accessor_var = sexp[1][1]
|
22
|
-
if trivial_reader?(sexp, accessor_var)
|
23
|
-
add_offence(:convention, lineno, READER_MESSAGE)
|
24
|
-
elsif trivial_writer?(sexp, accessor_var)
|
25
|
-
add_offence(:convention, lineno, WRITER_MESSAGE)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# body statements that exclude a trivial accessor
|
30
|
-
NON_TRIVIAL_BODYSTMT = [:void_stmt, :unary, :binary,
|
31
|
-
:@float, :@int, :hash, :begin,
|
32
|
-
:yield0, :zsuper, :array]
|
33
|
-
|
34
|
-
# looking for a trivial reader method
|
35
|
-
def trivial_reader?(sexp, accessor_var)
|
36
|
-
if reader_shape?(sexp)
|
37
|
-
accessor_body = sexp[3][1][0][1][1]
|
38
|
-
accessor_body.slice!(0) if accessor_body[0] == '@'
|
39
|
-
accessor_var == accessor_body
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# looking for a trivial writer method
|
44
|
-
def trivial_writer?(sexp, accessor_var)
|
45
|
-
if accessor_var[-1] == '=' &&
|
46
|
-
writer_shape?(sexp) &&
|
47
|
-
has_only_one_assignment?(sexp)
|
48
|
-
accessor_var.chop!
|
49
|
-
accessor_body = sexp[3][1][0][1][1][1]
|
50
|
-
accessor_body.slice!(0) if accessor_body[0] == '@'
|
51
|
-
unless sexp[3][1][0][0] == :vcall
|
52
|
-
body_purpose = sexp[3][1][0][2][0]
|
53
|
-
accessor_var == accessor_body && body_purpose == :var_ref
|
54
|
-
end
|
6
|
+
MSG = 'Use attr_%s to define trivial %s methods.'
|
7
|
+
|
8
|
+
def on_def(node)
|
9
|
+
_, args, body = *node
|
10
|
+
|
11
|
+
kind = if body.type == :ivar
|
12
|
+
'reader'
|
13
|
+
elsif args.children.size == 1 && body.type == :ivasgn &&
|
14
|
+
body.children[1].type == :lvar
|
15
|
+
'writer'
|
16
|
+
end
|
17
|
+
if kind
|
18
|
+
add_offence(:convention, node.loc.keyword.line,
|
19
|
+
sprintf(MSG, kind, kind))
|
55
20
|
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# return true if the sexp is a reader accessor, without params
|
59
|
-
# or with empty braces
|
60
|
-
def reader_shape?(sexp)
|
61
|
-
accessor_shape?(sexp) &&
|
62
|
-
(sexp[2][0] == :params || empty_params?(sexp[2]))
|
63
|
-
end
|
64
|
-
|
65
|
-
# return true if the sexp is a writer accessor, with a param
|
66
|
-
# and with or without braces
|
67
|
-
def writer_shape?(sexp)
|
68
|
-
accessor_shape?(sexp) && with_braces?(sexp[2])
|
69
|
-
end
|
70
|
-
|
71
|
-
# return true if the sexp has the common shape of an accessor
|
72
|
-
def accessor_shape?(sexp)
|
73
|
-
[:@ident, :@const].include?(sexp[1][0]) &&
|
74
|
-
sexp[3][0] == :bodystmt &&
|
75
|
-
!NON_TRIVIAL_BODYSTMT.include?(sexp[3][1][0][0])
|
76
|
-
end
|
77
|
-
|
78
|
-
# detect "def foo() ..." or
|
79
|
-
# "[:paren, [:params, nil, nil, nil, nil, nil, nil, nil]]"
|
80
|
-
def empty_params?(sexp)
|
81
|
-
sexp[0] == :paren &&
|
82
|
-
sexp[1][0] == :params &&
|
83
|
-
sexp[1][1..-1].reject { |x| !x }.empty?
|
84
|
-
end
|
85
21
|
|
86
|
-
|
87
|
-
def with_braces?(sexp)
|
88
|
-
(sexp[0] == :paren && sexp[1][0] == :params) ||
|
89
|
-
sexp[0] == :params
|
22
|
+
super
|
90
23
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# why [3..-1]? because:
|
95
|
-
# [:bodystmt, [[:assign, [:var_field, [:var_ref ...] and no :vcall
|
96
|
-
# thus [:bodystmt, :assign, :var_ref, nil, nil, nil ...]
|
97
|
-
def has_only_one_assignment?(sexp)
|
98
|
-
sexp[3][1][1] == nil
|
99
|
-
end
|
100
|
-
|
101
|
-
end # TrivialAccessors
|
102
|
-
end # Cop
|
103
|
-
end # Rubocop
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,16 +3,20 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class UnlessElse < Cop
|
6
|
-
|
6
|
+
MSG = 'Never use unless with else. Rewrite these with the ' +
|
7
7
|
'positive case first.'
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
def on_if(node)
|
10
|
+
loc = node.loc
|
11
|
+
|
12
|
+
# discard ternary ops and modifier if/unless nodes
|
13
|
+
return unless loc.respond_to?(:keyword) && loc.respond_to?(:else)
|
14
|
+
|
15
|
+
if loc.keyword.source == 'unless' && loc.else
|
16
|
+
add_offence(:convention, loc.line, MSG)
|
15
17
|
end
|
18
|
+
|
19
|
+
super
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Util
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def strip_quotes(str)
|
9
|
+
if str[0] == '"' || str[0] == "'"
|
10
|
+
str[0] = ''
|
11
|
+
str[-1] = ''
|
12
|
+
else
|
13
|
+
# we're dealing with %q or %Q
|
14
|
+
str[0, 3] = ''
|
15
|
+
str[-1] = ''
|
16
|
+
end
|
17
|
+
|
18
|
+
str
|
19
|
+
end
|
20
|
+
|
21
|
+
def block_length(block_node)
|
22
|
+
block_node.loc.end.line - block_node.loc.begin.line
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,18 +3,26 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class VariableInterpolation < Cop
|
6
|
-
|
7
|
-
each(:string_dvar, sexp) do |s|
|
8
|
-
interpolation = s[1][0] == :@backref ? s[1] : s[1][1]
|
9
|
-
var = interpolation[1]
|
10
|
-
lineno = interpolation[2].lineno
|
6
|
+
MSG = 'Replace interpolated var %s with expression #{%s}.'
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
)
|
8
|
+
def on_dstr(node)
|
9
|
+
var_nodes(node.children).each do |v|
|
10
|
+
var = (v.type == :nth_ref ? '$' : '') + v.to_a[0].to_s
|
11
|
+
|
12
|
+
if node.loc.expression.source.include?("##{var}")
|
13
|
+
add_offence(:convention,
|
14
|
+
v.loc.line,
|
15
|
+
sprintf(MSG, var, var))
|
16
|
+
end
|
17
17
|
end
|
18
|
+
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def var_nodes(nodes)
|
25
|
+
nodes.select { |n| [:ivar, :cvar, :gvar, :nth_ref].include?(n.type) }
|
18
26
|
end
|
19
27
|
end
|
20
28
|
end
|
@@ -3,25 +3,14 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class WhenThen < Cop
|
6
|
-
|
6
|
+
MSG = 'Never use "when x;". Use "when x then" instead.'
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
# when <value> <divider> <body>
|
12
|
-
# where divider is either semicolon, then, or line break.
|
13
|
-
last_pos_in_value = all_positions(s[1])[-1]
|
14
|
-
|
15
|
-
next unless last_pos_in_value # Give up if no positions found.
|
16
|
-
|
17
|
-
start_index = tokens.index { |t| t.pos == last_pos_in_value }
|
18
|
-
tokens[start_index..-1].each do |t|
|
19
|
-
break if ['then', "\n"].include?(t.text)
|
20
|
-
if t.type == :on_semicolon
|
21
|
-
add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
|
22
|
-
end
|
23
|
-
end
|
8
|
+
def on_when(node)
|
9
|
+
if node.loc.begin && node.loc.begin.source == ';'
|
10
|
+
add_offence(:convention, node.loc.line, MSG)
|
24
11
|
end
|
12
|
+
|
13
|
+
super
|
25
14
|
end
|
26
15
|
end
|
27
16
|
end
|
@@ -3,35 +3,34 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class WordArray < Cop
|
6
|
-
|
6
|
+
MSG = 'Use %w or %W for array of words.'
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
array_elems = s[1]
|
8
|
+
def on_array(node)
|
9
|
+
return unless node.loc.begin && node.loc.begin.source == '['
|
11
10
|
|
12
|
-
|
13
|
-
next unless array_elems && array_elems.size > 1
|
11
|
+
array_elems = node.children
|
14
12
|
|
15
|
-
|
13
|
+
# no need to check empty arrays
|
14
|
+
return unless array_elems && array_elems.size > 1
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
string_array = array_elems.all? { |e| e.type == :str }
|
17
|
+
|
18
|
+
if string_array && !complex_content?(array_elems)
|
19
|
+
add_offence(:convention, node.loc.line, MSG)
|
22
20
|
end
|
21
|
+
|
22
|
+
super
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
non_empty_strings = 0
|
25
|
+
private
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def complex_content?(arr_sexp)
|
28
|
+
arr_sexp.each do |s|
|
29
|
+
str_content = Util.strip_quotes(s.loc.expression.source)
|
30
|
+
return true unless str_content =~ /\A[\w-]+\z/
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
non_empty_strings == arr_sexp.size ? false : true
|
33
|
+
false
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|