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.

Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/README.md +16 -4
  4. data/config/default.yml +37 -10
  5. data/config/enabled.yml +25 -7
  6. data/lib/rubocop.rb +15 -19
  7. data/lib/rubocop/cli.rb +2 -2
  8. data/lib/rubocop/config.rb +40 -3
  9. data/lib/rubocop/config_loader.rb +6 -37
  10. data/lib/rubocop/config_store.rb +0 -1
  11. data/lib/rubocop/cop/commissioner.rb +12 -9
  12. data/lib/rubocop/cop/cop.rb +17 -5
  13. data/lib/rubocop/cop/force.rb +41 -0
  14. data/lib/rubocop/cop/ignored_node.rb +10 -10
  15. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  16. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -2
  17. data/lib/rubocop/cop/lint/block_alignment.rb +2 -2
  18. data/lib/rubocop/cop/lint/condition_position.rb +2 -0
  19. data/lib/rubocop/cop/lint/debugger.rb +17 -3
  20. data/lib/rubocop/cop/lint/end_alignment.rb +3 -11
  21. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  22. data/lib/rubocop/cop/lint/rescue_exception.rb +11 -0
  23. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -6
  24. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +39 -0
  25. data/lib/rubocop/cop/lint/unused_block_argument.rb +81 -0
  26. data/lib/rubocop/cop/lint/unused_method_argument.rb +52 -0
  27. data/lib/rubocop/cop/lint/useless_assignment.rb +6 -8
  28. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -0
  29. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  30. data/lib/rubocop/cop/lint/void.rb +1 -1
  31. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
  32. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +7 -3
  33. data/lib/rubocop/cop/mixin/check_assignment.rb +11 -0
  34. data/lib/rubocop/cop/mixin/check_methods.rb +12 -0
  35. data/lib/rubocop/cop/mixin/percent_literal.rb +26 -0
  36. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -2
  37. data/lib/rubocop/cop/mixin/string_help.rb +0 -4
  38. data/lib/rubocop/cop/rails/delegate.rb +109 -0
  39. data/lib/rubocop/cop/style/align_hash.rb +3 -3
  40. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
  41. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  42. data/lib/rubocop/cop/style/dot_position.rb +1 -1
  43. data/lib/rubocop/cop/style/encoding.rb +44 -16
  44. data/lib/rubocop/cop/style/indentation_width.rb +29 -19
  45. data/lib/rubocop/cop/style/lambda_call.rb +1 -1
  46. data/lib/rubocop/cop/style/line_end_concatenation.rb +1 -1
  47. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -21
  48. data/lib/rubocop/cop/style/predicate_name.rb +1 -1
  49. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  50. data/lib/rubocop/cop/style/redundant_begin.rb +18 -2
  51. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  52. data/lib/rubocop/cop/style/regexp_literal.rb +29 -37
  53. data/lib/rubocop/cop/style/space_after_method_name.rb +1 -1
  54. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  55. data/lib/rubocop/cop/style/trailing_blank_lines.rb +37 -23
  56. data/lib/rubocop/cop/style/trailing_comma.rb +2 -3
  57. data/lib/rubocop/cop/style/trivial_accessors.rb +40 -4
  58. data/lib/rubocop/cop/style/unneeded_capital_w.rb +29 -0
  59. data/lib/rubocop/cop/team.rb +10 -2
  60. data/lib/rubocop/cop/util.rb +2 -2
  61. data/lib/rubocop/cop/{variable_inspector.rb → variable_force.rb} +45 -37
  62. data/lib/rubocop/cop/{variable_inspector → variable_force}/assignment.rb +1 -1
  63. data/lib/rubocop/cop/{variable_inspector → variable_force}/locatable.rb +1 -1
  64. data/lib/rubocop/cop/{variable_inspector → variable_force}/reference.rb +13 -1
  65. data/lib/rubocop/cop/{variable_inspector → variable_force}/scope.rb +9 -1
  66. data/lib/rubocop/cop/{variable_inspector → variable_force}/variable.rb +14 -4
  67. data/lib/rubocop/cop/{variable_inspector → variable_force}/variable_table.rb +1 -1
  68. data/lib/rubocop/file_inspector.rb +3 -1
  69. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  70. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
  71. data/lib/rubocop/formatter/disabled_lines_formatter.rb +2 -2
  72. data/lib/rubocop/formatter/offense_count_formatter.rb +11 -10
  73. data/lib/rubocop/formatter/progress_formatter.rb +2 -2
  74. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  75. data/lib/rubocop/options.rb +74 -58
  76. data/lib/rubocop/path_util.rb +17 -2
  77. data/lib/rubocop/rake_task.rb +23 -5
  78. data/lib/rubocop/version.rb +1 -1
  79. data/relnotes/v0.21.0.md +45 -0
  80. data/rubocop-todo.yml +6 -6
  81. data/rubocop.gemspec +1 -1
  82. data/spec/rubocop/cli_spec.rb +170 -59
  83. data/spec/rubocop/config_spec.rb +48 -3
  84. data/spec/rubocop/config_store_spec.rb +3 -3
  85. data/spec/rubocop/cop/commissioner_spec.rb +9 -7
  86. data/spec/rubocop/cop/cop_spec.rb +0 -2
  87. data/spec/rubocop/cop/force_spec.rb +29 -0
  88. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +2 -2
  89. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +1 -1
  90. data/spec/rubocop/cop/lint/block_alignment_spec.rb +24 -24
  91. data/spec/rubocop/cop/lint/condition_position_spec.rb +7 -5
  92. data/spec/rubocop/cop/lint/debugger_spec.rb +26 -9
  93. data/spec/rubocop/cop/lint/end_alignment_spec.rb +6 -3
  94. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +7 -6
  95. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +36 -0
  96. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +4 -4
  97. data/spec/rubocop/cop/lint/underscore_prefixed_variable_name_spec.rb +179 -0
  98. data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +147 -0
  99. data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +140 -0
  100. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +50 -48
  101. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +1 -1
  102. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +2 -0
  103. data/spec/rubocop/cop/rails/delegate_spec.rb +152 -0
  104. data/spec/rubocop/cop/style/encoding_spec.rb +131 -36
  105. data/spec/rubocop/cop/style/indentation_width_spec.rb +79 -0
  106. data/spec/rubocop/cop/style/redundant_begin_spec.rb +32 -0
  107. data/spec/rubocop/cop/style/regexp_literal_spec.rb +83 -13
  108. data/spec/rubocop/cop/style/string_literals_spec.rb +9 -3
  109. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +65 -25
  110. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +76 -0
  111. data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +85 -0
  112. data/spec/rubocop/cop/team_spec.rb +43 -0
  113. data/spec/rubocop/cop/{variable_inspector → variable_force}/assignment_spec.rb +3 -3
  114. data/spec/rubocop/cop/{variable_inspector → variable_force}/locatable_spec.rb +3 -3
  115. data/spec/rubocop/cop/{variable_inspector → variable_force}/scope_spec.rb +30 -2
  116. data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_spec.rb +12 -27
  117. data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_table_spec.rb +1 -1
  118. data/spec/rubocop/cop/{variable_inspector_spec.rb → variable_force_spec.rb} +4 -8
  119. data/spec/rubocop/formatter/base_formatter_spec.rb +2 -2
  120. data/spec/rubocop/formatter/offense_count_formatter_spec.rb +1 -1
  121. data/spec/rubocop/formatter/progress_formatter_spec.rb +1 -1
  122. data/spec/rubocop/options_spec.rb +2 -2
  123. data/spec/rubocop/path_util_spec.rb +47 -14
  124. data/spec/spec_helper.rb +9 -3
  125. data/spec/support/file_helper.rb +2 -0
  126. metadata +43 -26
  127. data/lib/rubocop/cop/style/final_newline.rb +0 -29
  128. data/spec/rubocop/cop/style/final_newline_spec.rb +0 -30
