rubocop 0.92.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -7
  3. data/config/default.yml +169 -59
  4. data/exe/rubocop +1 -1
  5. data/lib/rubocop.rb +15 -3
  6. data/lib/rubocop/cached_data.rb +2 -1
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
  8. data/lib/rubocop/cli/command/version.rb +1 -1
  9. data/lib/rubocop/comment_config.rb +1 -1
  10. data/lib/rubocop/config.rb +4 -0
  11. data/lib/rubocop/config_loader.rb +19 -2
  12. data/lib/rubocop/config_loader_resolver.rb +7 -5
  13. data/lib/rubocop/config_validator.rb +7 -6
  14. data/lib/rubocop/cop/badge.rb +9 -24
  15. data/lib/rubocop/cop/base.rb +16 -1
  16. data/lib/rubocop/cop/bundler/duplicated_gem.rb +23 -3
  17. data/lib/rubocop/cop/commissioner.rb +36 -22
  18. data/lib/rubocop/cop/corrector.rb +3 -1
  19. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  20. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  21. data/lib/rubocop/cop/force.rb +1 -1
  22. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
  23. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  24. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  25. data/lib/rubocop/cop/layout/dot_position.rb +6 -9
  26. data/lib/rubocop/cop/layout/else_alignment.rb +15 -2
  27. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -7
  28. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
  29. data/lib/rubocop/cop/layout/end_alignment.rb +3 -3
  30. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -2
  31. data/lib/rubocop/cop/layout/hash_alignment.rb +4 -4
  32. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
  33. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -11
  34. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
  35. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
  36. data/lib/rubocop/cop/layout/space_inside_parens.rb +35 -13
  37. data/lib/rubocop/cop/layout/trailing_whitespace.rb +37 -13
  38. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
  39. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
  40. data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
  41. data/lib/rubocop/cop/lint/debugger.rb +2 -3
  42. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +77 -0
  43. data/lib/rubocop/cop/lint/else_layout.rb +29 -3
  44. data/lib/rubocop/cop/lint/empty_block.rb +59 -0
  45. data/lib/rubocop/cop/lint/flip_flop.rb +8 -2
  46. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
  47. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +17 -3
  48. data/lib/rubocop/cop/lint/loop.rb +0 -4
  49. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  50. data/lib/rubocop/cop/lint/nested_percent_literal.rb +14 -0
  51. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +58 -0
  52. data/lib/rubocop/cop/lint/number_conversion.rb +46 -13
  53. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +27 -8
  54. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  55. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
  56. data/lib/rubocop/cop/lint/to_enum_arguments.rb +95 -0
  57. data/lib/rubocop/cop/lint/to_json.rb +1 -1
  58. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +185 -0
  59. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  60. data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
  61. data/lib/rubocop/cop/metrics/block_length.rb +3 -1
  62. data/lib/rubocop/cop/metrics/class_length.rb +14 -6
  63. data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -1
  64. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  65. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  66. data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
  67. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +12 -2
  68. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +11 -5
  69. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +67 -18
  70. data/lib/rubocop/cop/naming/predicate_name.rb +2 -1
  71. data/lib/rubocop/cop/naming/variable_number.rb +82 -8
  72. data/lib/rubocop/cop/offense.rb +18 -5
  73. data/lib/rubocop/cop/security/open.rb +12 -10
  74. data/lib/rubocop/cop/style/access_modifier_declarations.rb +6 -2
  75. data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
  76. data/lib/rubocop/cop/style/arguments_forwarding.rb +142 -0
  77. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -4
  78. data/lib/rubocop/cop/style/case_like_if.rb +18 -6
  79. data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
  80. data/lib/rubocop/cop/style/collection_compact.rb +85 -0
  81. data/lib/rubocop/cop/style/combinable_loops.rb +8 -1
  82. data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
  83. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +67 -0
  84. data/lib/rubocop/cop/style/double_negation.rb +6 -1
  85. data/lib/rubocop/cop/style/explicit_block_argument.rb +6 -2
  86. data/lib/rubocop/cop/style/for.rb +0 -4
  87. data/lib/rubocop/cop/style/format_string_token.rb +48 -3
  88. data/lib/rubocop/cop/style/hash_syntax.rb +3 -3
  89. data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -0
  90. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +10 -13
  91. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -11
  92. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +7 -11
  93. data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
  94. data/lib/rubocop/cop/style/mixin_grouping.rb +0 -4
  95. data/lib/rubocop/cop/style/multiple_comparison.rb +54 -7
  96. data/lib/rubocop/cop/style/negated_if_else_condition.rb +99 -0
  97. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
  98. data/lib/rubocop/cop/style/raise_args.rb +21 -9
  99. data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
  100. data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
  101. data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
  102. data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
  103. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +45 -24
  104. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
  105. data/lib/rubocop/cop/style/redundant_self.rb +3 -0
  106. data/lib/rubocop/cop/style/safe_navigation.rb +16 -4
  107. data/lib/rubocop/cop/style/semicolon.rb +3 -0
  108. data/lib/rubocop/cop/style/string_concatenation.rb +14 -2
  109. data/lib/rubocop/cop/style/swap_values.rb +108 -0
  110. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  111. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
  112. data/lib/rubocop/cop/team.rb +6 -1
  113. data/lib/rubocop/cop/util.rb +5 -1
  114. data/lib/rubocop/cop/variable_force/branch.rb +0 -4
  115. data/lib/rubocop/ext/regexp_node.rb +35 -11
  116. data/lib/rubocop/ext/regexp_parser.rb +84 -0
  117. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  118. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +47 -0
  119. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  120. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  121. data/lib/rubocop/magic_comment.rb +2 -2
  122. data/lib/rubocop/options.rb +6 -1
  123. data/lib/rubocop/result_cache.rb +8 -2
  124. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  125. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  126. data/lib/rubocop/runner.rb +4 -4
  127. data/lib/rubocop/target_finder.rb +23 -25
  128. data/lib/rubocop/version.rb +56 -6
  129. metadata +22 -8
  130. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
