rubocop 0.20.1 → 0.21.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/CHANGELOG.md +46 -0
- data/README.md +16 -4
- data/config/default.yml +37 -10
- data/config/enabled.yml +25 -7
- data/lib/rubocop.rb +15 -19
- data/lib/rubocop/cli.rb +2 -2
- data/lib/rubocop/config.rb +40 -3
- data/lib/rubocop/config_loader.rb +6 -37
- data/lib/rubocop/config_store.rb +0 -1
- data/lib/rubocop/cop/commissioner.rb +12 -9
- data/lib/rubocop/cop/cop.rb +17 -5
- data/lib/rubocop/cop/force.rb +41 -0
- data/lib/rubocop/cop/ignored_node.rb +10 -10
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -2
- data/lib/rubocop/cop/lint/block_alignment.rb +2 -2
- data/lib/rubocop/cop/lint/condition_position.rb +2 -0
- data/lib/rubocop/cop/lint/debugger.rb +17 -3
- data/lib/rubocop/cop/lint/end_alignment.rb +3 -11
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +11 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -6
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +39 -0
- data/lib/rubocop/cop/lint/unused_block_argument.rb +81 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +52 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +6 -8
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +1 -1
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +7 -3
- data/lib/rubocop/cop/mixin/check_assignment.rb +11 -0
- data/lib/rubocop/cop/mixin/check_methods.rb +12 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +26 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -2
- data/lib/rubocop/cop/mixin/string_help.rb +0 -4
- data/lib/rubocop/cop/rails/delegate.rb +109 -0
- data/lib/rubocop/cop/style/align_hash.rb +3 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
- data/lib/rubocop/cop/style/dot_position.rb +1 -1
- data/lib/rubocop/cop/style/encoding.rb +44 -16
- data/lib/rubocop/cop/style/indentation_width.rb +29 -19
- data/lib/rubocop/cop/style/lambda_call.rb +1 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -21
- data/lib/rubocop/cop/style/predicate_name.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +18 -2
- data/lib/rubocop/cop/style/redundant_self.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +29 -37
- data/lib/rubocop/cop/style/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/trailing_blank_lines.rb +37 -23
- data/lib/rubocop/cop/style/trailing_comma.rb +2 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +40 -4
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +29 -0
- data/lib/rubocop/cop/team.rb +10 -2
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cop/{variable_inspector.rb → variable_force.rb} +45 -37
- data/lib/rubocop/cop/{variable_inspector → variable_force}/assignment.rb +1 -1
- data/lib/rubocop/cop/{variable_inspector → variable_force}/locatable.rb +1 -1
- data/lib/rubocop/cop/{variable_inspector → variable_force}/reference.rb +13 -1
- data/lib/rubocop/cop/{variable_inspector → variable_force}/scope.rb +9 -1
- data/lib/rubocop/cop/{variable_inspector → variable_force}/variable.rb +14 -4
- data/lib/rubocop/cop/{variable_inspector → variable_force}/variable_table.rb +1 -1
- data/lib/rubocop/file_inspector.rb +3 -1
- data/lib/rubocop/formatter/base_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
- data/lib/rubocop/formatter/disabled_lines_formatter.rb +2 -2
- data/lib/rubocop/formatter/offense_count_formatter.rb +11 -10
- data/lib/rubocop/formatter/progress_formatter.rb +2 -2
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/options.rb +74 -58
- data/lib/rubocop/path_util.rb +17 -2
- data/lib/rubocop/rake_task.rb +23 -5
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.21.0.md +45 -0
- data/rubocop-todo.yml +6 -6
- data/rubocop.gemspec +1 -1
- data/spec/rubocop/cli_spec.rb +170 -59
- data/spec/rubocop/config_spec.rb +48 -3
- data/spec/rubocop/config_store_spec.rb +3 -3
- data/spec/rubocop/cop/commissioner_spec.rb +9 -7
- data/spec/rubocop/cop/cop_spec.rb +0 -2
- data/spec/rubocop/cop/force_spec.rb +29 -0
- data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +2 -2
- data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +1 -1
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +24 -24
- data/spec/rubocop/cop/lint/condition_position_spec.rb +7 -5
- data/spec/rubocop/cop/lint/debugger_spec.rb +26 -9
- data/spec/rubocop/cop/lint/end_alignment_spec.rb +6 -3
- data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +7 -6
- data/spec/rubocop/cop/lint/rescue_exception_spec.rb +36 -0
- data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +4 -4
- data/spec/rubocop/cop/lint/underscore_prefixed_variable_name_spec.rb +179 -0
- data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +147 -0
- data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +140 -0
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +50 -48
- data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +1 -1
- data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +2 -0
- data/spec/rubocop/cop/rails/delegate_spec.rb +152 -0
- data/spec/rubocop/cop/style/encoding_spec.rb +131 -36
- data/spec/rubocop/cop/style/indentation_width_spec.rb +79 -0
- data/spec/rubocop/cop/style/redundant_begin_spec.rb +32 -0
- data/spec/rubocop/cop/style/regexp_literal_spec.rb +83 -13
- data/spec/rubocop/cop/style/string_literals_spec.rb +9 -3
- data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +65 -25
- data/spec/rubocop/cop/style/trivial_accessors_spec.rb +76 -0
- data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +85 -0
- data/spec/rubocop/cop/team_spec.rb +43 -0
- data/spec/rubocop/cop/{variable_inspector → variable_force}/assignment_spec.rb +3 -3
- data/spec/rubocop/cop/{variable_inspector → variable_force}/locatable_spec.rb +3 -3
- data/spec/rubocop/cop/{variable_inspector → variable_force}/scope_spec.rb +30 -2
- data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_spec.rb +12 -27
- data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_table_spec.rb +1 -1
- data/spec/rubocop/cop/{variable_inspector_spec.rb → variable_force_spec.rb} +4 -8
- data/spec/rubocop/formatter/base_formatter_spec.rb +2 -2
- data/spec/rubocop/formatter/offense_count_formatter_spec.rb +1 -1
- data/spec/rubocop/formatter/progress_formatter_spec.rb +1 -1
- data/spec/rubocop/options_spec.rb +2 -2
- data/spec/rubocop/path_util_spec.rb +47 -14
- data/spec/spec_helper.rb +9 -3
- data/spec/support/file_helper.rb +2 -0
- metadata +43 -26
- data/lib/rubocop/cop/style/final_newline.rb +0 -29
- data/spec/rubocop/cop/style/final_newline_spec.rb +0 -30
@@ -18,7 +18,7 @@ module Rubocop
|
|
18
18
|
MSG = 'Never put a space between a method name and the opening ' \
|
19
19
|
'parenthesis.'
|
20
20
|
|
21
|
-
def check(_node, _method_name, args,
|
21
|
+
def check(_node, _method_name, args, _body)
|
22
22
|
return unless args.loc.begin && args.loc.begin.is?('(')
|
23
23
|
expr = args.loc.expression
|
24
24
|
pos_before_left_paren = Parser::Source::Range.new(expr.source_buffer,
|
@@ -3,40 +3,54 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop looks for trailing blank lines in the
|
6
|
+
# This cop looks for trailing blank lines and a final newline in the
|
7
|
+
# source code.
|
7
8
|
class TrailingBlankLines < Cop
|
8
|
-
|
9
|
+
include ConfigurableEnforcedStyle
|
9
10
|
|
10
11
|
def investigate(processed_source)
|
11
|
-
|
12
|
+
sb = processed_source.buffer
|
13
|
+
return if sb.source.empty?
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
whitespace_at_end = sb.source[/\s*\Z/]
|
16
|
+
blank_lines = whitespace_at_end.count("\n") - 1
|
17
|
+
wanted_blank_lines = style == :final_newline ? 0 : 1
|
18
|
+
|
19
|
+
if blank_lines != wanted_blank_lines
|
20
|
+
begin_pos = sb.source.length - whitespace_at_end.length
|
21
|
+
autocorrect_range = Parser::Source::Range.new(sb, begin_pos,
|
22
|
+
sb.source.length)
|
23
|
+
begin_pos += "\n".length unless whitespace_at_end.length == 0
|
24
|
+
report_range = Parser::Source::Range.new(sb, begin_pos,
|
25
|
+
sb.source.length)
|
26
|
+
add_offense(autocorrect_range, report_range,
|
27
|
+
message(wanted_blank_lines, blank_lines))
|
19
28
|
end
|
29
|
+
end
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def message(wanted_blank_lines, blank_lines)
|
34
|
+
case blank_lines
|
35
|
+
when -1
|
36
|
+
'Final newline missing.'
|
37
|
+
when 0
|
38
|
+
'Trailing blank line missing.'
|
39
|
+
else
|
40
|
+
instead_of = if wanted_blank_lines == 0
|
41
|
+
''
|
42
|
+
else
|
43
|
+
"instead of #{wanted_blank_lines} "
|
44
|
+
end
|
45
|
+
format('%d trailing blank lines %sdetected.', blank_lines,
|
46
|
+
instead_of)
|
28
47
|
end
|
29
48
|
end
|
30
49
|
|
31
50
|
def autocorrect(range)
|
32
|
-
|
33
|
-
|
34
|
-
if range.source =~ / / &&
|
35
|
-
config.for_cop('TrailingWhitespace')['Enabled']
|
36
|
-
return
|
51
|
+
@corrections << lambda do |corrector|
|
52
|
+
corrector.replace(range, style == :final_newline ? "\n" : "\n\n")
|
37
53
|
end
|
38
|
-
|
39
|
-
@corrections << ->(corrector) { corrector.remove(range) }
|
40
54
|
end
|
41
55
|
end
|
42
56
|
end
|
@@ -56,8 +56,7 @@ module Rubocop
|
|
56
56
|
should_have_comma = style == :comma && multiline?(node)
|
57
57
|
if comma_offset
|
58
58
|
unless should_have_comma
|
59
|
-
avoid_comma(
|
60
|
-
after_last_item.begin_pos + comma_offset, sb)
|
59
|
+
avoid_comma(kind, after_last_item.begin_pos + comma_offset, sb)
|
61
60
|
end
|
62
61
|
elsif should_have_comma
|
63
62
|
put_comma(items, kind, sb)
|
@@ -79,7 +78,7 @@ module Rubocop
|
|
79
78
|
[node.loc.begin, node.loc.end].map(&:line).uniq.size > 1
|
80
79
|
end
|
81
80
|
|
82
|
-
def avoid_comma(
|
81
|
+
def avoid_comma(kind, comma_begin_pos, sb)
|
83
82
|
range = Parser::Source::Range.new(sb, comma_begin_pos,
|
84
83
|
comma_begin_pos + 1)
|
85
84
|
article = kind =~ /array/ ? 'an' : 'a'
|
@@ -32,6 +32,10 @@ module Rubocop
|
|
32
32
|
cop_config['AllowPredicates']
|
33
33
|
end
|
34
34
|
|
35
|
+
def allow_dsl_writers?
|
36
|
+
cop_config['AllowDSLWriters']
|
37
|
+
end
|
38
|
+
|
35
39
|
def whitelist
|
36
40
|
whitelist = cop_config['Whitelist']
|
37
41
|
Array(whitelist).map(&:to_sym) + [:initialize]
|
@@ -41,9 +45,14 @@ module Rubocop
|
|
41
45
|
method_name[-1] == '?'
|
42
46
|
end
|
43
47
|
|
48
|
+
def dsl_writer?(method_name)
|
49
|
+
!method_name.to_s.end_with?('=')
|
50
|
+
end
|
51
|
+
|
44
52
|
def trivial_reader?(method_name, args, body)
|
45
53
|
looks_like_trivial_reader?(args, body) &&
|
46
|
-
!allowed_method?(method_name, body)
|
54
|
+
!allowed_method?(method_name, body) &&
|
55
|
+
!allowed_reader?(method_name)
|
47
56
|
end
|
48
57
|
|
49
58
|
def looks_like_trivial_reader?(args, body)
|
@@ -52,7 +61,8 @@ module Rubocop
|
|
52
61
|
|
53
62
|
def trivial_writer?(method_name, args, body)
|
54
63
|
looks_like_trivial_writer?(args, body) &&
|
55
|
-
!allowed_method?(method_name, body)
|
64
|
+
!allowed_method?(method_name, body) &&
|
65
|
+
!allowed_writer?(method_name)
|
56
66
|
end
|
57
67
|
|
58
68
|
def looks_like_trivial_writer?(args, body)
|
@@ -62,16 +72,42 @@ module Rubocop
|
|
62
72
|
end
|
63
73
|
|
64
74
|
def allowed_method?(method_name, body)
|
65
|
-
|
66
|
-
whitelist.include?(method_name) ||
|
75
|
+
whitelist.include?(method_name) ||
|
67
76
|
exact_name_match? && !names_match?(method_name, body)
|
68
77
|
end
|
69
78
|
|
79
|
+
def allowed_writer?(method_name)
|
80
|
+
allow_dsl_writers? && dsl_writer?(method_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def allowed_reader?(method_name)
|
84
|
+
allow_predicates? && predicate?(method_name)
|
85
|
+
end
|
86
|
+
|
70
87
|
def names_match?(method_name, body)
|
71
88
|
ivar_name, = *body
|
72
89
|
|
73
90
|
method_name.to_s.chomp('=') == ivar_name[1..-1]
|
74
91
|
end
|
92
|
+
|
93
|
+
def autocorrect(node)
|
94
|
+
method_name, args, body = *node
|
95
|
+
return unless node.type == :def
|
96
|
+
return unless names_match?(method_name, body)
|
97
|
+
kind = if trivial_writer?(method_name, args, body)
|
98
|
+
return if dsl_writer?(method_name)
|
99
|
+
'writer'
|
100
|
+
elsif trivial_reader?(method_name, args, body)
|
101
|
+
'reader'
|
102
|
+
end
|
103
|
+
|
104
|
+
@corrections << lambda do |corrector|
|
105
|
+
corrector.replace(
|
106
|
+
node.loc.expression,
|
107
|
+
"attr_#{kind} :#{method_name.to_s.chomp('=')}"
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
75
111
|
end
|
76
112
|
end
|
77
113
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for usage of the %W() syntax when %w() would do.
|
7
|
+
class UnneededCapitalW < Cop
|
8
|
+
include PercentLiteral
|
9
|
+
|
10
|
+
MSG =
|
11
|
+
'Do not use `%W` unless interpolation is needed. If not, use `%w`.'
|
12
|
+
|
13
|
+
def on_array(node)
|
14
|
+
process(node, '%W')
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def on_percent_literal(node, types)
|
20
|
+
type = type(node)
|
21
|
+
if types.include?(type) &&
|
22
|
+
node.children.none? { |x| x.type == :dstr }
|
23
|
+
add_offense(node, :expression)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -32,7 +32,7 @@ module Rubocop
|
|
32
32
|
return Lint::Syntax.offenses_from_diagnostics(diagnostics)
|
33
33
|
end
|
34
34
|
|
35
|
-
commissioner = Commissioner.new(cops)
|
35
|
+
commissioner = Commissioner.new(cops, forces)
|
36
36
|
offenses = commissioner.investigate(processed_source)
|
37
37
|
process_commissioner_errors(
|
38
38
|
processed_source.file_path, commissioner.errors)
|
@@ -50,11 +50,19 @@ module Rubocop
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
def forces
|
54
|
+
@forces ||= Force.all.each_with_object([]) do |force_class, forces|
|
55
|
+
joining_cops = cops.select { |cop| cop.join_force?(force_class) }
|
56
|
+
next if joining_cops.empty?
|
57
|
+
forces << force_class.new(joining_cops)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
53
61
|
private
|
54
62
|
|
55
63
|
def cop_enabled?(cop_class)
|
56
64
|
@config.cop_enabled?(cop_class) ||
|
57
|
-
|
65
|
+
(@options[:only] || []).include?(cop_class.cop_name)
|
58
66
|
end
|
59
67
|
|
60
68
|
def autocorrect(buffer, cops)
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -144,8 +144,8 @@ module Rubocop
|
|
144
144
|
Parser::Source::Range.new(@processed_source.buffer, begin_pos, end_pos)
|
145
145
|
end
|
146
146
|
|
147
|
-
# Returns for example a bare `if` node if the given node is an `if`
|
148
|
-
# calls chained to the end of it.
|
147
|
+
# Returns, for example, a bare `if` node if the given node is an `if`
|
148
|
+
# with calls chained to the end of it.
|
149
149
|
def first_part_of_call_chain(node)
|
150
150
|
while node
|
151
151
|
case node.type
|
@@ -2,23 +2,37 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
# This
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
5
|
+
# This force provides a way to track local variables and scopes of Ruby.
|
6
|
+
# Cops intertact with this force need to override some of the hook methods.
|
7
|
+
#
|
8
|
+
# def before_entering_scope(scope, variable_table)
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def after_entering_scope(scope, variable_table)
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def before_leaving_scope(scope, variable_table)
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# def after_leaving_scope(scope, variable_table)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def before_declaring_variable(variable, variable_table)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def after_declaring_variable(variable, variable_table)
|
24
|
+
# end
|
25
|
+
class VariableForce < Force # rubocop:disable ClassLength
|
9
26
|
VARIABLE_ASSIGNMENT_TYPE = :lvasgn
|
10
27
|
REGEXP_NAMED_CAPTURE_TYPE = :match_with_lvasgn
|
11
28
|
VARIABLE_ASSIGNMENT_TYPES =
|
12
29
|
[VARIABLE_ASSIGNMENT_TYPE, REGEXP_NAMED_CAPTURE_TYPE].freeze
|
13
30
|
|
14
|
-
|
31
|
+
ARGUMENT_DECLARATION_TYPES = [
|
15
32
|
:arg, :optarg, :restarg,
|
16
|
-
:kwarg, :kwoptarg, :kwrestarg
|
33
|
+
:kwarg, :kwoptarg, :kwrestarg,
|
34
|
+
:blockarg # This doen't mean block argument, it's block-pass (&block).
|
17
35
|
].freeze
|
18
|
-
BLOCK_ARGUMENT_DECLARATION_TYPE = :blockarg
|
19
|
-
ARGUMENT_DECLARATION_TYPES = (
|
20
|
-
METHOD_ARGUMENT_DECLARATION_TYPES + [BLOCK_ARGUMENT_DECLARATION_TYPE]
|
21
|
-
).freeze
|
22
36
|
BLOCK_LOCAL_VARIABLE_DECLARATION_TYPE = :shadowarg
|
23
37
|
DECLARATION_TYPES = (
|
24
38
|
ARGUMENT_DECLARATION_TYPES + [BLOCK_LOCAL_VARIABLE_DECLARATION_TYPE]
|
@@ -42,27 +56,26 @@ module Rubocop
|
|
42
56
|
TWISTED_SCOPE_TYPES = [:block, :class, :sclass, :defs].freeze
|
43
57
|
SCOPE_TYPES = (TWISTED_SCOPE_TYPES + [:top_level, :module, :def]).freeze
|
44
58
|
|
59
|
+
def self.wrap_with_top_level_node(node)
|
60
|
+
# This is a custom node type, not defined in Parser.
|
61
|
+
Parser::AST::Node.new(:top_level, [node])
|
62
|
+
end
|
63
|
+
|
45
64
|
def variable_table
|
46
65
|
@variable_table ||= VariableTable.new(self)
|
47
66
|
end
|
48
67
|
|
49
68
|
# Starting point.
|
50
|
-
def
|
69
|
+
def investigate(processed_source)
|
70
|
+
root_node = processed_source.ast
|
51
71
|
return unless root_node
|
52
72
|
|
53
73
|
# Wrap the root node with :top_level scope node.
|
54
|
-
top_level_node = wrap_with_top_level_node(root_node)
|
74
|
+
top_level_node = self.class.wrap_with_top_level_node(root_node)
|
55
75
|
|
56
76
|
inspect_variables_in_scope(top_level_node)
|
57
77
|
end
|
58
78
|
|
59
|
-
def wrap_with_top_level_node(node)
|
60
|
-
# This is a custom node type, not defined in Parser.
|
61
|
-
Parser::AST::Node.new(:top_level, [node])
|
62
|
-
end
|
63
|
-
|
64
|
-
module_function :wrap_with_top_level_node
|
65
|
-
|
66
79
|
# This is called for each scope recursively.
|
67
80
|
def inspect_variables_in_scope(scope_node)
|
68
81
|
variable_table.push_scope(scope_node)
|
@@ -339,24 +352,19 @@ module Rubocop
|
|
339
352
|
@scanned_nodes ||= []
|
340
353
|
end
|
341
354
|
|
342
|
-
# Hooks
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
def before_declaring_variable(variable_variable)
|
357
|
-
end
|
358
|
-
|
359
|
-
def after_declaring_variable(variable_variable)
|
355
|
+
# Hooks invoked by VariableTable.
|
356
|
+
[
|
357
|
+
:before_entering_scope,
|
358
|
+
:after_entering_scope,
|
359
|
+
:before_leaving_scope,
|
360
|
+
:after_leaving_scope,
|
361
|
+
:before_declaring_variable,
|
362
|
+
:after_declaring_variable
|
363
|
+
].each do |hook|
|
364
|
+
define_method(hook) do |arg|
|
365
|
+
# Invoke hook in cops.
|
366
|
+
run_hook(hook, arg, variable_table)
|
367
|
+
end
|
360
368
|
end
|
361
369
|
|
362
370
|
# Post condition loops
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
|
5
|
+
class VariableForce
|
6
6
|
# This class represents each reference of a variable.
|
7
7
|
class Reference
|
8
8
|
include Locatable
|
@@ -25,6 +25,18 @@ module Rubocop
|
|
25
25
|
@node = node
|
26
26
|
@scope = scope
|
27
27
|
end
|
28
|
+
|
29
|
+
# There's an implicit variable reference by the zero-arity `super`:
|
30
|
+
#
|
31
|
+
# def some_method(foo)
|
32
|
+
# super
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# In this case, the variable `foo` is not explicitly referenced,
|
36
|
+
# but it can be considered used implicitly by the `super`.
|
37
|
+
def explicit?
|
38
|
+
@node.type != ZERO_ARITY_SUPER_TYPE
|
39
|
+
end
|
28
40
|
end
|
29
41
|
end
|
30
42
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
|
5
|
+
class VariableForce
|
6
6
|
# A Scope represents a context of local variable visibility.
|
7
7
|
# This is a place where local variables belong to.
|
8
8
|
# A scope instance holds a scope node and variable entries.
|
@@ -24,6 +24,14 @@ module Rubocop
|
|
24
24
|
@node.equal?(other.node)
|
25
25
|
end
|
26
26
|
|
27
|
+
def name
|
28
|
+
case @node.type
|
29
|
+
when :def then @node.children[0]
|
30
|
+
when :defs then @node.children[1]
|
31
|
+
else nil # TODO
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
def body_node
|
28
36
|
child_index = case @node.type
|
29
37
|
when :top_level then 0
|