@@ -31,33 +31,15 @@ module Rubocop
31
31
 
32
32
  hash.delete('inherit_from')
33
33
  config = Config.new(hash, path)
34
- deprecation_check(config)
35
- config.warn_unless_valid
36
- make_excludes_absolute(config)
37
- config
38
- end
39
34
 
40
- def deprecation_check(config)
41
- return unless config['AllCops']
42
- if config['AllCops']['Excludes']
43
- warn('AllCops/Excludes was renamed to AllCops/Exclude')
44
- exit(-1)
45
- elsif config['AllCops']['Includes']
46
- warn('AllCops/Includes was renamed to AllCops/Include')
35
+ config.deprecation_check do |deprecation_message|
36
+ warn("#{path} - #{deprecation_message}")
47
37
  exit(-1)
48
38
  end
49
- end
50
39
 
51
- def make_excludes_absolute(config)
52
- if config['AllCops'] && config['AllCops']['Exclude']
53
- config['AllCops']['Exclude'].map! do |exclude_elem|
54
- if exclude_elem.is_a?(String) && !exclude_elem.start_with?('/')
55
- File.join(config.base_dir_for_path_parameters, exclude_elem)
56
- else
57
- exclude_elem
58
- end
59
- end
60
- end
40
+ config.warn_unless_valid
41
+ config.make_excludes_absolute
42
+ config
61
43
  end