@@ -9,6 +9,8 @@ module RuboCop
9
9
  # The nodes modified by the corrections should be part of the
10
10
  # AST of the source_buffer.
11
11
  class Corrector < ::Parser::Source::TreeRewriter
12
+ NOOP_CONSUMER = ->(diagnostic) {} # noop
13
+
12
14
  # @param source [Parser::Source::Buffer, or anything
13
15
  # leading to one via `(processed_source.)buffer`]
14
16
  #
@@ -23,7 +25,7 @@ module RuboCop
23
25
  )
24
26
 
25
27
  # Don't print warnings to stderr if corrections conflict with each other
26
- diagnostics.consumer = ->(diagnostic) {}
28
+ diagnostics.consumer = NOOP_CONSUMER
27
29
  end
28
30
 
29
31
  alias rewrite process # Legacy
@@ -52,8 +52,8 @@ module RuboCop
52
52
  end
53
53
 
54
54
  def semicolon(node)
55
- @semicolon ||= {}
56
- @semicolon[node.object_id] ||= processed_source.tokens_within(node).find(&:semicolon?)
55
+ @semicolon ||= {}.compare_by_identity
56
+ @semicolon[node] ||= processed_source.tokens_within(node).find(&:semicolon?)
57
57
  end
58
58
  end
59
59
  end
@@ -89,7 +89,7 @@ module RuboCop
89
89
  begin_line_num = previous_line_num - base_line_num + 1
90
90
  end_line_num = node.first_line - base_line_num + 1
91
91
  lines = source_in_lines[begin_line_num...end_line_num]
92
- "\n#{(lines.join("\n").split(node.source).first || '')}"
92
+ "\n#{lines.join("\n").split(node.source).first || ''}"
93
93
  end
94
94
 
95
95
  def fix_escaped_content(word_node, escape, delimiters)
@@ -31,7 +31,7 @@ module RuboCop
31
31
  cops.each do |cop|
32
32
  next unless cop.respond_to?(method_name)
33
33
 
34
- cop.send(method_name, *args)
34
+ cop.public_send(method_name, *args)
35
35
  end
36
36
  end
37
37
 
@@ -58,24 +58,22 @@ module RuboCop
58
58
  (send _ :required_ruby_version= $_)
59
59
  PATTERN
60
60
 
61
- def_node_matcher :string_version?, <<~PATTERN
62
- {(str _) (array (str _))}
61
+ def_node_matcher :defined_ruby_version, <<~PATTERN
62
+ {$(str _) $(array (str _) (str _))
63
+ (send (const (const nil? :Gem) :Requirement) :new $(str _))}
63
64
  PATTERN
64
65
 
