rubocop 0.9.0 → 0.9.1
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 +23 -0
- data/README.md +1 -0
- data/config/default.yml +12 -0
- data/config/enabled.yml +0 -1
- data/lib/rubocop.rb +3 -0
- data/lib/rubocop/cli.rb +7 -1
- data/lib/rubocop/cop/cop.rb +20 -5
- data/lib/rubocop/cop/lint/end_alignment.rb +51 -42
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_condition.rb +59 -9
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
- data/lib/rubocop/cop/rails/validation.rb +0 -4
- data/lib/rubocop/cop/style/collection_methods.rb +28 -10
- data/lib/rubocop/cop/style/dot_position.rb +14 -4
- data/lib/rubocop/cop/style/if_then_else.rb +0 -51
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +47 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +20 -0
- data/lib/rubocop/cop/style/op_method.rb +16 -14
- data/lib/rubocop/cop/util.rb +4 -0
- data/lib/rubocop/cop/variable_inspector.rb +32 -13
- data/lib/rubocop/version.rb +1 -1
- data/rubocop.gemspec +1 -1
- data/spec/rubocop/cli_spec.rb +21 -0
- data/spec/rubocop/cops/lint/end_alignment_spec.rb +206 -299
- data/spec/rubocop/cops/lint/ensure_return_spec.rb +11 -0
- data/spec/rubocop/cops/lint/literal_in_condition_spec.rb +37 -3
- data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +63 -0
- data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +68 -0
- data/spec/rubocop/cops/offence_spec.rb +2 -2
- data/spec/rubocop/cops/style/collection_methods_spec.rb +32 -28
- data/spec/rubocop/cops/style/dot_position_spec.rb +46 -11
- data/spec/rubocop/cops/style/multiline_if_then_spec.rb +16 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ad204405cb1d04fa810d54f45d8b01725f3fb1c
|
4
|
+
data.tar.gz: 1240e7d221d6ae7e05ec4dc59bcc633afa96c3cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c8a7da40e56a46adb7a668379062a17fcf978a6df0d7c975b911e0aa1ff700ae38365aab8b1a0dbad0a70c2f2c05b461f5c49ca3c36ebc8825d04d654c90eb0
|
7
|
+
data.tar.gz: a180b2850a1946a6fb9b693be6ebe04ae3930fad2b1d341bbb2791347a2c32872a21ca518c277331fc3136c0e483070ea70717f46fd5f54fb426cda27b6dd373
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
## 0.9.1 (05/07/2013)
|
6
|
+
|
7
|
+
### New features
|
8
|
+
|
9
|
+
* Added `-l/--lint` option to allow doing only linting with no style checks (similar to running `ruby -wc`).
|
10
|
+
|
11
|
+
### Changes
|
12
|
+
|
13
|
+
* Removed the `BlockAlignSchema` configuration option from `EndAlignment`. We now support only the default alignment schema - `StartOfAssignment`.
|
14
|
+
* Made the preferred collection methods in `CollectionMethods` configurable.
|
15
|
+
* Made the `DotPosition` cop configurable - now both `leading` and `trailing` styles are supported.
|
16
|
+
|
17
|
+
### Bugs fixed
|
18
|
+
|
19
|
+
* [#318](https://github.com/bbatsov/rubocop/issues/318) - correct some special cases of block end alignment
|
20
|
+
* [#317](https://github.com/bbatsov/rubocop/issues/317) - fix a false positive in `LiteralInCondition`
|
21
|
+
* [#321](https://github.com/bbatsov/rubocop/issues/321) - Ignore variables whose name start with `_` in `ShadowingOuterLocalVariable`
|
22
|
+
* [#322](https://github.com/bbatsov/rubocop/issues/322) - Fix exception of `UnusedLocalVariable` and `ShadowingOuterLocalVariable` when inspecting keyword splat argument
|
23
|
+
* [#316](https://github.com/bbatsov/rubocop/issues/316) - Correct nested postfix unless in `MultilineIfThen`
|
24
|
+
* [#327](https://github.com/bbatsov/rubocop/issues/327) - Fix false offences for block expression that span on two lines in `EndAlignment`
|
25
|
+
* [#332](https://github.com/bbatsov/rubocop/issues/332) - Fix exception of `UnusedLocalVariable` and `ShadowingOuterLocalVariable` when inspecting named captures
|
26
|
+
* [#333](https://github.com/bbatsov/rubocop/issues/333) - Fix a case that `EnsureReturn` throws an exception when ensure has no body
|
27
|
+
|
5
28
|
## 0.9.0 (01/07/2013)
|
6
29
|
|
7
30
|
### New features
|
data/README.md
CHANGED
@@ -49,6 +49,7 @@ Command flag | Description
|
|
49
49
|
`-o/--out` | Write output to a file instead of STDOUT
|
50
50
|
`-r/--require` | Require Ruby file
|
51
51
|
`-R/--rails` | Run extra Rails cops
|
52
|
+
`-l/--lint` | Run only lint cops
|
52
53
|
`-a/--auto-correct` | Auto-correct certain offences.
|
53
54
|
`-s/--silent` | Suppress the final summary
|
54
55
|
`--only` | Run only the specified cop
|
data/config/default.yml
CHANGED
@@ -56,3 +56,15 @@ BlockNesting:
|
|
56
56
|
# character.
|
57
57
|
RegexpLiteral:
|
58
58
|
MaxSlashes: 1
|
59
|
+
|
60
|
+
# Align with the style guide.
|
61
|
+
CollectionMethods:
|
62
|
+
PreferredMethods:
|
63
|
+
collect: 'map'
|
64
|
+
inject: 'reduce'
|
65
|
+
detect: 'find'
|
66
|
+
find_all: 'select'
|
67
|
+
|
68
|
+
# Muli-line method chaining should be done with leading dots.
|
69
|
+
DotPosition:
|
70
|
+
Style: 'leading'
|
data/config/enabled.yml
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -63,6 +63,9 @@ require 'rubocop/cop/style/favor_sprintf'
|
|
63
63
|
require 'rubocop/cop/style/favor_unless_over_negated_if'
|
64
64
|
require 'rubocop/cop/style/hash_syntax'
|
65
65
|
require 'rubocop/cop/style/if_then_else'
|
66
|
+
require 'rubocop/cop/style/if_with_semicolon'
|
67
|
+
require 'rubocop/cop/style/multiline_if_then'
|
68
|
+
require 'rubocop/cop/style/one_line_conditional'
|
66
69
|
require 'rubocop/cop/style/lambda'
|
67
70
|
require 'rubocop/cop/style/leading_comment_space'
|
68
71
|
require 'rubocop/cop/style/line_continuation'
|
data/lib/rubocop/cli.rb
CHANGED
@@ -37,7 +37,10 @@ module Rubocop
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# filter out Rails cops unless requested
|
40
|
-
@cops.reject!
|
40
|
+
@cops.reject!(&:rails?) unless @options[:rails]
|
41
|
+
|
42
|
+
# filter out style cops when --lint is passed
|
43
|
+
@cops.select!(&:lint?) if @options[:lint]
|
41
44
|
|
42
45
|
target_files = target_files(args)
|
43
46
|
target_files.each(&:freeze).freeze
|
@@ -181,6 +184,9 @@ module Rubocop
|
|
181
184
|
opts.on('-R', '--rails', 'Run extra Rails cops.') do |r|
|
182
185
|
@options[:rails] = r
|
183
186
|
end
|
187
|
+
opts.on('-l', '--lint', 'Run only lint cops.') do |l|
|
188
|
+
@options[:lint] = l
|
189
|
+
end
|
184
190
|
opts.on('-a', '--auto-correct', 'Auto-correct offences.') do |a|
|
185
191
|
@options[:autocorrect] = a
|
186
192
|
end
|
data/lib/rubocop/cop/cop.rb
CHANGED
@@ -32,20 +32,35 @@ module Rubocop
|
|
32
32
|
@config = {}
|
33
33
|
|
34
34
|
class << self
|
35
|
-
attr_accessor :all
|
36
35
|
attr_accessor :config
|
37
36
|
end
|
38
37
|
|
38
|
+
def self.all
|
39
|
+
@all.clone
|
40
|
+
end
|
41
|
+
|
39
42
|
def self.inherited(subclass)
|
40
|
-
all << subclass
|
43
|
+
@all << subclass
|
41
44
|
end
|
42
45
|
|
43
46
|
def self.cop_name
|
44
47
|
name.to_s.split('::').last
|
45
48
|
end
|
46
49
|
|
50
|
+
def self.cop_type
|
51
|
+
name.to_s.split('::')[-2].downcase.to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.style?
|
55
|
+
cop_type == :style
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.lint?
|
59
|
+
cop_type == :lint
|
60
|
+
end
|
61
|
+
|
47
62
|
def self.rails?
|
48
|
-
|
63
|
+
cop_type == :rails
|
49
64
|
end
|
50
65
|
|
51
66
|
def initialize
|
@@ -116,8 +131,8 @@ module Rubocop
|
|
116
131
|
column_count)
|
117
132
|
newline_length = 1
|
118
133
|
begin_pos = preceding_lines.reduce(0) do |a, e|
|
119
|
-
|
120
|
-
|
134
|
+
a + e.length + newline_length
|
135
|
+
end + begin_column
|
121
136
|
Parser::Source::Range.new(source_buffer, begin_pos,
|
122
137
|
begin_pos + column_count)
|
123
138
|
end
|
@@ -5,23 +5,19 @@ module Rubocop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks whether the end keywords are aligned properly.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
8
|
+
# For keywords (if, def, etc.) the end is aligned with the start
|
9
|
+
# of the keyword.
|
10
|
+
# For blocks - with the start of the expression where the block
|
11
|
+
# is defined.
|
12
|
+
#
|
12
13
|
# @example
|
13
14
|
#
|
15
|
+
# variable = if true
|
16
|
+
# end
|
17
|
+
#
|
14
18
|
# variable = lambda do |i|
|
15
19
|
# i
|
16
20
|
# end
|
17
|
-
#
|
18
|
-
# Set BlockAlignSchema to StartOfBlockCommand if you want to
|
19
|
-
# align the end to the beginning of the expression that called the block.
|
20
|
-
# @example
|
21
|
-
#
|
22
|
-
# variable = lambda do |i|
|
23
|
-
# i
|
24
|
-
# end
|
25
21
|
class EndAlignment < Cop
|
26
22
|
MSG = 'end at %d, %d is not aligned with %s at %d, %d'
|
27
23
|
|
@@ -78,14 +74,25 @@ module Rubocop
|
|
78
74
|
super
|
79
75
|
end
|
80
76
|
|
81
|
-
def
|
82
|
-
if
|
83
|
-
|
84
|
-
|
77
|
+
def on_and(node)
|
78
|
+
return if already_processed_node?(node)
|
79
|
+
|
80
|
+
_left, right = *node
|
81
|
+
if right.type == :block
|
82
|
+
check_block_alignment(node.loc.expression, right.loc)
|
83
|
+
@inspected_blocks << right
|
85
84
|
end
|
86
85
|
super
|
87
86
|
end
|
88
87
|
|
88
|
+
alias_method :on_or, :on_and
|
89
|
+
|
90
|
+
def on_lvasgn(node)
|
91
|
+
_, children = *node
|
92
|
+
process_block_assignment(node, children)
|
93
|
+
super
|
94
|
+
end
|
95
|
+
|
89
96
|
alias_method :on_ivasgn, :on_lvasgn
|
90
97
|
alias_method :on_cvasgn, :on_lvasgn
|
91
98
|
alias_method :on_gvasgn, :on_lvasgn
|
@@ -93,43 +100,50 @@ module Rubocop
|
|
93
100
|
alias_method :on_or_asgn, :on_lvasgn
|
94
101
|
|
95
102
|
def on_casgn(node)
|
96
|
-
|
97
|
-
|
98
|
-
process_block_assignment(node, children)
|
99
|
-
end
|
103
|
+
_, _, children = *node
|
104
|
+
process_block_assignment(node, children)
|
100
105
|
super
|
101
106
|
end
|
102
107
|
|
103
108
|
def on_op_asgn(node)
|
104
|
-
|
105
|
-
|
106
|
-
process_block_assignment(variable, args)
|
107
|
-
end
|
109
|
+
variable, _op, args = *node
|
110
|
+
process_block_assignment(variable, args)
|
108
111
|
super
|
109
112
|
end
|
110
113
|
|
111
114
|
def on_send(node)
|
112
|
-
|
113
|
-
|
114
|
-
if attribute_writer?(method)
|
115
|
-
process_block_assignment(receiver, args)
|
116
|
-
end
|
117
|
-
end
|
115
|
+
_receiver, _method, *args = *node
|
116
|
+
process_block_assignment(node, args.last)
|
118
117
|
super
|
119
118
|
end
|
120
119
|
|
121
120
|
def on_masgn(node)
|
122
|
-
|
123
|
-
|
124
|
-
process_block_assignment(variables, args)
|
125
|
-
end
|
121
|
+
variables, args = *node
|
122
|
+
process_block_assignment(variables, args)
|
126
123
|
super
|
127
124
|
end
|
128
125
|
|
129
126
|
private
|
130
127
|
|
131
128
|
def process_block_assignment(begin_node, block_node)
|
132
|
-
|
129
|
+
return unless block_node
|
130
|
+
return if already_processed_node?(block_node)
|
131
|
+
|
132
|
+
while block_node.type == :send
|
133
|
+
receiver, _method, args = *block_node
|
134
|
+
if receiver && [:block, :send].include?(receiver.type)
|
135
|
+
block_node = receiver
|
136
|
+
elsif args && [:block, :send].include?(args.type)
|
137
|
+
block_node = args
|
138
|
+
else
|
139
|
+
break
|
140
|
+
end
|
141
|
+
end
|
142
|
+
if block_node.type == :block
|
143
|
+
# Align with the expression that is on the same line
|
144
|
+
# where the block is defined
|
145
|
+
return if block_is_on_next_line?(begin_node, block_node)
|
146
|
+
|
133
147
|
@inspected_blocks << block_node
|
134
148
|
check_block_alignment(begin_node.loc.expression, block_node.loc)
|
135
149
|
end
|
@@ -137,7 +151,6 @@ module Rubocop
|
|
137
151
|
|
138
152
|
def check_block_alignment(start_loc, block_loc)
|
139
153
|
end_loc = block_loc.end
|
140
|
-
|
141
154
|
if block_loc.begin.line != end_loc.line &&
|
142
155
|
start_loc.column != end_loc.column
|
143
156
|
add_offence(:warning,
|
@@ -167,12 +180,8 @@ module Rubocop
|
|
167
180
|
@inspected_blocks.include?(node)
|
168
181
|
end
|
169
182
|
|
170
|
-
def
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
def align_with_start_of_assignment?
|
175
|
-
EndAlignment.config['BlockAlignSchema'] == 'StartOfAssignment'
|
183
|
+
def block_is_on_next_line?(begin_node, block_node)
|
184
|
+
begin_node.loc.line != block_node.loc.line
|
176
185
|
end
|
177
186
|
end
|
178
187
|
end
|
@@ -3,8 +3,20 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop checks for literals used as
|
7
|
-
#
|
6
|
+
# This cop checks for literals used as the conditions or as
|
7
|
+
# operands in and/or expressions serving as the conditions of
|
8
|
+
# if/while/until.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# if 20
|
13
|
+
# do_something
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# if some_var && true
|
17
|
+
# do_something
|
18
|
+
# end
|
19
|
+
#
|
8
20
|
class LiteralInCondition < Cop
|
9
21
|
MSG = 'Literal %s appeared in a condition.'
|
10
22
|
|
@@ -46,15 +58,53 @@ module Rubocop
|
|
46
58
|
def check_for_literal(node)
|
47
59
|
cond, = *node
|
48
60
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
61
|
+
# if the cond node is literal we obviously have a problem
|
62
|
+
if literal?(cond)
|
63
|
+
add_offence(:warning, cond.loc.expression,
|
64
|
+
format(MSG, cond.loc.expression.source))
|
65
|
+
else
|
66
|
+
# alternatively we have to consider a logical node with a
|
67
|
+
# literal argument
|
68
|
+
check_node(cond)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def not?(node)
|
73
|
+
return false unless node && node.type == :send
|
55
74
|
|
56
|
-
|
75
|
+
_receiver, method_name, *_args = *node
|
76
|
+
|
77
|
+
method_name == :!
|
78
|
+
end
|
79
|
+
|
80
|
+
def literal?(node)
|
81
|
+
LITERALS.include?(node.type)
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_node(node)
|
85
|
+
return unless node
|
86
|
+
|
87
|
+
if not?(node)
|
88
|
+
receiver, = *node
|
89
|
+
|
90
|
+
handle_node(receiver)
|
91
|
+
elsif [:and, :or].include?(node.type)
|
92
|
+
*operands = *node
|
93
|
+
operands.each do |op|
|
94
|
+
handle_node(op)
|
57
95
|
end
|
96
|
+
elsif node.type == :begin && node.children.size == 1
|
97
|
+
child_node = node.children.first
|
98
|
+
handle_node(child_node)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def handle_node(node)
|
103
|
+
if literal?(node)
|
104
|
+
add_offence(:warning, node.loc.expression,
|
105
|
+
format(MSG, node.loc.expression.source))
|
106
|
+
elsif [:send, :and, :or, :begin].include?(node.type)
|
107
|
+
check_node(node)
|
58
108
|
end
|
59
109
|
end
|
60
110
|
end
|
@@ -20,6 +20,7 @@ module Rubocop
|
|
20
20
|
# Only block scope can reference outer local variables.
|
21
21
|
return unless variable_table.current_scope.node.type == :block
|
22
22
|
return unless ARGUMENT_DECLARATION_TYPES.include?(entry.node.type)
|
23
|
+
return if entry.name.to_s.start_with?('_')
|
23
24
|
|
24
25
|
outer_local_variable = variable_table.find_variable_entry(entry.name)
|
25
26
|
return unless outer_local_variable
|
@@ -12,22 +12,40 @@ module Rubocop
|
|
12
12
|
class CollectionMethods < Cop
|
13
13
|
MSG = 'Prefer %s over %s.'
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
def self.preferred_methods
|
16
|
+
Util.symbolize_keys(config['PreferredMethods'])
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_block(node)
|
20
|
+
method, _args, _body = *node
|
21
|
+
|
22
|
+
check_method_node(method)
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
21
26
|
|
22
27
|
def on_send(node)
|
23
|
-
|
28
|
+
_receiver, _method_name, *args = *node
|
29
|
+
|
30
|
+
if args.size == 1 && args.first.type == :block_pass
|
31
|
+
check_method_node(node)
|
32
|
+
end
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def check_method_node(node)
|
40
|
+
_receiver, method_name, *_args = *node
|
24
41
|
|
25
|
-
|
26
|
-
if receiver && PREFERRED_METHODS[method_name]
|
42
|
+
if self.class.preferred_methods[method_name]
|
27
43
|
add_offence(
|
28
44
|
:convention,
|
29
45
|
node.loc.selector,
|
30
|
-
sprintf(MSG,
|
46
|
+
sprintf(MSG,
|
47
|
+
self.class.preferred_methods[method_name],
|
48
|
+
method_name)
|
31
49
|
)
|
32
50
|
end
|
33
51
|
end
|