62
44
 
63
45
  # Return a recursive merge of two hashes. That is, a normal hash merge,
@@ -102,24 +84,11 @@ module Rubocop
102
84
  found_files = config_files_in_path(config_file)
103
85
  if found_files.any? && found_files.last != config_file
104
86
  print 'AllCops/Exclude ' if debug?
105
- add_excludes_from_higher_level(config, load_file(found_files.last))
87
+ config.add_excludes_from_higher_level(load_file(found_files.last))
106
88
  end
107
89
  merge_with_default(config, config_file)
108
90
  end
109
91
 
110
- def add_excludes_from_higher_level(config, highest_config)
111
- if highest_config['AllCops'] && highest_config['AllCops']['Exclude']
112
- config['AllCops'] ||= {}
113
- excludes = config['AllCops']['Exclude'] ||= []
114
- highest_config['AllCops']['Exclude'].each do |path|
115
- unless path.is_a?(Regexp) || path.start_with?('/')
116
- path = File.join(File.dirname(highest_config.loaded_path), path)
117
- end
118
- excludes << path unless excludes.include?(path)
119
- end
120
- end
121
- end
122
-
123
92
  def default_configuration
124
93
  @default_configuration ||= begin
125
94
  print 'Default ' if debug?
@@ -21,7 +21,6 @@ module Rubocop
21
21
 
22
22
  def options_config=(options_config)
23
23
  loaded_config = ConfigLoader.load_file(options_config)
24
- ConfigLoader.make_excludes_absolute(loaded_config)
25
24
  @options_config = ConfigLoader.merge_with_default(loaded_config,
26
25
  options_config)
27
26
  end
@@ -28,8 +28,9 @@ module Rubocop
28
28
  end
29
29
  end
30
30
 
31
- def initialize(cops, options = {})
31
+ def initialize(cops, forces, options = {})
32
32
  @cops = cops
33
+ @forces = forces
33
34
  @options = options
34
35
  reset_errors
35
36
  end
@@ -52,7 +53,8 @@ module Rubocop
52
53
  def investigate(processed_source)
53
54
  reset_errors
54
55
  prepare(processed_source)
55
- invoke_cops_callback(processed_source)
56
+ invoke_custom_processing(@cops, processed_source)
57
+ invoke_custom_processing(@forces, processed_source)
56
58
  process(processed_source.ast) if processed_source.ast
57
59
  @cops.each_with_object([]) do |cop, offenses|
58
60
  filename = processed_source.buffer.name
@@ -72,18 +74,19 @@ module Rubocop
72
74
  @cops.each { |cop| cop.processed_source = processed_source }
73
75
  end
74
76
 
75
- # There are cops that require their own custom processing.
77
+ # There are cops/forces that require their own custom processing.
76
78
  # If they define the #investigate method, all input parameters passed
77
79
  # to the commissioner will be passed to the cop too in order to do
78
80
  # its own processing.
79
- def invoke_cops_callback(processed_source)
80
- @cops.each do |cop|
81
+ def invoke_custom_processing(cops_or_forces, processed_source)
82
+ cops_or_forces.each do |cop|
81
83
  next unless cop.respond_to?(:investigate)
82
84
 