65
66
  # rubocop:disable Metrics/AbcSize
66
67
  def investigate(processed_source)
67
- version = required_ruby_version(processed_source.ast).first
68
+ version_def = required_ruby_version(processed_source.ast).first
68
69
 
69
- if version
70
- return unless string_version?(version)
71
-
72
- ruby_version = extract_ruby_version(version)
73
-
74
- return if ruby_version == target_ruby_version.to_s
70
+ if version_def
71
+ ruby_version = extract_ruby_version(defined_ruby_version(version_def))
72
+ return if !ruby_version || ruby_version == target_ruby_version.to_s
75
73
 
76
74
  add_offense(
77
75
  processed_source.ast,
78
- location: version.loc.expression,
76
+ location: version_def.loc.expression,
79
77
  message: not_equal_message(ruby_version, target_ruby_version)
80
78
  )
81
79
  else
@@ -88,6 +86,8 @@ module RuboCop
88
86
  private
89
87
 
90
88
  def extract_ruby_version(required_ruby_version)
89
+ return unless required_ruby_version
90
+
91
91
  if required_ruby_version.array_type?
92
92
  required_ruby_version = required_ruby_version.children.detect do |v|
93
93
  /[>=]/.match?(v.str_content)
@@ -265,6 +265,9 @@ module RuboCop
265
265
  end
266
266
 
267
267
  def end_position_for(node)
268
+ heredoc = find_heredoc(node)
269
+ return heredoc.location.heredoc_end.end_pos + 1 if heredoc
270
+
268
271
  end_line = buffer.line_for_position(node.loc.expression.end_pos)
269
272
  buffer.line_range(end_line).end_pos
270
273
  end
@@ -284,6 +287,10 @@ module RuboCop
284
287
  buffer.line_range(node.loc.line).begin_pos - 1
285
288
  end
286
289
 
290
+ def find_heredoc(node)
291
+ node.each_node(:str, :dstr, :xstr).find(&:heredoc?)
292
+ end
293
+
287
294
  def buffer
288
295
  processed_source.buffer
289
296
  end
@@ -46,7 +46,7 @@ module RuboCop
46
46
  alias on_defs on_def
47
47
 
48
48
  def on_send(node)
49
- return if !node.def_modifier? || node.method?(:using)
49
+ return unless node.def_modifier?
50
50
 
51
51
  method_def = node.each_descendant(:def, :defs).first
52
52
  expr = node.source_range
@@ -29,17 +29,14 @@ module RuboCop
29
29
  def on_send(node)
30
30
  return unless node.dot? || ampersand_dot?(node)
31
31
 
32
- if proper_dot_position?(node)
33
- correct_style_detected
34
- else
35
- return unless opposite_style_detected
32
+ return correct_style_detected if proper_dot_position?(node)
36
33
 
37
- dot = node.loc.dot
38
- message = message(dot)
34
+ opposite_style_detected
35
+ dot = node.loc.dot
36
+ message = message(dot)
39
37
 
40
- add_offense(dot, message: message) do |corrector|
41
- autocorrect(corrector, dot, node)
42
- end
38
+ add_offense(dot, message: message) do |corrector|
39
+ autocorrect(corrector, dot, node)
43
40
  end
44
41
  end
45
42
  alias on_csend on_send
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # This cop checks the alignment of else keywords. Normally they should
7
- # be aligned with an if/unless/while/until/begin/def keyword, but there
7
+ # be aligned with an if/unless/while/until/begin/def/rescue keyword, but there
8
8
  # are special cases when they should follow the same rules as the
9
9
  # alignment of end.
10
10
  #
@@ -93,7 +93,13 @@ module RuboCop
93
93
  case parent.type
94
94
  when :def, :defs then base_for_method_definition(parent)
95
95
  when :kwbegin then parent.loc.begin
96
- when :block then parent.send_node.source_range
96
+ when :block
97
+ assignment_node = assignment_node(parent)
98
+ if same_line?(parent, assignment_node)
99
+ assignment_node.source_range
100
+ else
101
+ parent.send_node.source_range
102
+ end
97
103
  else node.loc.keyword
98
104
  end
99
105
  end
@@ -136,6 +142,13 @@ module RuboCop
136
142
  )
137
143
  add_offense(else_range, location: else_range, message: message)
138
144
  end
