rubocop 0.90.0 → 0.93.1

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +79 -3
  4. data/lib/rubocop.rb +20 -5
  5. data/lib/rubocop/cached_data.rb +2 -1
  6. data/lib/rubocop/cli/command/execute_runner.rb +8 -0
  7. data/lib/rubocop/comment_config.rb +9 -5
  8. data/lib/rubocop/config_loader.rb +3 -3
  9. data/lib/rubocop/config_regeneration.rb +33 -0
  10. data/lib/rubocop/config_store.rb +3 -3
  11. data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
  12. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  13. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
  14. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  15. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
  16. data/lib/rubocop/cop/generator.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  18. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  19. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
  20. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  21. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
  22. data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
  23. data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
  24. data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
  25. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  26. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +6 -9
  28. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  29. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -12
  30. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +13 -8
  31. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
  32. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
  33. data/lib/rubocop/cop/layout/end_alignment.rb +5 -10
  34. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +26 -4
  35. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +4 -13
  36. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
  37. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
  38. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +6 -21
  39. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -8
  40. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
  44. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
  45. data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
  46. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
  47. data/lib/rubocop/cop/lint/debugger.rb +2 -3
  48. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
  50. data/lib/rubocop/cop/lint/duplicate_require.rb +7 -2
  51. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
  52. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  53. data/lib/rubocop/cop/lint/empty_file.rb +1 -4
  54. data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
  55. data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  57. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
  58. data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
  60. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  61. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  62. data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
  63. data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
  64. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -2
  65. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  66. data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
  67. data/lib/rubocop/cop/lint/rand_one.rb +2 -1
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
  70. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  71. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
  72. data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
  73. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
  75. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  76. data/lib/rubocop/cop/lint/to_json.rb +16 -5
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
  78. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
  79. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
  80. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
  81. data/lib/rubocop/cop/lint/useless_method_definition.rb +20 -27
  82. data/lib/rubocop/cop/lint/useless_times.rb +106 -0
  83. data/lib/rubocop/cop/metrics/block_length.rb +3 -1
  84. data/lib/rubocop/cop/metrics/class_length.rb +14 -6
  85. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
  86. data/lib/rubocop/cop/mixin/comments_help.rb +3 -9
  87. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  88. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  89. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +9 -0
  90. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -2
  91. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
  92. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
  93. data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
  94. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  95. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  96. data/lib/rubocop/cop/offense.rb +15 -2
  97. data/lib/rubocop/cop/security/eval.rb +1 -0
  98. data/lib/rubocop/cop/security/json_load.rb +1 -0
  99. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  100. data/lib/rubocop/cop/security/open.rb +1 -0
  101. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  102. data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
  103. data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
  104. data/lib/rubocop/cop/style/alias.rb +2 -0
  105. data/lib/rubocop/cop/style/array_coercion.rb +4 -0
  106. data/lib/rubocop/cop/style/array_join.rb +1 -0
  107. data/lib/rubocop/cop/style/attr.rb +1 -0
  108. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
  109. data/lib/rubocop/cop/style/case_equality.rb +3 -0
  110. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  111. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
  112. data/lib/rubocop/cop/style/class_check.rb +6 -9
  113. data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
  114. data/lib/rubocop/cop/style/class_methods_definitions.rb +42 -16
  115. data/lib/rubocop/cop/style/class_vars.rb +1 -2
  116. data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
  117. data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
  118. data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
  119. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
  120. data/lib/rubocop/cop/style/date_time.rb +12 -1
  121. data/lib/rubocop/cop/style/dir.rb +1 -0
  122. data/lib/rubocop/cop/style/double_negation.rb +1 -0
  123. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  124. data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
  125. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  126. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  127. data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
  128. data/lib/rubocop/cop/style/float_division.rb +2 -0
  129. data/lib/rubocop/cop/style/for.rb +0 -4
  130. data/lib/rubocop/cop/style/format_string.rb +1 -4
  131. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  132. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
  133. data/lib/rubocop/cop/style/hash_transform_keys.rb +5 -11
  134. data/lib/rubocop/cop/style/hash_transform_values.rb +5 -11
  135. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
  136. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  137. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
  138. data/lib/rubocop/cop/style/lambda_call.rb +3 -1
  139. data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
  140. data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
  141. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  142. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
  143. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
  144. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
  145. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  146. data/lib/rubocop/cop/style/non_nil_check.rb +2 -0
  147. data/lib/rubocop/cop/style/not.rb +1 -0
  148. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -3
  149. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
  150. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
  151. data/lib/rubocop/cop/style/preferred_hash_methods.rb +2 -0
  152. data/lib/rubocop/cop/style/raise_args.rb +2 -3
  153. data/lib/rubocop/cop/style/random_with_offset.rb +4 -3
  154. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
  155. data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
  156. data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
  157. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
  158. data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
  159. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  160. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -1
  161. data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
  162. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -6
  163. data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
  164. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
  165. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
  166. data/lib/rubocop/cop/style/redundant_return.rb +17 -17
  167. data/lib/rubocop/cop/style/redundant_self.rb +7 -9
  168. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
  169. data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
  170. data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
  171. data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
  172. data/lib/rubocop/cop/style/safe_navigation.rb +5 -0
  173. data/lib/rubocop/cop/style/sample.rb +2 -1
  174. data/lib/rubocop/cop/style/send.rb +2 -3
  175. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  176. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  177. data/lib/rubocop/cop/style/slicing_with_range.rb +2 -1
  178. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  179. data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
  180. data/lib/rubocop/cop/style/strip.rb +1 -0
  181. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
  182. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
  183. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  184. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -5
  185. data/lib/rubocop/cop/util.rb +0 -1
  186. data/lib/rubocop/cop/variable_force/branch.rb +0 -4
  187. data/lib/rubocop/core_ext/string.rb +1 -1
  188. data/lib/rubocop/directive_comment.rb +32 -0
  189. data/lib/rubocop/ext/regexp_node.rb +23 -7
  190. data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
  191. data/lib/rubocop/options.rb +37 -17
  192. data/lib/rubocop/result_cache.rb +38 -15
  193. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  194. data/lib/rubocop/rspec/expect_offense.rb +5 -5
  195. data/lib/rubocop/runner.rb +37 -18
  196. data/lib/rubocop/target_finder.rb +27 -26
  197. data/lib/rubocop/target_ruby.rb +1 -1
  198. data/lib/rubocop/version.rb +6 -1
  199. metadata +19 -18
  200. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
  201. data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -54,9 +54,9 @@ module RuboCop
