rubocop 0.1.0 → 0.2.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.
- data/.rbenv-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -8
- data/README.md +17 -1
- data/VERSION +1 -1
- data/bin/rubocop +1 -1
- data/features/step_definitions/rubocop_steps.rb +1 -0
- data/features/support/env.rb +2 -0
- data/lib/rubocop.rb +6 -0
- data/lib/rubocop/cli.rb +37 -17
- data/lib/rubocop/cop/align_parameters.rb +112 -0
- data/lib/rubocop/cop/cop.rb +43 -21
- data/lib/rubocop/cop/def_parentheses.rb +38 -0
- data/lib/rubocop/cop/empty_lines.rb +7 -6
- data/lib/rubocop/cop/encoding.rb +1 -1
- data/lib/rubocop/cop/end_of_line.rb +17 -0
- data/lib/rubocop/cop/grammar.rb +69 -9
- data/lib/rubocop/cop/hash_syntax.rb +26 -0
- data/lib/rubocop/cop/if_then_else.rb +49 -0
- data/lib/rubocop/cop/indentation.rb +16 -27
- data/lib/rubocop/cop/line_length.rb +2 -2
- data/lib/rubocop/cop/numeric_literals.rb +19 -0
- data/lib/rubocop/cop/offence.rb +2 -3
- data/lib/rubocop/cop/space_after_comma_etc.rb +10 -9
- data/lib/rubocop/cop/surrounding_space.rb +66 -17
- data/lib/rubocop/cop/tab.rb +2 -2
- data/lib/rubocop/cop/trailing_whitespace.rb +2 -2
- data/lib/rubocop/report/emacs_style.rb +4 -3
- data/rubocop.gemspec +16 -2
- data/spec/rubocop/cli_spec.rb +20 -5
- data/spec/rubocop/cops/align_parameters_spec.rb +201 -0
- data/spec/rubocop/cops/cop_spec.rb +4 -2
- data/spec/rubocop/cops/def_parentheses_spec.rb +48 -0
- data/spec/rubocop/cops/empty_lines_spec.rb +9 -8
- data/spec/rubocop/cops/end_of_line_spec.rb +17 -0
- data/spec/rubocop/cops/grammar_spec.rb +51 -11
- data/spec/rubocop/cops/hash_syntax_spec.rb +44 -0
- data/spec/rubocop/cops/if_then_else_spec.rb +74 -0
- data/spec/rubocop/cops/indentation_spec.rb +29 -4
- data/spec/rubocop/cops/line_length_spec.rb +4 -2
- data/spec/rubocop/cops/numeric_literals_spec.rb +49 -0
- data/spec/rubocop/cops/offence_spec.rb +4 -3
- data/spec/rubocop/cops/space_after_comma_etc_spec.rb +7 -5
- data/spec/rubocop/cops/surrounding_space_spec.rb +89 -26
- data/spec/rubocop/cops/tab_spec.rb +4 -2
- data/spec/rubocop/cops/trailing_whitespace_spec.rb +5 -3
- data/spec/rubocop/reports/emacs_style_spec.rb +4 -2
- data/spec/rubocop/reports/report_spec.rb +3 -1
- data/spec/spec_helper.rb +9 -1
- metadata +17 -3
data/lib/rubocop/cop/encoding.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class EndOfLine < Cop
|
6
|
+
ERROR_MESSAGE = 'Carriage return character detected.'
|
7
|
+
|
8
|
+
def inspect(file, source, tokens, sexp)
|
9
|
+
source.each_with_index do |line, index|
|
10
|
+
if line =~ /\r$/
|
11
|
+
add_offence(:convention, index + 1, ERROR_MESSAGE)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/rubocop/cop/grammar.rb
CHANGED
@@ -1,13 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Rubocop
|
2
4
|
module Cop
|
3
5
|
class Grammar
|
4
6
|
def initialize(tokens)
|
5
|
-
@tokens_without_pos = tokens.map { |
|
7
|
+
@tokens_without_pos = tokens.map { |t| [t.type, t.text] }
|
8
|
+
process_embedded_expressions
|
9
|
+
@token_indexes = {}
|
10
|
+
@tokens_without_pos.each_with_index { |t, i|
|
11
|
+
@token_indexes[t] ||= []
|
12
|
+
@token_indexes[t] << i
|
13
|
+
}
|
6
14
|
@ix = 0
|
7
15
|
@table = {}
|
8
|
-
token_positions = tokens.map { |
|
16
|
+
token_positions = tokens.map { |t| [t.pos.lineno, t.pos.column] }
|
9
17
|
@index_by_pos = Hash[*token_positions.each_with_index.to_a.flatten(1)]
|
10
|
-
@special = {
|
18
|
+
@special = {
|
19
|
+
assign: [:on_op, '='],
|
20
|
+
brace_block: [:on_lbrace, '{']
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# The string "#{x}" will give the tokens
|
25
|
+
# [:on_tstring_beg, '"'], [:on_embexpr_beg, '#{'], [:on_ident, 'x'],
|
26
|
+
# [:on_rbrace, '}'], [:on_tstring_end, '"']
|
27
|
+
# which is not so good for us. We want to distinguish between a
|
28
|
+
# right brace that ends an embedded expression inside a string
|
29
|
+
# and an ordinary right brace. So we replace :on_rbrace with the
|
30
|
+
# made up :on_embexpr_end.
|
31
|
+
def process_embedded_expressions
|
32
|
+
state = :outside
|
33
|
+
brace_depth = 0
|
34
|
+
@tokens_without_pos.each_with_index do |(type, _), ix|
|
35
|
+
case state
|
36
|
+
when :outside
|
37
|
+
state = :inside_string if type == :on_tstring_beg
|
38
|
+
when :inside_string
|
39
|
+
case type
|
40
|
+
when :on_tstring_end
|
41
|
+
state = :outside
|
42
|
+
when :on_embexpr_beg
|
43
|
+
brace_depth = 1
|
44
|
+
state = :inside_expr
|
45
|
+
end
|
46
|
+
when :inside_expr
|
47
|
+
case type
|
48
|
+
when :on_lbrace
|
49
|
+
brace_depth += 1
|
50
|
+
when :on_rbrace
|
51
|
+
if brace_depth == 1
|
52
|
+
@tokens_without_pos[ix][0] = :on_embexpr_end
|
53
|
+
state = :inside_string
|
54
|
+
end
|
55
|
+
brace_depth -= 1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
11
59
|
end
|
12
60
|
|
13
61
|
# Returns a hash mapping indexes in the token array to grammar
|
@@ -28,14 +76,15 @@ module Rubocop
|
|
28
76
|
when /^@/
|
29
77
|
# Leaves in the grammar have a corresponding token with a
|
30
78
|
# position, which we search for and advance @ix.
|
31
|
-
@ix = @index_by_pos[sexp[-1]]
|
79
|
+
@ix = @index_by_pos[[sexp[-1].lineno, sexp[-1].column]]
|
80
|
+
fail "#{sexp}\n#{@index_by_pos}" unless @ix
|
32
81
|
@table[@ix] = path + [sexp[0]]
|
33
82
|
@ix += 1
|
34
83
|
when *@special.keys
|
35
84
|
# Here we don't advance @ix because there may be other
|
36
85
|
# tokens inbetween the current one and the one we get from
|
37
86
|
# @special.
|
38
|
-
find(path, sexp,
|
87
|
+
find(path, sexp, @special[sexp[0]])
|
39
88
|
when :block_var # "{ |...|" or "do |...|"
|
40
89
|
@ix = find(path, sexp, [:on_op, '|']) + 1
|
41
90
|
find(path, sexp, [:on_op, '|'])
|
@@ -44,7 +93,7 @@ module Rubocop
|
|
44
93
|
# Compensate for reverse order of if modifier
|
45
94
|
children = (sexp[0] == :if_mod) ? sexp.reverse : sexp
|
46
95
|
|
47
|
-
children.each
|
96
|
+
children.each do |elem|
|
48
97
|
case elem
|
49
98
|
when Array
|
50
99
|
correlate(elem, path) # Dive deeper
|
@@ -56,7 +105,7 @@ module Rubocop
|
|
56
105
|
find(path, [elem], [:on_op, elem.to_s.chomp('@')])
|
57
106
|
end
|
58
107
|
end
|
59
|
-
|
108
|
+
end
|
60
109
|
end
|
61
110
|
@table
|
62
111
|
end
|
@@ -64,11 +113,22 @@ module Rubocop
|
|
64
113
|
private
|
65
114
|
|
66
115
|
def find(path, sexp, token_to_find)
|
67
|
-
|
68
|
-
ix = @ix
|
116
|
+
indices = @token_indexes[token_to_find] or return
|
117
|
+
ix = indices.find { |i| i >= @ix } or return
|
69
118
|
@table[ix] = path + [sexp[0]]
|
119
|
+
add_matching_rbrace(ix) if token_to_find == [:on_lbrace, '{']
|
70
120
|
ix
|
71
121
|
end
|
122
|
+
|
123
|
+
def add_matching_rbrace(ix)
|
124
|
+
brace_depth = 0
|
125
|
+
rbrace_offset = @tokens_without_pos[@ix..-1].index do |t|
|
126
|
+
brace_depth += 1 if t == [:on_lbrace, '{']
|
127
|
+
brace_depth -= 1 if t == [:on_rbrace, '}']
|
128
|
+
brace_depth == 0 && t == [:on_rbrace, '}']
|
129
|
+
end
|
130
|
+
@table[@ix + rbrace_offset] = @table[ix] if rbrace_offset
|
131
|
+
end
|
72
132
|
end
|
73
133
|
end
|
74
134
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class HashSyntax < Cop
|
6
|
+
ERROR_MESSAGE = 'Ruby 1.8 hash syntax detected'
|
7
|
+
|
8
|
+
def inspect(file, source, tokens, sexp)
|
9
|
+
each(:assoclist_from_args, sexp) do |assoclist_from_args|
|
10
|
+
keys = assoclist_from_args[1].map { |assoc_new| assoc_new[1][0] }
|
11
|
+
# If at least one of the keys in the hash is neither a symbol (:a)
|
12
|
+
# nor a label (a:), we can't require the new syntax.
|
13
|
+
return if keys.find do |key|
|
14
|
+
not [:symbol_literal, :@label].include?(key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
each(:assoc_new, sexp) do |assoc_new|
|
18
|
+
if assoc_new[1][0] == :symbol_literal
|
19
|
+
add_offence(:convention, assoc_new[1][1][1][-1].lineno,
|
20
|
+
ERROR_MESSAGE)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class IfThenElse < Cop
|
6
|
+
ERROR_MESSAGE = {
|
7
|
+
multiline_if_then:
|
8
|
+
'Never use then for multi-line if/unless.',
|
9
|
+
one_liner:
|
10
|
+
'Favor the ternary operator (?:) over if/then/else/end constructs.',
|
11
|
+
semicolon:
|
12
|
+
'Never use if x; Use the ternary operator instead.'
|
13
|
+
}
|
14
|
+
|
15
|
+
def inspect(file, source, tokens, sexp)
|
16
|
+
tokens.each_with_index do |t, ix|
|
17
|
+
if t.type == :on_kw && ['if', 'unless'].include?(t.text)
|
18
|
+
error = ERROR_MESSAGE[kind_of_if(tokens, ix + 1)]
|
19
|
+
add_offence(:convention, t.pos.lineno, error) if error
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def kind_of_if(tokens, ix)
|
25
|
+
then_found = false
|
26
|
+
tokens[ix..-1].each do |t|
|
27
|
+
case t.type
|
28
|
+
when :on_kw
|
29
|
+
case t.text
|
30
|
+
when 'then' then then_found = true
|
31
|
+
when 'end' then return :one_liner
|
32
|
+
end
|
33
|
+
when :on_ignored_nl, :on_nl
|
34
|
+
break
|
35
|
+
when :on_semicolon
|
36
|
+
return :semicolon
|
37
|
+
when :on_comment
|
38
|
+
break if t.text =~ /\n/
|
39
|
+
when :on_sp
|
40
|
+
nil
|
41
|
+
else
|
42
|
+
then_found = false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
then_found ? :multiline_if_then : nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Rubocop
|
2
4
|
module Cop
|
3
5
|
class Indentation < Cop
|
@@ -6,49 +8,36 @@ module Rubocop
|
|
6
8
|
def inspect(file, source, tokens, sexp)
|
7
9
|
case_tokens = find_keywords(tokens, 'case')
|
8
10
|
when_tokens = find_keywords(tokens, 'when')
|
9
|
-
each_when(sexp)
|
10
|
-
when_pos = when_tokens.shift
|
11
|
-
if when_pos
|
12
|
-
|
13
|
-
add_offence(:convention, index, source[index], ERROR_MESSAGE)
|
11
|
+
each_when(sexp) do |case_ix|
|
12
|
+
when_pos = when_tokens.shift.pos
|
13
|
+
if when_pos.column != case_tokens[case_ix].pos.column
|
14
|
+
add_offence(:convention, when_pos.lineno, ERROR_MESSAGE)
|
14
15
|
end
|
15
|
-
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
19
|
def find_keywords(tokens, keyword)
|
19
|
-
indexes = tokens.each_index.find_all
|
20
|
+
indexes = tokens.each_index.find_all do |ix|
|
20
21
|
keyword?(tokens, ix, keyword)
|
21
|
-
|
22
|
+
end
|
22
23
|
tokens.values_at(*indexes)
|
23
24
|
end
|
24
25
|
|
25
26
|
def keyword?(tokens, ix, keyword)
|
26
|
-
tokens[ix][
|
27
|
-
tokens[ix - 1]
|
27
|
+
[tokens[ix].type, tokens[ix].text] == [:on_kw, keyword] &&
|
28
|
+
tokens[ix - 1].type != :on_symbeg
|
28
29
|
end
|
29
30
|
|
30
31
|
# Does a depth first search for :when, yielding the index of the
|
31
32
|
# corresponding :case for each one.
|
32
33
|
def each_when(sexp, case_ix = -1, &block)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
case_ix = next_when(sexp, case_ix, &block)
|
37
|
-
when :when
|
38
|
-
yield case_ix
|
39
|
-
all_except_when = sexp.grep(Array).find_all { |s| s[0] != :when }
|
40
|
-
case_ix_deep = each_when(all_except_when, case_ix, &block)
|
41
|
-
case_ix_next = next_when(sexp, case_ix, &block)
|
42
|
-
case_ix = (case_ix_next == case_ix) ? case_ix_deep : case_ix_next
|
34
|
+
if sexp[0] == :case
|
35
|
+
@total_case_ix = (@total_case_ix || -1) + 1
|
36
|
+
each_when(sexp[2], @total_case_ix, &block)
|
43
37
|
else
|
44
|
-
|
38
|
+
yield case_ix if sexp[0] == :when
|
39
|
+
sexp.grep(Array).each { |s| each_when(s, case_ix, &block) }
|
45
40
|
end
|
46
|
-
case_ix
|
47
|
-
end
|
48
|
-
|
49
|
-
def next_when(sexp, case_ix, &block)
|
50
|
-
nxt = sexp.grep(Array).find { |s| s[0] == :when } or return case_ix
|
51
|
-
each_when(nxt, case_ix, &block)
|
52
41
|
end
|
53
42
|
end
|
54
43
|
end
|
@@ -6,11 +6,11 @@ module Rubocop
|
|
6
6
|
ERROR_MESSAGE = 'Line is too long. [%d/%d]'
|
7
7
|
MAX_LINE_LENGTH = 79
|
8
8
|
|
9
|
-
def inspect(file, source)
|
9
|
+
def inspect(file, source, tokens, sexp)
|
10
10
|
source.each_with_index do |line, index|
|
11
11
|
if line.length > MAX_LINE_LENGTH
|
12
12
|
message = sprintf(ERROR_MESSAGE, line.length, MAX_LINE_LENGTH)
|
13
|
-
add_offence(:convention, index
|
13
|
+
add_offence(:convention, index + 1, message)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
class NumericLiterals < Cop
|
6
|
+
ERROR_MESSAGE = 'Add underscores to large numeric literals to ' +
|
7
|
+
'improve their readability.'
|
8
|
+
|
9
|
+
def inspect(file, source, tokens, sexp)
|
10
|
+
tokens.each do |t|
|
11
|
+
if [:on_int, :on_float].include?(t.type) &&
|
12
|
+
t.text.split('.').grep(/\d{6}/).any?
|
13
|
+
add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rubocop/cop/offence.rb
CHANGED
@@ -3,14 +3,13 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
class Offence
|
6
|
-
attr_accessor :severity, :line_number, :
|
6
|
+
attr_accessor :severity, :line_number, :message
|
7
7
|
|
8
8
|
SEVERITIES = [:refactor, :convention, :warning, :error, :fatal]
|
9
9
|
|
10
|
-
def initialize(severity, line_number,
|
10
|
+
def initialize(severity, line_number, message)
|
11
11
|
@severity = severity
|
12
12
|
@line_number = line_number
|
13
|
-
@line = line
|
14
13
|
@message = message
|
15
14
|
end
|
16
15
|
|
@@ -1,23 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Rubocop
|
2
4
|
module Cop
|
3
5
|
class SpaceAfterCommaEtc < Cop
|
4
6
|
ERROR_MESSAGE = 'Space missing after %s.'
|
5
7
|
|
6
8
|
def inspect(file, source, tokens, sexp)
|
7
|
-
tokens.each_index
|
8
|
-
|
9
|
-
kind = case
|
9
|
+
tokens.each_index do |ix|
|
10
|
+
t = tokens[ix]
|
11
|
+
kind = case t.type
|
10
12
|
when :on_comma then 'comma'
|
11
13
|
when :on_label then 'colon'
|
12
|
-
when :on_op then 'colon' if text == ':'
|
14
|
+
when :on_op then 'colon' if t.text == ':'
|
13
15
|
when :on_semicolon then 'semicolon'
|
14
16
|
end
|
15
|
-
if kind and not [:on_sp,
|
16
|
-
|
17
|
-
add_offence(:convention,
|
18
|
-
ERROR_MESSAGE % kind)
|
17
|
+
if kind and not [:on_sp,
|
18
|
+
:on_ignored_nl].include?(tokens[ix + 1].type)
|
19
|
+
add_offence(:convention, t.pos.lineno, ERROR_MESSAGE % kind)
|
19
20
|
end
|
20
|
-
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -1,32 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require_relative 'grammar'
|
2
4
|
|
3
5
|
module Rubocop
|
4
6
|
module Cop
|
5
7
|
class SurroundingSpace < Cop
|
6
|
-
ERROR_MESSAGE = 'Surrounding space missing for
|
8
|
+
ERROR_MESSAGE = 'Surrounding space missing for '
|
7
9
|
|
8
10
|
def inspect(file, source, tokens, sexp)
|
9
|
-
Grammar.new(tokens).correlate(sexp).sort.each
|
10
|
-
|
11
|
-
|
11
|
+
Grammar.new(tokens).correlate(sexp).sort.each do |ix, grammar_path|
|
12
|
+
t = tokens[ix]
|
13
|
+
case t.type
|
14
|
+
when :on_op
|
12
15
|
unless surrounded_by_whitespace?(tokens[ix - 1, 3])
|
13
16
|
unless ok_without_spaces?(grammar_path)
|
14
|
-
|
15
|
-
|
16
|
-
ERROR_MESSAGE + " '#{text}'.")
|
17
|
+
add_offence(:convention, t.pos.lineno,
|
18
|
+
ERROR_MESSAGE + "operator '#{t.text}'.")
|
17
19
|
end
|
18
20
|
end
|
21
|
+
when :on_lbrace
|
22
|
+
unless surrounded_by_whitespace?(tokens[ix - 1, 3])
|
23
|
+
add_offence(:convention, t.pos.lineno, ERROR_MESSAGE + "'{'.")
|
24
|
+
end
|
25
|
+
when :on_rbrace
|
26
|
+
unless whitespace?(tokens[ix - 1])
|
27
|
+
add_offence(:convention, t.pos.lineno,
|
28
|
+
"Space missing to the left of '}'.")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
tokens.each_index do |ix|
|
33
|
+
t = tokens[ix]
|
34
|
+
prev, nxt = tokens.values_at(ix - 1, ix + 1)
|
35
|
+
offence_detected = case t.type
|
36
|
+
when :on_lbracket, :on_lparen
|
37
|
+
nxt.type == :on_sp
|
38
|
+
when :on_rbracket, :on_rparen
|
39
|
+
if prev.type == :on_sp
|
40
|
+
prev_ns = previous_non_space(tokens, ix)
|
41
|
+
prev_ns && tokens_on_same_row?(prev_ns,
|
42
|
+
tokens[ix]) &&
|
43
|
+
# Avoid double repoting of [ ] and ( )
|
44
|
+
prev_ns.type != :on_lbracket &&
|
45
|
+
prev_ns.type != :on_lparen
|
46
|
+
end
|
47
|
+
when :on_op
|
48
|
+
t.text == '**' &&
|
49
|
+
(whitespace?(prev) || whitespace?(nxt))
|
50
|
+
end
|
51
|
+
if offence_detected
|
52
|
+
kind = case t.type
|
53
|
+
when :on_lparen, :on_rparen
|
54
|
+
'inside parentheses'
|
55
|
+
when :on_lbracket, :on_rbracket
|
56
|
+
'inside square brackets'
|
57
|
+
when :on_op
|
58
|
+
"around operator #{t.text}"
|
59
|
+
end
|
60
|
+
add_offence(:convention, t.pos.lineno, "Space #{kind} detected.")
|
19
61
|
end
|
20
|
-
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def tokens_on_same_row?(t1, t2)
|
68
|
+
t1.pos.lineno == t2.pos.lineno
|
69
|
+
end
|
70
|
+
|
71
|
+
def previous_non_space(tokens, ix)
|
72
|
+
(ix - 1).downto(0) do |i|
|
73
|
+
t = tokens[i]
|
74
|
+
return t unless whitespace?(t)
|
75
|
+
end
|
76
|
+
nil
|
21
77
|
end
|
22
78
|
|
23
79
|
def ok_without_spaces?(grammar_path)
|
24
|
-
|
80
|
+
parent, child = grammar_path.values_at(-2, -1)
|
25
81
|
return true if [:unary, :symbol, :defs, :def, :call].include?(parent)
|
26
|
-
return true if [
|
27
|
-
:args_add_block, :const_path_ref, :dot2,
|
28
|
-
:dot3].include?(child)
|
29
|
-
return true if grandparent == :unary && parent == :vcall
|
82
|
+
return true if [:**, :block_var].include?(child)
|
30
83
|
return true if parent == :command_call && child == :'::'
|
31
84
|
false
|
32
85
|
end
|
@@ -35,10 +88,6 @@ module Rubocop
|
|
35
88
|
left, _, right = nearby_tokens
|
36
89
|
whitespace?(left) && whitespace?(right)
|
37
90
|
end
|
38
|
-
|
39
|
-
def whitespace?(token)
|
40
|
-
[:on_sp, :on_ignored_nl, :on_nl].include?(token[1])
|
41
|
-
end
|
42
91
|
end
|
43
92
|
end
|
44
93
|
end
|