83
- filename = processed_source.buffer.name
84
-
85
- # ignore files that are of no interest to the cop in question
86
- next unless cop.relevant_file?(filename)
85
+ if cop.respond_to?(:relevant_file?)
86
+ # ignore files that are of no interest to the cop in question
87
+ filename = processed_source.buffer.name
88
+ next unless cop.relevant_file?(filename)
89
+ end
87
90
 
88
91
  with_cop_error_handling(cop) do
89
92
  cop.investigate(processed_source)
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Rubocop
4
4
  module Cop
5
+ class CorrectionNotPossible < Exception; end
6
+
5
7
  # Store for all cops with helper functions
6
8
  class CopStore < ::Array
7
9
  # @return [Array<String>] list of types for current cops.
@@ -86,6 +88,10 @@ module Rubocop
86
88
  @corrections = []
87
89
  end
88
90
 
91
+ def join_force?(_force_class)
92
+ false
93
+ end
94
+
89
95
  def cop_config
90
96
  @config.for_cop(self)
91
97
  end
@@ -102,7 +108,7 @@ module Rubocop
102
108
  debug? || @options[:display_cop_names]
103
109
  end
104
110
 
105
- def message(node = nil)
111
+ def message(_node = nil)
106
112
  self.class::MSG
107
113
  end
108
114
 
@@ -123,9 +129,13 @@ module Rubocop
123
129
  message ||= message(node)
124
130
  message = display_cop_names? ? "#{name}: #{message}" : message
125
131
 
126
- autocorrect(node) if autocorrect?
127
- @offenses << Offense.new(severity, location, message, name,
128
- autocorrect?)
132
+ corrected = begin
133
+ autocorrect(node) if autocorrect?
134
+ autocorrect?
135
+ rescue CorrectionNotPossible
136
+ false
137
+ end
138
+ @offenses << Offense.new(severity, location, message, name, corrected)
129
139
  yield if block_given?
130
140
  end
131
141
 
@@ -162,7 +172,9 @@ module Rubocop
162
172
  patterns = cop_config && cop_config[parameter]
163
173
  return default_result unless patterns
164
174
  path = config.path_relative_to_config(file)
165
- patterns.any? { |pattern| match_path?(pattern, path) }
175
+ patterns.any? do |pattern|
176
+ match_path?(pattern, path, config.loaded_path)
177
+ end
166
178
  end
167
179
 
168
180
  def enabled_line?(line_number)
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # A scaffold for concrete forces.
6
+ class Force
7
+ attr_reader :cops
8
+
9
+ def self.all
10
+ @all ||= []
11
+ end
12
+
13
+ def self.inherited(subclass)
14
+ all << subclass
15
+ end
16
+
17
+ def self.force_name
18
+ name.split('::').last
19
+ end
20
+
21
+ def initialize(cops)
22
+ @cops = cops
23
+ end
24
+
25
+ def name
26
+ self.class.force_name
27
+ end
28
+
29
+ def run_hook(method_name, *args)
30
+ cops.each do |cop|
31
+ next unless cop.respond_to?(method_name)
32
+ cop.send(method_name, *args)
33
+ end
34
+ end
35
+
36
+ def investigate(_processed_source)
37
+ # Do custom processing and invoke #run_hook at arbitrary timing.
38
+ end
39
+ end
40
+ end
41
+ end
@@ -5,26 +5,26 @@ module Rubocop
5
5
  # Handles adding and checking ignored nodes.
6
6
  module IgnoredNode
7
7
  def ignore_node(node)
8
- @ignored_nodes ||= []
9
- @ignored_nodes << node
8
+ ignored_nodes << node
10
9
  end
11
10
 
12
11
  def part_of_ignored_node?(node)
13
- return false unless @ignored_nodes
14
12
  expression = node.loc.expression
15
- @ignored_nodes.each do |ignored_node|
16
- if ignored_node.loc.expression.begin_pos <= expression.begin_pos &&
13
+ ignored_nodes.any? do |ignored_node|
14
+ ignored_node.loc.expression.begin_pos <= expression.begin_pos &&
17
15
  ignored_node.loc.expression.end_pos >= expression.end_pos
18
- return true
19
- end
20
16
  end
21
-
22
- false
23
17
  end