54
54
  @path_cache[dir] ||= ConfigLoader.configuration_file_for(dir)
55
55
  path = @path_cache[dir]
56
56
  @object_cache[path] ||= begin
57
- print "For #{dir}: " if ConfigLoader.debug?
58
- ConfigLoader.configuration_from_file(path)
59
- end
57
+ print "For #{dir}: " if ConfigLoader.debug?
58
+ ConfigLoader.configuration_from_file(path)
59
+ end
60
60
  end
61
61
  end
62
62
  end
@@ -53,7 +53,11 @@ module RuboCop
53
53
  gem_declarations(processed_source.ast)
54
54
  .group_by(&:first_argument)
55
55
  .values
56
- .select { |nodes| nodes.size > 1 }
56
+ .select { |nodes| nodes.size > 1 && !condition?(nodes) }
57
+ end
58
+
59
+ def condition?(nodes)
60
+ nodes[0].parent&.if_type? && nodes[0].parent == nodes[1].parent
57
61
  end
58
62
 
59
63
  def register_offense(node, gem_name, line_of_first_occurrence)
@@ -64,6 +64,7 @@ module RuboCop
64
64
  MSG = 'Missing gem description comment.'
65
65
  CHECKED_OPTIONS_CONFIG = 'OnlyFor'
66
66
  VERSION_SPECIFIERS_OPTION = 'version_specifiers'
67
+ RESTRICT_ON_SEND = %i[gem].freeze
67
68
 
68
69
  def_node_matcher :gem_declaration?, '(send nil? :gem str ...)'
69
70
 
@@ -34,6 +34,8 @@ module RuboCop
34
34
  "Please change your source to 'https://rubygems.org' " \
35
35
  "if possible, or 'http://rubygems.org' if not."
36
36
 