145
+
146
+ def assignment_node(node)
147
+ assignment_node = node.ancestors.first
148
+ return unless assignment_node&.assignment?
149
+
150
+ assignment_node
151
+ end
139
152
  end
140
153
  end
141
154
  end
@@ -84,7 +84,8 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def on_send(node)
87
- return unless register_offense?(node)
87
+ return unless node.bare_access_modifier? && !node.parent&.block_type?
88
+ return if expected_empty_lines?(node)
88
89
 
89
90
  message = message(node)
90
91
  add_offense(node, message: message) do |corrector|
@@ -98,17 +99,15 @@ module RuboCop
98
99
 
99
100
  private
100
101
 
101
- def register_offense?(node)
102
- return false unless node.bare_access_modifier? && !node.parent.block_type?
103
-
102
+ def expected_empty_lines?(node)
104
103
  case style
105
104
  when :around
106
- return false if empty_lines_around?(node)
105
+ return true if empty_lines_around?(node)
107
106
  when :only_before
108
- return false if allowed_only_before_style?(node)
107
+ return true if allowed_only_before_style?(node)
109
108
  end
110
109
 
111
- true
110
+ false
112
111
  end
113
112
 
114
113
  def allowed_only_before_style?(node)
@@ -142,6 +141,7 @@ module RuboCop
142
141
  def previous_line_empty?(send_line)
143
142
  previous_line = previous_line_ignoring_comments(processed_source,
144
143
  send_line)
144
+ return true unless previous_line
145
145
 
146
146
  block_start?(send_line) ||
147
147
  class_def?(send_line) ||
@@ -88,7 +88,7 @@ module RuboCop
88
88
  end
89
89
 
90
90
  def require_empty_line?(node)
91
- return false unless node&.respond_to?(:type)
91
+ return false unless node.respond_to?(:type)
92
92
 
93
93
  !allow_alias?(node) && !attribute_or_allowed_method?(node)
94
94
  end
@@ -137,10 +137,10 @@ module RuboCop
137
137
  def asgn_variable_align_with(outer_node, inner_node)
138
138
  expr = outer_node.source_range
139
139
 
140
- if !line_break_before_keyword?(expr, inner_node)
141
- range_between(expr.begin_pos, inner_node.loc.keyword.end_pos)
142
- else
140
+ if line_break_before_keyword?(expr, inner_node)
143
141
  inner_node.loc.keyword
142
+ else
143
+ range_between(expr.begin_pos, inner_node.loc.keyword.end_pos)
144
144
  end
145
145
  end
146
146
 
@@ -56,8 +56,7 @@ module RuboCop
56
56
  aligned = Set[locs.first.line, locs.last.line]
57
57
  locs.each_cons(3) do |before, loc, after|
58
58
  col = loc.column
59
- aligned << loc.line if col == before.column || # rubocop:disable Style/MultipleComparison
60
- col == after.column
59
+ aligned << loc.line if col == before.column || col == after.column
61
60
  end
62
61
  aligned
63
62
  end
@@ -296,13 +296,13 @@ module RuboCop
296
296
  # just give each lambda the same reference and they would all get the
297
297
  # last value of each. A local variable fixes the problem.
298
298
 
299
- if !node.value
300
- delta_value = delta[:key] || 0
301
- correct_no_value(corrector, delta_value, node.source_range)
302
- else
299
+ if node.value
303
300
  correct_key_value(corrector, delta, node.key.source_range,
304
301
  node.value.source_range,
305
302
  node.loc.operator)
303
+ else
304
+ delta_value = delta[:key] || 0
305
+ correct_no_value(corrector, delta_value, node.source_range)
306
306
  end
307
307
  end
308
308
 
@@ -54,17 +54,11 @@ module RuboCop
54
54
  end
55
55
 
56
56
  def check_inside_pipes(arguments)
57
- opening_pipe, closing_pipe = pipes(arguments)
58
-
59
57
  case style
60
58
  when :no_space
61
- check_no_space_style_inside_pipes(arguments.children,
62
- opening_pipe,
63
- closing_pipe)
59
+ check_no_space_style_inside_pipes(arguments)
64
60
  when :space
65
- check_space_style_inside_pipes(arguments.children,
66
- opening_pipe,
67
- closing_pipe)
61
+ check_space_style_inside_pipes(arguments)
68
62
  end
69
63
  end
70
64
 
@@ -76,22 +70,29 @@ module RuboCop
76
70
  closing_pipe, 'after closing `|`')