24
18
 
25
19
  def ignored_node?(node)
26
20
  # Same object found in array?
27
- @ignored_nodes && @ignored_nodes.any? { |n| n.eql?(node) }
21
+ ignored_nodes.any? { |n| n.equal?(node) }
22
+ end
23
+
24
+ private
25
+
26
+ def ignored_nodes
27
+ @ignored_nodes ||= []
28
28
  end
29
29
  end
30
30
  end
@@ -30,7 +30,7 @@ module Rubocop
30
30
 
31
31
  MSG_FORMAT = 'Ambiguous %{actual} operator. Parenthesize the method ' \
32
32
  "arguments if it's surely a %{actual} operator, or add " \
33
- 'a whitespace to the right of the %{operator} if it ' \
33
+ 'a whitespace to the right of the `%{operator}` if it ' \
34
34
  'should be a %{possible}.'
35
35
 
36
36
  private
@@ -19,7 +19,7 @@ module Rubocop
19
19
 
20
20
  MSG = 'Ambiguous regexp literal. Parenthesize the method arguments ' \
21
21
  "if it's surely a regexp literal, or add a whitespace to the " \
22
- 'right of the / if it should be a division.'
22
+ 'right of the `/` if it should be a division.'
23
23
 
24
24
  private
25
25
 
@@ -27,7 +27,7 @@ module Rubocop
27
27
  diagnostic.reason == :ambiguous_literal
28
28
  end
29
29
 
30
- def alternative_message(diagnostic)
30
+ def alternative_message(_diagnostic)
31
31
  MSG
32
32
  end
33
33
  end
@@ -14,7 +14,7 @@ module Rubocop
14
14
  class BlockAlignment < Cop
15
15
  include CheckAssignment
16
16
 
17
- MSG = 'end at %d, %d is not aligned with %s at %d, %d%s'
17
+ MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d%s'
18
18
 
19
19
  def initialize(config = nil, options = nil)
20
20
  super
@@ -131,7 +131,7 @@ module Rubocop
131
131
  start_loc.column == indentation_of_do_line
132
132
  ''
133
133
  else
134
- " or #{match[0]} at #{do_loc.line}, #{indentation_of_do_line}"
134
+ " or `#{match[0]}` at #{do_loc.line}, #{indentation_of_do_line}"
135
135
  end
136
136
  end
137
137
 
@@ -30,6 +30,8 @@ module Rubocop
30
30
  private
31
31
 
32
32
  def check(node)
33
+ return if !node.loc.keyword.is?('elsif') && node.loc.end.nil?
34
+
33
35
  condition, = *node
34
36
 