37
+ RESTRICT_ON_SEND = %i[source].freeze
38
+
37
39
  def_node_matcher :insecure_protocol_source?, <<~PATTERN
38
40
  (send nil? :source
39
41
  $(sym ${:gemcutter :rubygems :rubyforge}))
@@ -52,8 +52,8 @@ module RuboCop
52
52
  end
53
53
 
54
54
  def semicolon(node)
55
- @semicolon ||= {}
56
- @semicolon[node.object_id] ||= tokens(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
@@ -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)
@@ -59,7 +59,7 @@ module RuboCop
59
59
  # TODO: Implement the cop in here.
60
60
  #
61
61
  # In many cases, you can use a node matcher for matching node pattern.
62
- # See https://github.com/rubocop-hq/rubocop-ast/blob/master/lib/rubocop/node_pattern.rb
62
+ # See https://github.com/rubocop-hq/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb
63
63
  #
64
64
  # For example
65
65
  MSG = 'Use `#good_method` instead of `#bad_method`.'
@@ -18,6 +18,7 @@ module RuboCop
18
18
 
19
19
  MSG = 'Use `method?(%<method_name>s)` instead of ' \
20
20
  '`method_name == %<method_name>s`.'
21
+ RESTRICT_ON_SEND = %i[==].freeze
21
22
 
22
23
  def_node_matcher :method_name?, <<~PATTERN
