rubocop 0.4.0 → 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 +7 -0
- data/.gitignore +50 -0
- data/.rubocop.yml +5 -127
- data/.travis.yml +7 -1
- data/CHANGELOG.md +157 -0
- data/CONTRIBUTING.md +13 -6
- data/Gemfile +3 -8
- data/README.md +160 -9
- data/Rakefile +3 -17
- data/bin/rubocop +16 -10
- data/config/default.yml +46 -0
- data/config/disabled.yml +5 -0
- data/config/enabled.yml +322 -0
- data/lib/rubocop/cli.rb +248 -93
- data/lib/rubocop/config.rb +205 -0
- data/lib/rubocop/config_store.rb +37 -0
- data/lib/rubocop/cop/access_control.rb +41 -0
- data/lib/rubocop/cop/alias.rb +17 -0
- data/lib/rubocop/cop/align_parameters.rb +20 -95
- data/lib/rubocop/cop/and_or.rb +26 -0
- data/lib/rubocop/cop/ascii_comments.rb +13 -0
- data/lib/rubocop/cop/ascii_identifiers.rb +19 -0
- data/lib/rubocop/cop/avoid_class_vars.rb +15 -0
- data/lib/rubocop/cop/avoid_for.rb +17 -0
- data/lib/rubocop/cop/avoid_global_vars.rb +61 -0
- data/lib/rubocop/cop/avoid_perl_backrefs.rb +17 -0
- data/lib/rubocop/cop/avoid_perlisms.rb +47 -0
- data/lib/rubocop/cop/block_comments.rb +15 -0
- data/lib/rubocop/cop/blocks.rb +11 -47
- data/lib/rubocop/cop/case_indentation.rb +22 -0
- data/lib/rubocop/cop/class_and_module_camel_case.rb +20 -11
- data/lib/rubocop/cop/class_methods.rb +15 -0
- data/lib/rubocop/cop/collection_methods.rb +16 -16
- data/lib/rubocop/cop/colon_method_call.rb +20 -0
- data/lib/rubocop/cop/constant_name.rb +24 -0
- data/lib/rubocop/cop/cop.rb +34 -47
- data/lib/rubocop/cop/def_parentheses.rb +43 -35
- data/lib/rubocop/cop/empty_line_between_defs.rb +22 -0
- data/lib/rubocop/cop/empty_lines.rb +21 -13
- 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 +19 -0
- data/lib/rubocop/cop/eval.rb +19 -0
- data/lib/rubocop/cop/favor_join.rb +22 -0
- data/lib/rubocop/cop/favor_modifier.rb +38 -48
- data/lib/rubocop/cop/favor_percent_r.rb +19 -0
- data/lib/rubocop/cop/favor_sprintf.rb +21 -0
- data/lib/rubocop/cop/favor_unless_over_negated_if.rb +19 -17
- data/lib/rubocop/cop/handle_exceptions.rb +17 -0
- 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 +17 -0
- data/lib/rubocop/cop/line_continuation.rb +15 -0
- data/lib/rubocop/cop/line_length.rb +4 -4
- data/lib/rubocop/cop/loop.rb +33 -0
- data/lib/rubocop/cop/method_and_variable_snake_case.rb +41 -17
- data/lib/rubocop/cop/method_length.rb +52 -0
- data/lib/rubocop/cop/new_lambda_literal.rb +8 -6
- data/lib/rubocop/cop/not.rb +21 -0
- data/lib/rubocop/cop/numeric_literals.rb +9 -7
- data/lib/rubocop/cop/offence.rb +12 -1
- data/lib/rubocop/cop/op_method.rb +26 -0
- 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 +19 -0
- data/lib/rubocop/cop/reduce_arguments.rb +29 -0
- data/lib/rubocop/cop/rescue_exception.rb +26 -0
- data/lib/rubocop/cop/rescue_modifier.rb +17 -0
- data/lib/rubocop/cop/semicolon.rb +31 -0
- data/lib/rubocop/cop/single_line_methods.rb +44 -0
- data/lib/rubocop/cop/space_after_comma_etc.rb +30 -10
- data/lib/rubocop/cop/space_after_control_keyword.rb +29 -0
- data/lib/rubocop/cop/string_literals.rb +9 -23
- data/lib/rubocop/cop/surrounding_space.rb +223 -83
- data/lib/rubocop/cop/symbol_array.rb +31 -0
- data/lib/rubocop/cop/symbol_name.rb +23 -0
- data/lib/rubocop/cop/syntax.rb +35 -5
- 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 +26 -0
- data/lib/rubocop/cop/unless_else.rb +11 -7
- data/lib/rubocop/cop/util.rb +26 -0
- data/lib/rubocop/cop/variable_interpolation.rb +29 -0
- data/lib/rubocop/cop/when_then.rb +6 -14
- data/lib/rubocop/cop/word_array.rb +37 -0
- data/lib/rubocop/report/emacs_style.rb +2 -2
- data/lib/rubocop/report/plain_text.rb +1 -1
- data/lib/rubocop/version.rb +3 -1
- data/lib/rubocop.rb +48 -8
- data/rubocop.gemspec +32 -151
- data/spec/project_spec.rb +27 -0
- data/spec/rubocop/cli_spec.rb +573 -200
- data/spec/rubocop/config_spec.rb +409 -0
- data/spec/rubocop/config_store_spec.rb +66 -0
- data/spec/rubocop/cops/access_control_spec.rb +129 -0
- data/spec/rubocop/cops/alias_spec.rb +39 -0
- data/spec/rubocop/cops/align_parameters_spec.rb +66 -70
- data/spec/rubocop/cops/and_or_spec.rb +37 -0
- data/spec/rubocop/cops/ascii_comments_spec.rb +26 -0
- data/spec/rubocop/cops/ascii_identifiers_spec.rb +26 -0
- data/spec/rubocop/cops/avoid_class_vars_spec.rb +25 -0
- data/spec/rubocop/cops/avoid_for_spec.rb +35 -0
- data/spec/rubocop/cops/avoid_global_vars_spec.rb +32 -0
- data/spec/rubocop/cops/avoid_perl_backrefs_spec.rb +18 -0
- data/spec/rubocop/cops/avoid_perlisms_spec.rb +44 -0
- data/spec/rubocop/cops/block_comments_spec.rb +25 -0
- data/spec/rubocop/cops/blocks_spec.rb +33 -0
- data/spec/rubocop/cops/{indentation_spec.rb → case_indentation_spec.rb} +7 -7
- data/spec/rubocop/cops/class_and_module_camel_case_spec.rb +15 -5
- data/spec/rubocop/cops/class_methods_spec.rb +49 -0
- data/spec/rubocop/cops/collection_methods_spec.rb +9 -4
- data/spec/rubocop/cops/colon_method_call_spec.rb +53 -0
- 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 +83 -0
- data/spec/rubocop/cops/empty_lines_spec.rb +14 -59
- data/spec/rubocop/cops/empty_literal_spec.rb +90 -0
- data/spec/rubocop/cops/encoding_spec.rb +11 -11
- data/spec/rubocop/cops/end_of_line_spec.rb +2 -2
- data/spec/rubocop/cops/ensure_return_spec.rb +35 -0
- data/spec/rubocop/cops/eval_spec.rb +39 -0
- data/spec/rubocop/cops/favor_join_spec.rb +35 -0
- data/spec/rubocop/cops/favor_modifier_spec.rb +16 -14
- data/spec/rubocop/cops/favor_percent_r_spec.rb +29 -0
- data/spec/rubocop/cops/favor_sprintf_spec.rb +51 -0
- 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 +34 -0
- 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 +54 -0
- data/spec/rubocop/cops/line_continuation_spec.rb +24 -0
- data/spec/rubocop/cops/line_length_spec.rb +3 -2
- data/spec/rubocop/cops/loop_spec.rb +31 -0
- data/spec/rubocop/cops/method_and_variable_snake_case_spec.rb +55 -9
- data/spec/rubocop/cops/method_length_spec.rb +147 -0
- data/spec/rubocop/cops/multiline_if_then_spec.rb +15 -15
- data/spec/rubocop/cops/new_lambda_literal_spec.rb +5 -6
- data/spec/rubocop/cops/not_spec.rb +31 -0
- data/spec/rubocop/cops/numeric_literals_spec.rb +13 -13
- data/spec/rubocop/cops/offence_spec.rb +13 -0
- data/spec/rubocop/cops/one_line_conditional_spec.rb +1 -1
- data/spec/rubocop/cops/op_method_spec.rb +78 -0
- 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 +29 -0
- data/spec/rubocop/cops/reduce_arguments_spec.rb +57 -0
- data/spec/rubocop/cops/rescue_exception_spec.rb +125 -0
- data/spec/rubocop/cops/rescue_modifier_spec.rb +37 -0
- data/spec/rubocop/cops/semicolon_spec.rb +88 -0
- data/spec/rubocop/cops/single_line_methods_spec.rb +50 -0
- 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 +67 -0
- data/spec/rubocop/cops/space_after_semicolon_spec.rb +6 -1
- data/spec/rubocop/cops/space_around_braces_spec.rb +18 -3
- data/spec/rubocop/cops/space_around_equals_in_default_parameter_spec.rb +12 -2
- data/spec/rubocop/cops/space_around_operators_spec.rb +88 -26
- data/spec/rubocop/cops/space_inside_brackets_spec.rb +13 -7
- data/spec/rubocop/cops/space_inside_hash_literal_braces_spec.rb +79 -0
- data/spec/rubocop/cops/space_inside_parens_spec.rb +7 -3
- data/spec/rubocop/cops/string_literals_spec.rb +21 -6
- data/spec/rubocop/cops/symbol_array_spec.rb +41 -0
- data/spec/rubocop/cops/symbol_name_spec.rb +119 -0
- data/spec/rubocop/cops/syntax_spec.rb +28 -5
- 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 +329 -0
- data/spec/rubocop/cops/unless_else_spec.rb +8 -8
- data/spec/rubocop/cops/variable_interpolation_spec.rb +49 -0
- data/spec/rubocop/cops/when_then_spec.rb +14 -14
- data/spec/rubocop/cops/word_array_spec.rb +47 -0
- data/spec/spec_helper.rb +30 -9
- data/spec/support/file_helper.rb +21 -0
- data/spec/support/isolated_environment.rb +27 -0
- metadata +235 -76
- data/.document +0 -5
- data/Gemfile.lock +0 -41
- data/VERSION +0 -1
- data/lib/rubocop/cop/ampersands_pipes_vs_and_or.rb +0 -25
- data/lib/rubocop/cop/grammar.rb +0 -135
- data/lib/rubocop/cop/indentation.rb +0 -44
- data/spec/rubocop/cops/ampersands_pipes_vs_and_or_spec.rb +0 -57
- data/spec/rubocop/cops/grammar_spec.rb +0 -71
- data/spec/rubocop/cops/multiline_blocks_spec.rb +0 -24
- data/spec/rubocop/cops/single_line_blocks_spec.rb +0 -22
data/lib/rubocop/cop/cop.rb
CHANGED
@@ -2,37 +2,24 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
class Position < Struct.new :lineno, :column
|
6
|
-
# Does a recursive search and replaces each [lineno, column] array
|
7
|
-
# in the sexp with a Position object.
|
8
|
-
def self.make_position_objects(sexp)
|
9
|
-
if sexp[0] =~ /^@/
|
10
|
-
sexp[2] = Position.new(*sexp[2])
|
11
|
-
else
|
12
|
-
sexp.grep(Array).each { |s| make_position_objects(s) }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# The point of this class is to provide named attribute access.
|
17
|
-
# So we don't want backwards compatibility with array indexing.
|
18
|
-
undef_method :[]
|
19
|
-
end
|
20
|
-
|
21
5
|
class Token
|
22
6
|
attr_reader :pos, :type, :text
|
23
7
|
|
24
8
|
def initialize(pos, type, text)
|
25
|
-
@pos, @type, @text =
|
9
|
+
@pos, @type, @text = pos, type, text
|
26
10
|
end
|
27
11
|
|
28
12
|
def to_s
|
29
|
-
"[[#{@pos.
|
13
|
+
"[[#{@pos.line}, #{@pos.column}], #{@type}, #{@text.inspect}]"
|
30
14
|
end
|
31
15
|
end
|
32
16
|
|
33
|
-
class Cop
|
17
|
+
class Cop < Parser::AST::Processor
|
18
|
+
extend AST::Sexp
|
19
|
+
|
34
20
|
attr_accessor :offences
|
35
|
-
|
21
|
+
attr_accessor :debug
|
22
|
+
attr_writer :disabled_lines
|
36
23
|
|
37
24
|
@all = []
|
38
25
|
@config = {}
|
@@ -46,50 +33,50 @@ module Rubocop
|
|
46
33
|
all << subclass
|
47
34
|
end
|
48
35
|
|
36
|
+
def self.cop_name
|
37
|
+
name.to_s.split('::').last
|
38
|
+
end
|
39
|
+
|
49
40
|
def initialize
|
50
41
|
@offences = []
|
42
|
+
@debug = false
|
51
43
|
end
|
52
44
|
|
53
45
|
def has_report?
|
54
46
|
!@offences.empty?
|
55
47
|
end
|
56
48
|
|
57
|
-
def
|
58
|
-
|
49
|
+
def inspect(source, tokens, ast, comments)
|
50
|
+
process(ast)
|
51
|
+
comments.each { |c| on_comment(c) }
|
59
52
|
end
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
def each_parent_of(sym, sexp)
|
64
|
-
parents = []
|
65
|
-
sexp.each do |elem|
|
66
|
-
if Array === elem
|
67
|
-
if elem[0] == sym
|
68
|
-
parents << sexp unless parents.include?(sexp)
|
69
|
-
elem = elem[1..-1]
|
70
|
-
end
|
71
|
-
each_parent_of(sym, elem) do |parent|
|
72
|
-
parents << parent unless parents.include?(parent)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
parents.each { |parent| yield parent }
|
54
|
+
def on_comment(comment)
|
77
55
|
end
|
78
56
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
57
|
+
def add_offence(severity, line_number, message)
|
58
|
+
unless @disabled_lines && @disabled_lines.include?(line_number)
|
59
|
+
message = debug ? "#{name}: #{message}" : message
|
60
|
+
@offences << Offence.new(severity, line_number, message)
|
83
61
|
end
|
84
62
|
end
|
85
63
|
|
86
|
-
def
|
87
|
-
|
64
|
+
def name
|
65
|
+
self.class.cop_name
|
88
66
|
end
|
89
67
|
|
90
|
-
|
91
|
-
|
92
|
-
|
68
|
+
private
|
69
|
+
|
70
|
+
def on_node(syms, sexp, excludes = [])
|
71
|
+
yield sexp if Array(syms).include?(sexp.type)
|
72
|
+
|
73
|
+
return if Array(excludes).include?(sexp.type)
|
74
|
+
|
75
|
+
sexp.children.each do |elem|
|
76
|
+
if Parser::AST::Node === elem
|
77
|
+
on_node(syms, elem, excludes) { |s| yield s }
|
78
|
+
end
|
79
|
+
end
|
93
80
|
end
|
94
81
|
end
|
95
82
|
end
|
@@ -2,52 +2,60 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
module DefParentheses
|
6
|
-
EMPTY_PARAMS = [:params, nil, nil, nil,
|
7
|
-
nil, nil, nil, nil] if RUBY_VERSION >= '2.0.0'
|
8
|
-
EMPTY_PARAMS = [:params, nil, nil, nil,
|
9
|
-
nil, nil] if RUBY_VERSION < '2.0.0'
|
10
|
-
|
11
|
-
def inspect(file, source, tokens, sexp)
|
12
|
-
each(:def, sexp) { |def_sexp| check(tokens, def_sexp) }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
5
|
class DefWithParentheses < Cop
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
6
|
+
MSG = "Omit the parentheses in defs when the method doesn't accept " +
|
7
|
+
'any arguments.'
|
8
|
+
|
9
|
+
def on_def(node)
|
10
|
+
start_line = node.loc.keyword.line
|
11
|
+
end_line = node.loc.end.line
|
12
|
+
|
13
|
+
return if start_line == end_line
|
14
|
+
|
15
|
+
_, args = *node
|
16
|
+
if args.children == [] && args.loc.begin
|
17
|
+
add_offence(:convention, node.loc.line, MSG)
|
18
|
+
end
|
19
|
+
|
20
|
+
super
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if first_body_token.pos.lineno > pos.lineno
|
33
|
-
# Only report offence if there's a line break after
|
34
|
-
# the empty parens.
|
35
|
-
add_offence(:convention, pos.lineno, error_message)
|
36
|
-
end
|
23
|
+
def on_defs(node)
|
24
|
+
start_line = node.loc.keyword.line
|
25
|
+
end_line = node.loc.end.line
|
26
|
+
|
27
|
+
return if start_line == end_line
|
28
|
+
|
29
|
+
_, _, args = *node
|
30
|
+
if args.children == [] && args.loc.begin
|
31
|
+
add_offence(:convention, node.loc.line, MSG)
|
37
32
|
end
|
33
|
+
|
34
|
+
super
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
41
38
|
class DefWithoutParentheses < Cop
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
MSG = 'Use def with parentheses when there are arguments.'
|
40
|
+
|
41
|
+
def on_def(node)
|
42
|
+
_, args = *node
|
43
|
+
|
44
|
+
if args.children.size > 0 && args.loc.begin.nil?
|
45
|
+
add_offence(:convention, node.loc.line, MSG)
|
46
|
+
end
|
47
|
+
|
48
|
+
super
|
45
49
|
end
|
46
50
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
51
|
+
def on_defs(node)
|
52
|
+
_, _, args = *node
|
53
|
+
|
54
|
+
if args.children.size > 0 && args.loc.begin.nil?
|
55
|
+
add_offence(:convention, node.loc.line, MSG)
|
50
56
|
end
|
57
|
+
|
58
|
+
super
|
51
59
|
end
|
52
60
|
end
|
53
61
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class EmptyLineBetweenDefs < Cop
|
6
|
+
MSG = 'Use empty lines between defs.'
|
7
|
+
|
8
|
+
def on_def(s)
|
9
|
+
def_start = s.loc.keyword.line
|
10
|
+
def_end = s.loc.end.line
|
11
|
+
|
12
|
+
if @prev_def_end && (def_start - @prev_def_end) < 2
|
13
|
+
add_offence(:convention, def_start, MSG)
|
14
|
+
end
|
15
|
+
|
16
|
+
@prev_def_end = def_end
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -3,22 +3,30 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class EmptyLines < Cop
|
6
|
-
|
6
|
+
MSG = 'Extra blank line detected.'
|
7
|
+
LINE_OFFSET = 2
|
7
8
|
|
8
|
-
def inspect(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
def inspect(source, tokens, ast, comments)
|
10
|
+
return if tokens.empty?
|
11
|
+
|
12
|
+
prev_line = 1
|
13
|
+
|
14
|
+
tokens.each do |token|
|
15
|
+
cur_line = token.pos.line
|
16
|
+
line_diff = cur_line - prev_line
|
17
|
+
|
18
|
+
if line_diff > LINE_OFFSET
|
19
|
+
# we need to be wary of comments since they
|
20
|
+
# don't show up in the tokens
|
21
|
+
((prev_line + 1)...cur_line).each do |line|
|
22
|
+
# we check if the prev and current lines are empty
|
23
|
+
if source[line - 2].empty? && source[line - 1].empty?
|
24
|
+
add_offence(:convention, line, MSG)
|
25
|
+
end
|
19
26
|
end
|
20
|
-
current_row_ix = next_row_ix
|
21
27
|
end
|
28
|
+
|
29
|
+
prev_line = cur_line
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class EmptyLiteral < Cop
|
6
|
+
ARR_MSG = 'Use array literal [] instead of Array.new.'
|
7
|
+
HASH_MSG = 'Use hash literal {} instead of Hash.new.'
|
8
|
+
STR_MSG = "Use string literal '' instead of String.new."
|
9
|
+
|
10
|
+
# Empty array node
|
11
|
+
#
|
12
|
+
# (send
|
13
|
+
# (const nil :Array) :new)
|
14
|
+
ARRAY_NODE = s(:send, s(:const, nil, :Array), :new)
|
15
|
+
|
16
|
+
# Empty hash node
|
17
|
+
#
|
18
|
+
# (send
|
19
|
+
# (const nil :Hash) :new)
|
20
|
+
HASH_NODE = s(:send, s(:const, nil, :Hash), :new)
|
21
|
+
|
22
|
+
# Empty string node
|
23
|
+
#
|
24
|
+
# (send
|
25
|
+
# (const nil :String) :new)
|
26
|
+
STR_NODE = s(:send, s(:const, nil, :String), :new)
|
27
|
+
|
28
|
+
def inspect(source, tokens, ast, comments)
|
29
|
+
on_node(:send, ast, :block) do |node|
|
30
|
+
if node == ARRAY_NODE
|
31
|
+
add_offence(:convention,
|
32
|
+
node.loc.line,
|
33
|
+
ARR_MSG)
|
34
|
+
elsif node == HASH_NODE
|
35
|
+
add_offence(:convention,
|
36
|
+
node.loc.line,
|
37
|
+
HASH_MSG)
|
38
|
+
elsif node == STR_NODE
|
39
|
+
add_offence(:convention,
|
40
|
+
node.loc.line,
|
41
|
+
STR_MSG)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/rubocop/cop/encoding.rb
CHANGED
@@ -3,14 +3,14 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class Encoding < Cop
|
6
|
-
|
6
|
+
MSG = 'Missing utf-8 encoding comment.'
|
7
7
|
|
8
|
-
def inspect(
|
8
|
+
def inspect(source, tokens, ast, comments)
|
9
9
|
unless RUBY_VERSION >= '2.0.0'
|
10
10
|
expected_line = 0
|
11
11
|
expected_line += 1 if source[expected_line] =~ /^#!/
|
12
12
|
unless source[expected_line] =~ /#.*coding: (UTF|utf)-8/
|
13
|
-
add_offence(:convention, 1,
|
13
|
+
add_offence(:convention, 1, MSG)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class EndOfLine < Cop
|
6
|
-
|
6
|
+
MSG = 'Carriage return character 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 =~ /\r$/
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class EnsureReturn < Cop
|
6
|
+
MSG = 'Never return from an ensure block.'
|
7
|
+
|
8
|
+
def on_ensure(node)
|
9
|
+
_body, ensure_body = *node
|
10
|
+
|
11
|
+
on_node(:return, ensure_body) do |e|
|
12
|
+
add_offence(:warning, e.loc.line, MSG)
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class Eval < Cop
|
6
|
+
MSG = 'The use of eval is a serious security risk.'
|
7
|
+
|
8
|
+
def on_send(node)
|
9
|
+
receiver, method_name, = *node
|
10
|
+
|
11
|
+
if receiver.nil? && method_name == :eval
|
12
|
+
add_offence(:security, node.loc.line, MSG)
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class FavorJoin < Cop
|
6
|
+
MSG = 'Favor Array#join over Array#*.'
|
7
|
+
|
8
|
+
def on_send(node)
|
9
|
+
receiver_node, method_name, *arg_nodes = *node
|
10
|
+
|
11
|
+
if receiver_node && receiver_node.type == :array &&
|
12
|
+
method_name == :* && arg_nodes[0].type == :str
|
13
|
+
add_offence(:convention,
|
14
|
+
node.loc.expression.line,
|
15
|
+
MSG)
|
16
|
+
end
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -3,53 +3,36 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module FavorModifier
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# If it contains an else, it can't be written as a modifier.
|
11
|
-
next if s[3] && s[3][0] == :else
|
6
|
+
# TODO extremely ugly solution that needs lots of polish
|
7
|
+
def check(sexp)
|
8
|
+
# discard if/then/else
|
9
|
+
return false if sexp.loc.respond_to?(:else) && sexp.loc.else
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
if %w(if while).include?(sexp.loc.keyword.source)
|
12
|
+
cond, body = *sexp
|
13
|
+
else
|
14
|
+
cond, _else, body = *sexp
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
if length(sexp) > 3
|
18
|
+
false
|
19
|
+
else
|
20
|
+
cond_length = sexp.loc.keyword.size + cond.loc.expression.size + 1
|
21
|
+
body_length = body_length(body)
|
24
22
|
|
25
|
-
|
26
|
-
next # not a single-line body
|
27
|
-
end
|
28
|
-
# The start ix is the index of the leftmost token on the
|
29
|
-
# line of the if/unless, i.e. the index of if/unless itself,
|
30
|
-
# or of the indentation space.
|
31
|
-
start_ix = if_ix.downto(0).find do |block_ix|
|
32
|
-
block_ix == 0 || tokens[block_ix - 1].text =~ /\n/
|
33
|
-
end
|
34
|
-
# The stop index is the index of the token just before
|
35
|
-
# 'end', not counting whitespace tokens.
|
36
|
-
stop_ix = (end_ix - 1).downto(0).find do |block_ix|
|
37
|
-
tokens[block_ix].text !~ /\s/
|
38
|
-
end
|
39
|
-
if length(tokens, start_ix, stop_ix) <= LineLength.max
|
40
|
-
add_offence(:convention, token_positions[if_ix].lineno,
|
41
|
-
error_message)
|
42
|
-
end
|
23
|
+
(cond_length + body_length) <= LineLength.max
|
43
24
|
end
|
44
25
|
end
|
45
26
|
|
46
|
-
def length(
|
47
|
-
(
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
27
|
+
def length(sexp)
|
28
|
+
sexp.loc.expression.source.split("\n").size
|
29
|
+
end
|
30
|
+
|
31
|
+
def body_length(body)
|
32
|
+
if body
|
33
|
+
body.loc.expression.column + body.loc.expression.size
|
34
|
+
else
|
35
|
+
0
|
53
36
|
end
|
54
37
|
end
|
55
38
|
end
|
@@ -59,23 +42,30 @@ module Rubocop
|
|
59
42
|
|
60
43
|
def error_message
|
61
44
|
'Favor modifier if/unless usage when you have a single-line body. ' +
|
62
|
-
'Another good alternative is the usage of control flow
|
45
|
+
'Another good alternative is the usage of control flow &&/||.'
|
63
46
|
end
|
64
47
|
|
65
|
-
def
|
66
|
-
|
48
|
+
def on_if(node)
|
49
|
+
# discard ternary ops and modifier if/unless nodes
|
50
|
+
return unless node.loc.respond_to?(:keyword) &&
|
51
|
+
node.loc.respond_to?(:else)
|
52
|
+
|
53
|
+
add_offence(:convention, node.loc.line, error_message) if check(node)
|
54
|
+
|
55
|
+
super
|
67
56
|
end
|
68
57
|
end
|
69
58
|
|
70
59
|
class WhileUntilModifier < Cop
|
71
60
|
include FavorModifier
|
72
61
|
|
73
|
-
|
62
|
+
MSG =
|
74
63
|
'Favor modifier while/until usage when you have a single-line body.'
|
75
|
-
end
|
76
64
|
|
77
|
-
def inspect(
|
78
|
-
[:while, :until]
|
65
|
+
def inspect(source, tokens, ast, comments)
|
66
|
+
on_node([:while, :until], ast) do |node|
|
67
|
+
add_offence(:convention, node.loc.line, MSG) if check(node)
|
68
|
+
end
|
79
69
|
end
|
80
70
|
end
|
81
71
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class FavorPercentR < Cop
|
6
|
+
MSG = 'Use %r for regular expressions matching more ' +
|
7
|
+
"than one '/' character."
|
8
|
+
|
9
|
+
def on_regexp(node)
|
10
|
+
if node.loc.begin.source == '/' &&
|
11
|
+
node.loc.expression.source[1...-1].scan(/\//).size > 1
|
12
|
+
add_offence(:convention, node.loc.line, MSG)
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class FavorSprintf < Cop
|
6
|
+
MSG = 'Favor sprintf over String#%.'
|
7
|
+
|
8
|
+
def on_send(node)
|
9
|
+
receiver_node, method_name, *arg_nodes = *node
|
10
|
+
|
11
|
+
if method_name == :% &&
|
12
|
+
([:str, :dstr].include?(receiver_node.type) ||
|
13
|
+
arg_nodes[0].type == :array)
|
14
|
+
add_offence(:convention, node.loc.expression.line, MSG)
|
15
|
+
end
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,17 +3,17 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module FavorOtherKeywordOverNegation
|
6
|
-
|
7
|
-
|
8
|
-
each(grammar_part, sexp) do |s|
|
9
|
-
# Don't complain about negative if/else. We don't want unless/else.
|
10
|
-
next if s[3] && [:else, :elsif].include?(s[3][0])
|
6
|
+
def check(node)
|
7
|
+
condition, _body, _rest = *node
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
# Look at last expression of contents if there's a parenthesis
|
10
|
+
# around condition.
|
11
|
+
*_, condition = *condition while condition.type == :begin
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
if condition.type == :send
|
14
|
+
_object, method = *condition
|
15
|
+
if method == :! && !(node.loc.respond_to?(:else) && node.loc.else)
|
16
|
+
add_offence(:convention, node.loc.expression.line,
|
17
17
|
error_message)
|
18
18
|
end
|
19
19
|
end
|
@@ -23,24 +23,26 @@ module Rubocop
|
|
23
23
|
class FavorUnlessOverNegatedIf < Cop
|
24
24
|
include FavorOtherKeywordOverNegation
|
25
25
|
|
26
|
-
def
|
27
|
-
|
26
|
+
def on_if(node)
|
27
|
+
check(node)
|
28
|
+
super
|
28
29
|
end
|
29
30
|
|
30
|
-
def
|
31
|
-
|
31
|
+
def error_message
|
32
|
+
'Favor unless (or control flow or) over if for negative conditions.'
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
36
|
class FavorUntilOverNegatedWhile < Cop
|
36
37
|
include FavorOtherKeywordOverNegation
|
37
38
|
|
38
|
-
def
|
39
|
-
|
39
|
+
def on_while(node)
|
40
|
+
check(node)
|
41
|
+
super
|
40
42
|
end
|
41
43
|
|
42
|
-
def
|
43
|
-
|
44
|
+
def error_message
|
45
|
+
'Favor until over while for negative conditions.'
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class HandleExceptions < Cop
|
6
|
+
MSG = 'Do not suppress exceptions.'
|
7
|
+
|
8
|
+
def on_resbody(node)
|
9
|
+
_exc_list_node, _exc_var_node, body_node = *node
|
10
|
+
|
11
|
+
add_offence(:warning, node.loc.line, MSG) if body_node.type == :nil
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|