77
71
  end
78
72
 
79
- def check_no_space_style_inside_pipes(args, opening_pipe, closing_pipe)
73
+ def check_no_space_style_inside_pipes(arguments)
74
+ args = arguments.children
75
+ opening_pipe, closing_pipe = pipes(arguments)
76
+
80
77
  first = args.first.source_range
81
78
  last = args.last.source_range
82
79
 
83
80
  check_no_space(opening_pipe.end_pos, first.begin_pos,
84
81
  'Space before first')
85
- check_no_space(last_end_pos_inside_pipes(last),
82
+ check_no_space(last_end_pos_inside_pipes(arguments, last),
86
83
  closing_pipe.begin_pos, 'Space after last')
87
84
  end
88
85
 
89
- def check_space_style_inside_pipes(args, opening_pipe, closing_pipe)
90
- check_opening_pipe_space(args, opening_pipe)
91
- check_closing_pipe_space(args, closing_pipe)
86
+ def check_space_style_inside_pipes(arguments)
87
+ opening_pipe, closing_pipe = pipes(arguments)
88
+
89
+ check_opening_pipe_space(arguments, opening_pipe)
90
+ check_closing_pipe_space(arguments, closing_pipe)
92
91
  end
93
92
 
94
- def check_opening_pipe_space(args, opening_pipe)
93
+ def check_opening_pipe_space(arguments, opening_pipe)
94
+ args = arguments.children
95
+
95
96
  first_arg = args.first
96
97
  range = first_arg.source_range
97
98
 
@@ -101,9 +102,11 @@ module RuboCop
101
102
  'Extra space before first')
102
103
  end
103
104
 
104
- def check_closing_pipe_space(args, closing_pipe)
105
+ def check_closing_pipe_space(arguments, closing_pipe)
106
+ args = arguments.children
107
+
105
108
  last = args.last.source_range
106
- last_end_pos = last_end_pos_inside_pipes(last)
109
+ last_end_pos = last_end_pos_inside_pipes(arguments, last)
107
110
 
108
111
  check_space(last_end_pos, closing_pipe.begin_pos, last,
109
112
  'after last block parameter')
@@ -111,9 +114,12 @@ module RuboCop
111
114
  'Extra space after last')
112
115
  end
113
116
 
114
- def last_end_pos_inside_pipes(range)
117
+ def last_end_pos_inside_pipes(arguments, range)
115
118
  pos = range.end_pos
116
- range.source_buffer.source[pos] == ',' ? pos + 1 : pos
119
+ num = pos - arguments.source_range.begin_pos
120
+ trailing_comma_index = arguments.source[num..-1].index(',')
121
+
122
+ trailing_comma_index ? pos + trailing_comma_index + 1 : pos
117
123
  end
118
124
 
119
125
  def check_each_arg(args)
@@ -51,22 +51,13 @@ module RuboCop
51
51
  style == :no_space && no_surrounding_space
52
52
  correct_style_detected
53
53
  else
54
- incorrect_style_detected(arg, value, space_on_both_sides,
55
- no_surrounding_space)
54
+ incorrect_style_detected(arg, value)
56
55
  end
57
56
  end
58
57
 
59
- def incorrect_style_detected(arg, value, space_on_both_sides,
60
- no_surrounding_space)
58
+ def incorrect_style_detected(arg, value)
61
59
  range = range_between(arg.end_pos, value.begin_pos)
62
60
 
63
- if style == :space && no_surrounding_space ||
64
- style == :no_space && space_on_both_sides
65
- return unless opposite_style_detected
66
- else
67
- return unless unrecognized_style_detected
68
- end
69
-
70
61
  add_offense(range) do |corrector|
71
62
  autocorrect(corrector, range)
72
63
  end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Layout
6
6
  # Checks that operators have space around them, except for ** which
7
7
  # should or shouldn't have surrounding space depending on configuration.
8
+ # It allows vertical alignment consisting of one or more whitespace
9
+ # around operators.
8
10
  #
9
11
  # This cop has `AllowForAlignment` option. When `true`, allows most
10
12
  # uses of extra spacing if the intent is to align with an operator on
@@ -207,7 +209,8 @@ module RuboCop
207
209
  token = Token.new(operator, nil, operator.source)
208
210
  align_preceding = aligned_with_preceding_assignment(token)
209
211
 