23
24
  (send
@@ -17,6 +17,7 @@ module RuboCop
17
17
  extend AutoCorrector
18
18
 
19
19
  MSG = 'Use `#%<type>s_type?` to check node type.'
20
+ RESTRICT_ON_SEND = %i[==].freeze
20
21
 
21
22
  def_node_matcher :node_type_check, <<~PATTERN
22
23
  (send (send $_ :type) :== (sym $_))
@@ -18,6 +18,7 @@ module RuboCop
18
18
 
19
19
  MSG = 'Use `:%<keyword>s` as the location argument to ' \
20
20
  '`#add_offense`.'
21
+ RESTRICT_ON_SEND = %i[add_offense].freeze
21
22
 
22
23
  def on_send(node)
23
24
  node_type_check(node) do |node_arg, kwargs|
@@ -21,6 +21,7 @@ module RuboCop
21
21
  extend AutoCorrector
22
22
 
23
23
  MSG = 'Redundant location argument to `#add_offense`.'
24
+ RESTRICT_ON_SEND = %i[add_offense].freeze
24
25
 
25
26
  def_node_matcher :redundant_location_argument, <<~PATTERN
26
27
  (send nil? :add_offense _
@@ -24,6 +24,7 @@ module RuboCop
24
24
  extend AutoCorrector
25
25
 
26
26
  MSG = 'Redundant message argument to `#add_offense`.'
27
+ RESTRICT_ON_SEND = %i[add_offense].freeze
27
28
 
28
29
  def_node_matcher :node_type_check, <<~PATTERN
29
30
  (send nil? :add_offense $_node $hash)
@@ -44,6 +44,7 @@ module RuboCop
44
44
 
45
45
  def on_array(node)
46
46
  return if node.children.size < 2
47
+ return if node.parent&.masgn_type?
47
48
 
48
49
  check_alignment(node.children, base_column(node, node.children))
49
50
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks whether the end keyword of `begin` is aligned properly.
7
+ #
8
+ # Two modes are supported through the `EnforcedStyleAlignWith` configuration
9
+ # parameter. If it's set to `start_of_line` (which is the default), the
10
+ # `end` shall be aligned with the start of the line where the `begin`
11
+ # keyword is. If it's set to `begin`, the `end` shall be aligned with the
12
+ # `begin` keyword.
13
+ #
14
+ # `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
15
+ # by default. On the other hand, `||= begin` that this cop targets tends to
16
+ # align with the start of the line, it defaults to `EnforcedStyleAlignWith: start_of_line`.
17
+ # These style can be configured by each cop.
18
+ #
19
+ # @example EnforcedStyleAlignWith: start_of_line (default)
20
+ # # bad
21
+ # foo ||= begin
22
+ # do_something
23
+ # end
24
+ #
25
+ # # good
26
+ # foo ||= begin
27
+ # do_something
28
+ # end
29
+ #
30
+ # @example EnforcedStyleAlignWith: begin
31
+ # # bad
32
+ # foo ||= begin
33
+ # do_something
34
+ # end
35
+ #
36
+ # # good
37
+ # foo ||= begin
38
+ # do_something
39
+ # end
40
+ #
41
+ class BeginEndAlignment < Base
42
+ include EndKeywordAlignment
43
+ include RangeHelp
44
+ extend AutoCorrector
45
+
46
+ MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d.'
47
+
48
+ def on_kwbegin(node)
49
+ check_begin_alignment(node)
50
+ end
51
+
52
+ private
53
+
54
+ def check_begin_alignment(node)
55
+ align_with = {
56
+ begin: node.loc.begin,
57
+ start_of_line: start_line_range(node)
58
+ }
59
+ check_end_kw_alignment(node, align_with)
60
+ end
61
+
62
+ def autocorrect(corrector, node)
63
+ AlignmentCorrector.align_end(corrector, processed_source, node, alignment_node(node))
64
+ end
65
+
66
+ def alignment_node(node)
67
+ case style
68
+ when :begin
69
+ node
70
+ else
71
+ start_line_range(node)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -105,7 +105,10 @@ module RuboCop
105
105
  end
106
106
 
107
107
  def incorrect_style(when_node)
108
- add_offense(when_node.loc.keyword) do |corrector|
108
+ depth = indent_one_step? ? 'one step more than' : 'as deep as'
109
+ message = format(MSG, depth: depth, base: style)
110
+
111
+ add_offense(when_node.loc.keyword, message: message) do |corrector|
109
112
  detect_incorrect_style(when_node)
110
113
 
111
114
  whitespace = whitespace_range(when_node)
@@ -125,12 +128,6 @@ module RuboCop
125
128
  end
126
129
  end
127
130
 
128
- def find_message(*)
129
- depth = indent_one_step? ? 'one step more than' : 'as deep as'
130
-
131
- format(MSG, depth: depth, base: style)
132
- end
133
-
134
131
  def base_column(case_node, base)
135
132
  case base
136
133
  when :case then case_node.location.keyword.column
@@ -169,7 +169,7 @@ module RuboCop
169
169
  # Autocorrect by swapping between two nodes autocorrecting them
170
170
  def autocorrect(corrector, node)
171
171
  node_classification = classify(node)
172
- previous = left_siblings_of(node).find do |sibling|
172
+ previous = node.left_siblings.find do |sibling|
173
173
  classification = classify(sibling)
174
174
  !ignore?(classification) && node_classification != classification
175
175
  end
@@ -46,7 +46,7 @@ module RuboCop
46
46
  alias on_defs on_def
47
47
 
48
48
  def on_send(node)
49
- return unless node.def_modifier?
49
+ return if !node.def_modifier? || node.method?(:using)
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
@@ -95,7 +95,7 @@ module RuboCop
95
95
  end
96
96
 
97
97
  def next_sibling_parent_empty_or_else?(node)
98
- next_sibling = node.parent.children[node.sibling_index + 1]
98
+ next_sibling = node.right_sibling
99
99
  return true if next_sibling.nil?
100
100
 
101
101
  parent = next_sibling.parent
@@ -104,7 +104,7 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def next_sibling_empty_or_guard_clause?(node)
107
- next_sibling = node.parent.children[node.sibling_index + 1]
107
+ next_sibling = node.right_sibling
108
108
  return true if next_sibling.nil?
109
109
 
110
110
  next_sibling.if_type? && contains_guard_clause?(next_sibling)
@@ -53,7 +53,6 @@ module RuboCop
53
53
  #
54
54
  class EmptyLineAfterMultilineCondition < Base
55
55
  include RangeHelp
56
- include RescueNode
57
56
  extend AutoCorrector
58
57
 
59
58
  MSG = 'Use empty line after multiline condition.'
@@ -62,7 +61,7 @@ module RuboCop
62
61
  return if node.ternary?
63
62
 
64
63
  if node.modifier_form?
65
- check_condition(node.condition) unless next_sibling_empty?(node)
64
+ check_condition(node.condition) if node.right_sibling
66
65
  else
67
66
  check_condition(node.condition)
68
67
  end
@@ -74,7 +73,7 @@ module RuboCop
74
73
  alias on_until on_while
75
74
 
76
75
  def on_while_post(node)
77
- return if next_sibling_empty?(node)
76
+ return unless node.right_sibling
78
77
 
79
78
  check_condition(node.condition)
80
79
  end
@@ -92,10 +91,8 @@ module RuboCop
92
91
  end
93
92
 
94
93
  def on_rescue(node)
95
- _body, *resbodies, _else = *node
96
-
97
- resbodies.each do |resbody|
98
- rescued_exceptions = rescued_exceptions(resbody)
94
+ node.resbody_branches.each do |resbody|
95
+ rescued_exceptions = resbody.exceptions
99
96
  next if !multiline_rescue_exceptions?(rescued_exceptions) ||
100
97
  next_line_empty?(rescued_exceptions.last.last_line)
101
98
 
@@ -116,11 +113,6 @@ module RuboCop
116
113
  processed_source[line].blank?
117
114
  end
118
115
 
119
- def next_sibling_empty?(node)
120
- next_sibling = node.parent.children[node.sibling_index + 1]
121
- next_sibling.nil?
122
- end
123
-
124
116
  def multiline_when_condition?(when_node)
125
117
  when_node.conditions.first.first_line != when_node.conditions.last.last_line
126
118
  end
@@ -84,14 +84,8 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def on_send(node)
87
- return unless node.bare_access_modifier?
88
-
89
- case style
90
- when :around
91
- return if empty_lines_around?(node)
92
- when :only_before
93
- return if allowed_only_before_style?(node)
94
- end
87
+ return unless node.bare_access_modifier? && !node.parent&.block_type?
88
+ return if expected_empty_lines?(node)
95
89
 
96
90
  message = message(node)
97
91
  add_offense(node, message: message) do |corrector|
@@ -105,6 +99,17 @@ module RuboCop
105
99
 
106
100
  private
107
101
 
102
+ def expected_empty_lines?(node)
103
+ case style
104
+ when :around
105
+ return true if empty_lines_around?(node)
106
+ when :only_before
107
+ return true if allowed_only_before_style?(node)
108
+ end
109
+
110
+ false
111
+ end
112
+
108
113
  def allowed_only_before_style?(node)
109
114
  if node.special_modifier?
110
115
  return true if processed_source[node.last_line] == 'end'
@@ -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
@@ -96,7 +96,7 @@ module RuboCop
96
96
  def next_line_node(node)
97
97
  return if node.parent.if_type?
98
98
 
99
- node.parent.children[node.sibling_index + 1]
99
+ node.right_sibling
100
100
  end
101
101
 
102
102
  def allow_alias?(node)
@@ -113,10 +113,9 @@ module RuboCop
113
113
  end
114
114
 
115
115
  def keyword_locations_in_rescue(node)
116
- _begin_body, *resbodies, _else_body = *node
117
116
  [
118
117
  node.loc.else,
119
- *resbodies.map { |body| body.loc.keyword }
118
+ *node.resbody_branches.map { |body| body.loc.keyword }
120
119
  ].compact
121
120
  end
122
121
 
@@ -17,6 +17,11 @@ module RuboCop
17
17
  # If it's set to `start_of_line`, the `end` shall be aligned with the
18
18
  # start of the line where the matching keyword appears.
19
19
  #
20
+ # This `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
21
+ # by default. On the other hand, `Layout/BeginEndAlignment` cop aligns with
22
+ # `EnforcedStyleAlignWith: start_of_line` by default due to `||= begin` tends
23
+ # to align with the start of the line. These style can be configured by each cop.
24
+ #
20
25
  # @example EnforcedStyleAlignWith: keyword (default)
21
26
  # # bad
22
27
  #
@@ -173,16 +178,6 @@ module RuboCop
173
178
  node
174
179
  end
175
180
  end
176
-
177
- def start_line_range(node)
178
- expr = node.source_range
179
- buffer = expr.source_buffer
180
- source = buffer.source_line(expr.line)
181
- range = buffer.line_range(expr.line)
182
-
183
- range_between(range.begin_pos + (source =~ /\S/),
184
- range.begin_pos + (source =~ /\s*\z/))
185
- end
186
181
  end
187
182
  end
188
183
  end