35
37
  if on_different_line?(node.loc.keyword.line,
@@ -5,13 +5,18 @@ module Rubocop
5
5
  module Lint
6
6
  # This cop checks for calls to debugger or pry.
7
7
  class Debugger < Cop
8
- MSG = 'Remove calls to `debugger`.'
8
+ MSG = 'Remove debugger entry point `%s`.'
9
9
 
10
10
  # debugger call node
11
11
  #
12
12
  # (send nil :debugger)
13
13
  DEBUGGER_NODE = s(:send, nil, :debugger)
14
14
 
15
+ # byebug call node
16
+ #
17
+ # (send nil :byebug)
18
+ BYEBUG_NODE = s(:send, nil, :byebug)
19
+
15
20
  # binding.pry node
16
21
  #
17
22
  # (send
@@ -24,10 +29,19 @@ module Rubocop
24
29
  # (send nil :binding) :remote_pry)
25
30
  REMOTE_PRY_NODE = s(:send, s(:send, nil, :binding), :remote_pry)
26
31
 
27
- DEBUGGER_NODES = [DEBUGGER_NODE, PRY_NODE, REMOTE_PRY_NODE]
32
+ DEBUGGER_NODES = [
33
+ DEBUGGER_NODE,
34
+ BYEBUG_NODE,
35
+ PRY_NODE,
36
+ REMOTE_PRY_NODE
37
+ ]
28
38
 
29
39
  def on_send(node)
30
- add_offense(node, :selector) if DEBUGGER_NODES.include?(node)
40
+ if DEBUGGER_NODES.include?(node)
41
+ add_offense(node,
42
+ :expression,
43
+ format(MSG, node.loc.expression.source))
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -20,7 +20,7 @@ module Rubocop
20
20
  include CheckAssignment
21
21
  include ConfigurableEnforcedStyle
22
22
 
23
- MSG = 'end at %d, %d is not aligned with %s at %d, %d'
23
+ MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d'
24
24
 
25
25
  def on_class(node)
26
26
  check(node)
@@ -43,6 +43,8 @@ module Rubocop
43
43
  end
44
44
 
45
45
  def on_send(node)
46
+ super
47
+
46
48
  receiver, method_name, *args = *node
47
49
  if visibility_and_def_on_same_line?(receiver, method_name, args)
48
50
  expr = node.loc.expression
@@ -58,16 +60,6 @@ module Rubocop
58
60
 
59
61
  private
60
62
 
61
- # Returns true for constructs such as
62
- # private def my_method
63
- # which are allowed in Ruby 2.1 and later.
64
- def visibility_and_def_on_same_line?(receiver, method_name, args)
65
- !receiver &&
66
- [:public, :protected, :private,
67
- :module_function].include?(method_name) &&
68
- args.size == 1 && [:def, :defs].include?(args.first.type)
69
- end
70
-
71
63
  def check_assignment(node, rhs)
72
64
  # If there are method calls chained to the right hand side of the
73
65
  # assignment, we let rhs be the receiver of those method calls before
@@ -10,7 +10,7 @@ module Rubocop
10
10
  #
11
11
  # puts (x + y)
12
12
  class ParenthesesAsGroupedExpression < Cop
13
- MSG = '(...) interpreted as grouped expression.'
13
+ MSG = '`(...)` interpreted as grouped expression.'
14
14
 
15
15
  def on_send(node)
16
16
  _receiver, method_name, args = *node
@@ -18,6 +18,17 @@ module Rubocop
18
18
  def targets_exception?(rescue_arg_node)
19
19
  Util.const_name(rescue_arg_node) == 'Exception'
20
20
  end
21
+
22
+ def autocorrect(node)
23
+ @corrections << lambda do |corrector|
24
+ corrector.remove(
25
+ range_with_surrounding_space(
26
+ node.children.first.children.first.loc.expression,
27
+ :left
28
+ )
29
+ )
30
+ end
31
+ end
21
32
  end
22
33
  end
23
34
  end
@@ -8,15 +8,13 @@ module Rubocop
8
8
  # This is a mimic of the warning
9
9
  # "shadowing outer local variable - foo" from `ruby -cw`.
10
10
  class ShadowingOuterLocalVariable < Cop
11
- include VariableInspector
11
+ MSG = 'Shadowing outer local variable - `%s`.'
12
12
 
13
- MSG = 'Shadowing outer local variable - `%s`'
14
-
15
- def investigate(processed_source)
16
- inspect_variables(processed_source.ast)
13
+ def join_force?(force_class)
14
+ force_class == VariableForce
17
15
  end
18
16
 
19
- def before_declaring_variable(variable)
17
+ def before_declaring_variable(variable, variable_table)
20
18
  return if variable.name.to_s.start_with?('_')
21
19
 
22
20
  outer_local_variable = variable_table.find_variable(variable.name)
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for underscore-prefixed variables that are actually
7
+ # used.
8
+ class UnderscorePrefixedVariableName < Cop
9
+ MSG = 'Do not use prefix `_` for a variable that is used.'
10
+
11
+ def join_force?(force_class)
12
+ force_class == VariableForce
13
+ end
14
+
15
+ def after_leaving_scope(scope, _variable_table)
16
+ scope.variables.each_value do |variable|
17
+ check_variable(variable)
18
+ end
19
+ end
20
+
21
+ def check_variable(variable)
22
+ return unless variable.name.to_s.start_with?('_')
23
+ return if variable.references.empty?
24
+ return if variable.references.none?(&:explicit?)
25
+
26
+ node = variable.declaration_node
27
+
28
+ location = if node.type == :match_with_lvasgn
29
+ node.children.first.loc.expression
30
+ else
31
+ node.loc.name
32
+ end
33
+
34
+ add_offense(nil, location)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end