210
- return align_preceding == :no unless align_preceding == :none
212
+ return false if align_preceding == :yes ||
213
+ aligned_with_subsequent_assignment(token) == :none
211
214
 
212
215
  aligned_with_subsequent_assignment(token) != :yes
213
216
  end
@@ -206,8 +206,6 @@ module RuboCop
206
206
 
207
207
  def no_space(begin_pos, end_pos, msg)
208
208
  if style == :space
209
- return unless opposite_style_detected
210
-
211
209
  offense(begin_pos, end_pos, msg)
212
210
  else
213
211
  correct_style_detected
@@ -216,8 +214,6 @@ module RuboCop
216
214
 
217
215
  def space(begin_pos, end_pos, msg)
218
216
  if style == :no_space
219
- return unless opposite_style_detected
220
-
221
217
  offense(begin_pos, end_pos, msg)
222
218
  else
223
219
  correct_style_detected
@@ -11,10 +11,12 @@ module RuboCop
11
11
  # # bad
12
12
  # f( 3)
13
13
  # g = (a + 3 )
14
+ # f( )
14
15
  #
15
16
  # # good
16
17
  # f(3)
17
18
  # g = (a + 3)
19
+ # f()
18
20
  #
19
21
  # @example EnforcedStyle: space
20
22
  # # The `space` style enforces that parentheses have a space at the
@@ -44,11 +46,7 @@ module RuboCop
44
46
  @processed_source = processed_source
45
47
 
46
48
  if style == :space
47
- each_missing_space(processed_source.tokens) do |range|
48
- add_offense(range, message: MSG_SPACE) do |corrector|
49
- corrector.insert_before(range, ' ')
50
- end
51
- end
49
+ process_with_space_style(processed_source)
52
50
  else
53
51
  each_extraneous_space(processed_source.tokens) do |range|
54
52
  add_offense(range) do |corrector|
@@ -60,6 +58,21 @@ module RuboCop
60
58
 
61
59
  private
62
60
 
61
+ def process_with_space_style(processed_source)
62
+ processed_source.tokens.each_cons(2) do |token1, token2|
63
+ each_extraneous_space_in_empty_parens(token1, token2) do |range|
64
+ add_offense(range) do |corrector|
65
+ corrector.remove(range)
66
+ end
67
+ end
68
+ each_missing_space(token1, token2) do |range|
69
+ add_offense(range, message: MSG_SPACE) do |corrector|
70
+ corrector.insert_before(range, ' ')
71
+ end
72
+ end
73
+ end
74
+ end
75
+
63
76
  def each_extraneous_space(tokens)
64
77
  tokens.each_cons(2) do |token1, token2|
65
78
  next unless parens?(token1, token2)
@@ -73,15 +86,21 @@ module RuboCop
73
86
  end
74
87
  end
75
88
 
76
- def each_missing_space(tokens)
77
- tokens.each_cons(2) do |token1, token2|
78
- next if can_be_ignored?(token1, token2)
89
+ def each_extraneous_space_in_empty_parens(token1, token2)
90
+ return unless token1.left_parens? && token2.right_parens?
79
91
 
80
- if token1.left_parens?
81
- yield range_between(token2.begin_pos, token2.begin_pos + 1)
82
- elsif token2.right_parens?
83
- yield range_between(token2.begin_pos, token2.end_pos)
84
- end
92
+ return if range_between(token1.begin_pos, token2.end_pos).source == '()'
93
+
94
+ yield range_between(token1.end_pos, token2.begin_pos)
95
+ end
96
+
97
+ def each_missing_space(token1, token2)
98
+ return if can_be_ignored?(token1, token2)
99
+
100
+ if token1.left_parens?
101
+ yield range_between(token2.begin_pos, token2.begin_pos + 1)
102
+ elsif token2.right_parens?
103
+ yield range_between(token2.begin_pos, token2.end_pos)
85
104
  end
86
105
  end
87
106
 
@@ -96,6 +115,9 @@ module RuboCop
96
115
  def can_be_ignored?(token1, token2)
97
116
  return true unless parens?(token1, token2)
98
117
 
118
+ # Ignore empty parentheses.
119
+ return true if range_between(token1.begin_pos, token2.end_pos).source == '()'
120
+
99
121
  # If the second token is a comment, that means that a line break
100
122
  # follows, and that the rules for space inside don't apply.
101
123
  return true if token2.comment?