rubocop 0.47.1 → 0.48.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.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -16
  3. data/config/default.yml +203 -115
  4. data/config/disabled.yml +0 -5
  5. data/config/enabled.yml +92 -8
  6. data/lib/rubocop.rb +24 -1
  7. data/lib/rubocop/ast/builder.rb +7 -2
  8. data/lib/rubocop/ast/node.rb +23 -20
  9. data/lib/rubocop/ast/node/and_node.rb +37 -0
  10. data/lib/rubocop/ast/node/array_node.rb +4 -1
  11. data/lib/rubocop/ast/node/case_node.rb +1 -0
  12. data/lib/rubocop/ast/node/ensure_node.rb +25 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +10 -3
  14. data/lib/rubocop/ast/node/if_node.rb +2 -0
  15. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +23 -0
  16. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +35 -0
  17. data/lib/rubocop/ast/node/or_node.rb +37 -0
  18. data/lib/rubocop/ast/node/resbody_node.rb +25 -0
  19. data/lib/rubocop/ast/node/send_node.rb +190 -0
  20. data/lib/rubocop/ast/node/when_node.rb +1 -1
  21. data/lib/rubocop/ast/traversal.rb +15 -15
  22. data/lib/rubocop/comment_config.rb +1 -1
  23. data/lib/rubocop/config.rb +39 -15
  24. data/lib/rubocop/config_loader.rb +34 -13
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +23 -4
  26. data/lib/rubocop/cop/commissioner.rb +4 -0
  27. data/lib/rubocop/cop/cop.rb +5 -0
  28. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +53 -0
  29. data/lib/rubocop/cop/lint/debugger.rb +8 -1
  30. data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -1
  31. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -4
  32. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  33. data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
  34. data/lib/rubocop/cop/lint/empty_ensure.rb +6 -2
  35. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  36. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +20 -18
  37. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -3
  38. data/lib/rubocop/cop/lint/literal_in_condition.rb +1 -1
  39. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  40. data/lib/rubocop/cop/lint/multiple_compare.rb +5 -3
  41. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +26 -18
  42. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -8
  43. data/lib/rubocop/cop/lint/require_parentheses.rb +7 -13
  44. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -3
  45. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -6
  46. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -8
  47. data/lib/rubocop/cop/lint/unneeded_disable.rb +35 -11
  48. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  49. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -2
  50. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -6
  51. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
  52. data/lib/rubocop/cop/lint/useless_comparison.rb +5 -4
  53. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  54. data/lib/rubocop/cop/message_annotator.rb +7 -3
  55. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  56. data/lib/rubocop/cop/metrics/block_nesting.rb +4 -4
  57. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -2
  58. data/lib/rubocop/cop/metrics/line_length.rb +2 -9
  59. data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -3
  60. data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -2
  61. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  62. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -2
  63. data/lib/rubocop/cop/mixin/check_assignment.rb +6 -6
  64. data/lib/rubocop/cop/mixin/duplication.rb +1 -1
  65. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  66. data/lib/rubocop/cop/mixin/ignored_pattern.rb +27 -0
  67. data/lib/rubocop/cop/mixin/method_preference.rb +2 -0
  68. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +17 -29
  69. data/lib/rubocop/cop/mixin/on_method_def.rb +3 -3
  70. data/lib/rubocop/cop/mixin/percent_literal.rb +27 -0
  71. data/lib/rubocop/cop/mixin/rescue_node.rb +21 -0
  72. data/lib/rubocop/cop/mixin/safe_mode.rb +1 -1
  73. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  74. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
  75. data/lib/rubocop/cop/mixin/target_rails_version.rb +16 -0
  76. data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
  77. data/lib/rubocop/cop/offense.rb +3 -3
  78. data/lib/rubocop/cop/performance/casecmp.rb +1 -1
  79. data/lib/rubocop/cop/performance/detect.rb +2 -1
  80. data/lib/rubocop/cop/performance/double_start_end_with.rb +35 -1
  81. data/lib/rubocop/cop/performance/end_with.rb +3 -1
  82. data/lib/rubocop/cop/performance/flat_map.rb +6 -6
  83. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
  84. data/lib/rubocop/cop/performance/range_include.rb +3 -1
  85. data/lib/rubocop/cop/performance/redundant_match.rb +6 -5
  86. data/lib/rubocop/cop/performance/regexp_match.rb +10 -3
  87. data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
  88. data/lib/rubocop/cop/performance/size.rb +6 -11
  89. data/lib/rubocop/cop/performance/start_with.rb +3 -1
  90. data/lib/rubocop/cop/performance/string_replacement.rb +13 -18
  91. data/lib/rubocop/cop/performance/times_map.rb +4 -4
  92. data/lib/rubocop/cop/rails/action_filter.rb +42 -42
  93. data/lib/rubocop/cop/rails/active_support_aliases.rb +68 -0
  94. data/lib/rubocop/cop/rails/blank.rb +131 -0
  95. data/lib/rubocop/cop/rails/date.rb +25 -28
  96. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +5 -7
  97. data/lib/rubocop/cop/rails/dynamic_find_by.rb +7 -3
  98. data/lib/rubocop/cop/rails/exit.rb +9 -9
  99. data/lib/rubocop/cop/rails/file_path.rb +5 -14
  100. data/lib/rubocop/cop/rails/find_by.rb +8 -10
  101. data/lib/rubocop/cop/rails/find_each.rb +6 -9
  102. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -0
  103. data/lib/rubocop/cop/rails/http_positional_arguments.rb +15 -7
  104. data/lib/rubocop/cop/rails/output.rb +3 -5
  105. data/lib/rubocop/cop/rails/output_safety.rb +4 -8
  106. data/lib/rubocop/cop/rails/pluralization_grammar.rb +25 -24
  107. data/lib/rubocop/cop/rails/present.rb +137 -0
  108. data/lib/rubocop/cop/rails/read_write_attribute.rb +9 -18
  109. data/lib/rubocop/cop/rails/relative_date_constant.rb +53 -0
  110. data/lib/rubocop/cop/rails/request_referer.rb +7 -4
  111. data/lib/rubocop/cop/rails/reversible_migration.rb +1 -2
  112. data/lib/rubocop/cop/rails/safe_navigation.rb +2 -1
  113. data/lib/rubocop/cop/rails/save_bang.rb +10 -10
  114. data/lib/rubocop/cop/rails/skips_model_validations.rb +23 -6
  115. data/lib/rubocop/cop/rails/time_zone.rb +20 -18
  116. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -2
  117. data/lib/rubocop/cop/rails/validation.rb +8 -11
  118. data/lib/rubocop/cop/registry.rb +3 -3
  119. data/lib/rubocop/cop/security/json_load.rb +1 -1
  120. data/lib/rubocop/cop/security/marshal_load.rb +5 -1
  121. data/lib/rubocop/cop/security/yaml_load.rb +3 -3
  122. data/lib/rubocop/cop/severity.rb +1 -1
  123. data/lib/rubocop/cop/style/alias.rb +5 -5
  124. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  125. data/lib/rubocop/cop/style/align_parameters.rb +5 -5
  126. data/lib/rubocop/cop/style/and_or.rb +16 -31
  127. data/lib/rubocop/cop/style/attr.rb +14 -8
  128. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +8 -11
  129. data/lib/rubocop/cop/style/block_delimiters.rb +11 -13
  130. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -23
  131. data/lib/rubocop/cop/style/case_indentation.rb +2 -0
  132. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  133. data/lib/rubocop/cop/style/class_check.rb +5 -7
  134. data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +5 -4
  135. data/lib/rubocop/cop/style/collection_methods.rb +8 -8
  136. data/lib/rubocop/cop/style/colon_method_call.rb +2 -9
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +38 -45
  138. data/lib/rubocop/cop/style/constant_name.rb +1 -1
  139. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  140. data/lib/rubocop/cop/style/dot_position.rb +3 -7
  141. data/lib/rubocop/cop/style/double_negation.rb +2 -1
  142. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  143. data/lib/rubocop/cop/style/empty_else.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_line_after_magic_comment.rb +63 -0
  145. data/lib/rubocop/cop/style/empty_line_between_defs.rb +74 -4
  146. data/lib/rubocop/cop/style/empty_lines_around_begin_body.rb +42 -0
  147. data/lib/rubocop/cop/style/empty_lines_around_exception_handling_keywords.rb +127 -0
  148. data/lib/rubocop/cop/style/empty_literal.rb +17 -9
  149. data/lib/rubocop/cop/style/end_of_line.rb +25 -3
  150. data/lib/rubocop/cop/style/file_name.rb +1 -1
  151. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  152. data/lib/rubocop/cop/style/first_parameter_indentation.rb +17 -19
  153. data/lib/rubocop/cop/style/for.rb +2 -4
  154. data/lib/rubocop/cop/style/format_string.rb +5 -4
  155. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/identical_conditional_branches.rb +27 -1
  157. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  158. data/lib/rubocop/cop/style/indent_assignment.rb +2 -2
  159. data/lib/rubocop/cop/style/indent_hash.rb +2 -1
  160. data/lib/rubocop/cop/style/indent_heredoc.rb +173 -0
  161. data/lib/rubocop/cop/style/indentation_width.rb +61 -29
  162. data/lib/rubocop/cop/style/inverse_methods.rb +130 -0
  163. data/lib/rubocop/cop/style/lambda_call.rb +15 -11
  164. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -4
  165. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -14
  166. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -16
  167. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  168. data/lib/rubocop/cop/style/missing_else.rb +4 -3
  169. data/lib/rubocop/cop/style/mixin_grouping.rb +97 -0
  170. data/lib/rubocop/cop/style/multiline_memoization.rb +38 -5
  171. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +2 -3
  172. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +38 -19
  173. data/lib/rubocop/cop/style/mutable_constant.rb +5 -1
  174. data/lib/rubocop/cop/style/negated_if.rb +73 -1
  175. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +21 -19
  176. data/lib/rubocop/cop/style/next.rb +5 -5
  177. data/lib/rubocop/cop/style/non_nil_check.rb +7 -10
  178. data/lib/rubocop/cop/style/not.rb +3 -4
  179. data/lib/rubocop/cop/style/numeric_literals.rb +25 -3
  180. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  182. data/lib/rubocop/cop/style/op_method.rb +2 -2
  183. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -3
  184. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +52 -6
  185. data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
  186. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -9
  187. data/lib/rubocop/cop/style/raise_args.rb +28 -24
  188. data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
  189. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
  190. data/lib/rubocop/cop/style/redundant_self.rb +17 -35
  191. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -14
  192. data/lib/rubocop/cop/style/self_assignment.rb +3 -3
  193. data/lib/rubocop/cop/style/send.rb +4 -5
  194. data/lib/rubocop/cop/style/space_after_not.rb +7 -8
  195. data/lib/rubocop/cop/style/space_around_keyword.rb +8 -9
  196. data/lib/rubocop/cop/style/space_around_operators.rb +19 -15
  197. data/lib/rubocop/cop/style/space_before_first_arg.rb +17 -14
  198. data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -1
  199. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +3 -3
  200. data/lib/rubocop/cop/style/space_inside_parens.rb +1 -1
  201. data/lib/rubocop/cop/style/special_global_vars.rb +14 -14
  202. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -1
  203. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  204. data/lib/rubocop/cop/style/string_methods.rb +10 -5
  205. data/lib/rubocop/cop/style/struct_inheritance.rb +4 -15
  206. data/lib/rubocop/cop/style/symbol_array.rb +31 -35
  207. data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
  208. data/lib/rubocop/cop/style/ternary_parentheses.rb +41 -13
  209. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +6 -9
  210. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -1
  211. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  212. data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -2
  213. data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
  214. data/lib/rubocop/cop/style/word_array.rb +12 -34
  215. data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -4
  216. data/lib/rubocop/cop/team.rb +4 -1
  217. data/lib/rubocop/cop/util.rb +33 -26
  218. data/lib/rubocop/cop/variable_force.rb +13 -13
  219. data/lib/rubocop/cop/variable_force/assignment.rb +1 -8
  220. data/lib/rubocop/cop/variable_force/branch.rb +318 -0
  221. data/lib/rubocop/cop/variable_force/branchable.rb +21 -0
  222. data/lib/rubocop/cop/variable_force/reference.rb +1 -3
  223. data/lib/rubocop/cop/variable_force/scope.rb +36 -20
  224. data/lib/rubocop/cop/variable_force/variable.rb +9 -8
  225. data/lib/rubocop/formatter/colorizable.rb +10 -10
  226. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  227. data/lib/rubocop/formatter/html_formatter.rb +2 -1
  228. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -2
  229. data/lib/rubocop/magic_comment.rb +20 -6
  230. data/lib/rubocop/options.rb +1 -1
  231. data/lib/rubocop/platform.rb +11 -0
  232. data/lib/rubocop/processed_source.rb +1 -1
  233. data/lib/rubocop/remote_config.rb +18 -6
  234. data/lib/rubocop/result_cache.rb +8 -8
  235. data/lib/rubocop/rspec/cop_helper.rb +2 -0
  236. data/lib/rubocop/rspec/shared_contexts.rb +20 -0
  237. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  238. data/lib/rubocop/runner.rb +2 -2
  239. data/lib/rubocop/target_finder.rb +64 -6
  240. data/lib/rubocop/version.rb +2 -4
  241. metadata +27 -4
  242. data/lib/rubocop/cop/variable_force/locatable.rb +0 -200
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `until` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `until` nodes within RuboCop.
8
+ class AndNode < Node
9
+ include BinaryOperatorNode
10
+ include PredicateOperatorNode
11
+
12
+ # Returns the alternate operator of the `and` as a string.
13
+ # Returns `and` for `&&` and vice versa.
14
+ #
15
+ # @return [String] the alternate of the `and` operator
16
+ def alternate_operator
17
+ logical_operator? ? SEMANTIC_AND : LOGICAL_AND
18
+ end
19
+
20
+ # Returns the inverse keyword of the `and` node as a string.
21
+ # Returns `||` for `&&` and `or` for `and`.
22
+ #
23
+ # @return [String] the inverse of the `and` operator
24
+ def inverse_operator
25
+ logical_operator? ? LOGICAL_OR : SEMANTIC_OR
26
+ end
27
+
28
+ # Custom destructuring method. This can be used to normalize
29
+ # destructuring for different variations of the node.
30
+ #
31
+ # @return [Array<Node>] the different parts of the `and` predicate
32
+ def node_parts
33
+ [*self]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -29,9 +29,12 @@ module RuboCop
29
29
  #
30
30
  # @overload percent_literal?
31
31
  # Check for any percent literal.
32
+ #
32
33
  # @overload percent_literal?(type)
33
34
  # Check for percent literaly of type `type`.
34
- # @param type [Symbol] an optional percent literal type
35
+ #
36
+ # @param type [Symbol] an optional percent literal type
37
+ #
35
38
  # @return [Boolean] whether the array is enclosed in percent brackets
36
39
  def percent_literal?(type = nil)
37
40
  if type
@@ -40,6 +40,7 @@ module RuboCop
40
40
  # Returns the else branch of the `case` statement, if any.
41
41
  #
42
42
  # @return [Node] the else branch node of the `case` statement
43
+ # @return [nil] if the case statement does not have an else branch.
43
44
  def else_branch
44
45
  node_parts[-1]
45
46
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `ensure` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `ensure` nodes within RuboCop.
8
+ class EnsureNode < Node
9
+ # Returns the body of the `ensure` clause.
10
+ #
11
+ # @return [Node, nil] The body of the `ensure`.
12
+ def body
13
+ node_parts[1]
14
+ end
15
+
16
+ # Custom destructuring method. This can be used to normalize
17
+ # destructuring for different variations of the node.
18
+ #
19
+ # @return [Array<Node>] the different parts of the `ensure` statement
20
+ def node_parts
21
+ [*self]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -13,6 +13,13 @@ module RuboCop
13
13
  each_pair.to_a
14
14
  end
15
15
 
16
+ # Checks whether the `hash` node contains any `pair`- or `kwsplat` nodes.
17
+ #
18
+ # @return[Boolean] whether the `hash` is empty
19
+ def empty?
20
+ children.empty?
21
+ end
22
+
16
23
  # Calls the given block for each `pair` node in the `hash` literal.
17
24
  # If no block is given, an `Enumerator` is returned.
18
25
  #
@@ -30,7 +37,7 @@ module RuboCop
30
37
 
31
38
  # Returns an array of all the keys in the `hash` literal.
32
39
  #
33
- # @return [Node] an array of keys in the `hash` literal
40
+ # @return [Array<Node>] an array of keys in the `hash` literal
34
41
  def keys
35
42
  each_key.to_a
36
43
  end
@@ -52,7 +59,7 @@ module RuboCop
52
59
 
53
60
  # Returns an array of all the values in the `hash` literal.
54
61
  #
55
- # @return [Node] an array of values in the `hash` literal
62
+ # @return [Array<Node>] an array of values in the `hash` literal
56
63
  def values
57
64
  each_pair.map(&:value)
58
65
  end
@@ -95,7 +102,7 @@ module RuboCop
95
102
  #
96
103
  # @return [Boolean] whether the `hash` literal is enclosed in braces
97
104
  def braces?
98
- loc.end
105
+ loc.end && loc.end.is?('}')
99
106
  end
100
107
  end
101
108
  end
@@ -104,6 +104,7 @@ module RuboCop
104
104
  # @note This is normalized for `unless` nodes.
105
105
  #
106
106
  # @return [Node] the truthy branch node of the `if` node
107
+ # @return [nil] if the truthy branch is empty
107
108
  def if_branch
108
109
  node_parts[1]
109
110
  end
@@ -114,6 +115,7 @@ module RuboCop
114
115
  # @note This is normalized for `unless` nodes.
115
116
  #
116
117
  # @return [Node] the falsey branch node of the `if` node
118
+ # @return [nil] when there is no else branch
117
119
  def else_branch
118
120
  node_parts[2]
119
121
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for nodes that are binary operations:
6
+ # `or`, `and` ...
7
+ module BinaryOperatorNode
8
+ # Returns the left hand side node of the binary operation.
9
+ #
10
+ # @return [Node] the left hand side of the binary operation
11
+ def lhs
12
+ node_parts[0]
13
+ end
14
+
15
+ # Returns the right hand side node of the binary operation.
16
+ #
17
+ # @return [Node] the right hand side of the binary operation
18
+ def rhs
19
+ node_parts[1]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for nodes that are predicates:
6
+ # `or`, `and` ...
7
+ module PredicateOperatorNode
8
+ LOGICAL_AND = '&&'.freeze
9
+ SEMANTIC_AND = 'and'.freeze
10
+ LOGICAL_OR = '||'.freeze
11
+ SEMANTIC_OR = 'or'.freeze
12
+
13
+ # Returns the operator as a string.
14
+ #
15
+ # @return [String] the operator
16
+ def operator
17
+ loc.operator.source
18
+ end
19
+
20
+ # Checks whether this is a logical operator.
21
+ #
22
+ # @return [Boolean] whether this is a logical operator
23
+ def logical_operator?
24
+ operator == LOGICAL_AND || operator == LOGICAL_OR
25
+ end
26
+
27
+ # Checks whether this is a semantic operator.
28
+ #
29
+ # @return [Boolean] whether this is a semantic operator
30
+ def semantic_operator?
31
+ operator == SEMANTIC_AND || operator == SEMANTIC_OR
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `or` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `or` nodes within RuboCop.
8
+ class OrNode < Node
9
+ include BinaryOperatorNode
10
+ include PredicateOperatorNode
11
+
12
+ # Returns the alternate operator of the `or` as a string.
13
+ # Returns `or` for `||` and vice versa.
14
+ #
15
+ # @return [String] the alternate of the `or` operator
16
+ def alternate_operator
17
+ logical_operator? ? SEMANTIC_OR : LOGICAL_OR
18
+ end
19
+
20
+ # Returns the inverse keyword of the `or` node as a string.
21
+ # Returns `and` for `or` and `&&` for `||`.
22
+ #
23
+ # @return [String] the inverse of the `or` operator
24
+ def inverse_operator
25
+ logical_operator? ? LOGICAL_AND : SEMANTIC_AND
26
+ end
27
+
28
+ # Custom destructuring method. This can be used to normalize
29
+ # destructuring for different variations of the node.
30
+ #
31
+ # @return [Array<Node>] the different parts of the `or` predicate
32
+ def node_parts
33
+ [*self]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `resbody` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `resbody` nodes within RuboCop.
8
+ class ResbodyNode < Node
9
+ # Returns the body of the `rescue` clause.
10
+ #
11
+ # @return [Node, nil] The body of the `resbody`.
12
+ def body
13
+ node_parts[2]
14
+ end
15
+
16
+ # Custom destructuring method. This can be used to normalize
17
+ # destructuring for different variations of the node.
18
+ #
19
+ # @return [Array<Node>] the different parts of the `resbody` statement
20
+ def node_parts
21
+ [*self]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `send` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `send` nodes within RuboCop.
8
+ class SendNode < Node
9
+ MACRO_PARENT_NODES = %i(class module).freeze
10
+
11
+ # The receiving node of the method invocation.
12
+ #
13
+ # @return [Node, nil] the receiver of the invoked method or `nil`
14
+ def receiver
15
+ node_parts[0]
16
+ end
17
+
18
+ # The name of the invoked method called as a string.
19
+ #
20
+ # @return [Symbol] the name of the invoked method
21
+ def method_name
22
+ node_parts[1]
23
+ end
24
+
25
+ # Checks whether the method name matches the argument.
26
+ #
27
+ # @param [Symbol, String] name the method name to check for
28
+ # @return [Boolean] whether the method name matches the argument
29
+ def method?(name)
30
+ method_name == name.to_sym
31
+ end
32
+
33
+ # Checks whether the method is a macro method. A macro method is defined
34
+ # as a method that sits in a class- or module body and has an implicit
35
+ # receiver.
36
+ #
37
+ # @note This does not include DSLs that use nested blocks, like RSpec
38
+ #
39
+ # @return [Boolean] whether the method is a macro method
40
+ def macro?
41
+ !receiver && MACRO_PARENT_NODES.include?(parent && parent.type)
42
+ end
43
+
44
+ # Checks whether the method name matches the argument and has an
45
+ # implicit receiver.
46
+ #
47
+ # @param [Symbol, String] name the method name to check for
48
+ # @return [Boolean] whether the method name matches the argument
49
+ def command?(name)
50
+ !receiver && method?(name)
51
+ end
52
+
53
+ # An array containing the arguments of the method invocation.
54
+ #
55
+ # @return [Array<Node>] the arguments of the method invocation or `nil`
56
+ def arguments
57
+ node_parts[2..-1]
58
+ end
59
+
60
+ # A shorthand for getting the first argument of the method invocation.
61
+ # Equivalent to `arguments.first`.
62
+ #
63
+ # @return [Node, nil] the first argument of the method invocation,
64
+ # or `nil` if there are no arguments
65
+ def first_argument
66
+ arguments[0]
67
+ end
68
+
69
+ # A shorthand for getting the last argument of the method invocation.
70
+ # Equivalent to `arguments.last`.
71
+ #
72
+ # @return [Node, nil] the last argument of the method invocation,
73
+ # or `nil` if there are no arguments
74
+ def last_argument
75
+ arguments[-1]
76
+ end
77
+
78
+ # Checks whether this method was invoked with arguments.
79
+ #
80
+ # @return [Boolean] whether this method was invoked with arguments
81
+ def arguments?
82
+ !arguments.empty?
83
+ end
84
+
85
+ # Checks whether this method invocation's arguments are wrapped in
86
+ # parentheses.
87
+ #
88
+ # @return [Boolean] whether this method invocation's arguments are
89
+ # wrapped in parentheses
90
+ def parenthesized?
91
+ loc.end && loc.end.is?(')')
92
+ end
93
+
94
+ # Checks whether the invoked method is a setter method.
95
+ #
96
+ # @return [Boolean] whether the invoked method is a setter
97
+ def setter_method?
98
+ loc.operator
99
+ end
100
+
101
+ # Checks whether the invoked method is an operator method.
102
+ #
103
+ # @return [Boolean] whether the invoked method is an operator
104
+ def operator_method?
105
+ RuboCop::Cop::Util::OPERATOR_METHODS.include?(method_name)
106
+ end
107
+
108
+ # Checks whether the method call uses a dot to connect the receiver and
109
+ # the method name.
110
+ #
111
+ # This is useful for comparison operators, which can be called either
112
+ # with or without a dot, i.e. `foo == bar` or `foo.== bar`.
113
+ #
114
+ # @return [Boolean] whether the method was called with a connecting dot
115
+ def dot?
116
+ loc.dot && loc.dot.is?('.')
117
+ end
118
+
119
+ # Checks whether the method call uses a double colon to connect the
120
+ # receiver and the method name.
121
+ #
122
+ # @return [Boolean] whether the method was called with a connecting dot
123
+ def double_colon?
124
+ loc.dot && loc.dot.is?('::')
125
+ end
126
+
127
+ # Checks whether the receiver of this method invocation is `self`.
128
+ #
129
+ # @return [Boolean] whether the receiver of this method invocation
130
+ # is `self`
131
+ def self_receiver?
132
+ receiver && receiver.self_type?
133
+ end
134
+
135
+ # Checks whether the method call is of the implicit form of `#call`,
136
+ # e.g. `foo.(bar)`.
137
+ #
138
+ # @return [Boolean] whether the method is an implicit form of `#call`
139
+ def implicit_call?
140
+ method_name == :call && !loc.selector
141
+ end
142
+
143
+ # Checks whether the invoked method is a predicate method.
144
+ #
145
+ # @return [Boolean] whether the invoked method is a predicate method
146
+ def predicate_method?
147
+ method_name.to_s.end_with?('?')
148
+ end
149
+
150
+ # Checks whether the invoked method is a bang method.
151
+ #
152
+ # @return [Boolean] whether the invoked method is a bang method
153
+ def bang_method?
154
+ method_name.to_s.end_with?('!')
155
+ end
156
+
157
+ # Checks whether the invoked method is a camel case method,
158
+ # e.g. `Integer()`.
159
+ #
160
+ # @return [Boolean] whether the invoked method is a camel case method
161
+ def camel_case_method?
162
+ method_name.to_s =~ /\A[A-Z]/
163
+ end
164
+
165
+ # Whether the last argument of the method invocation is a block pass,
166
+ # i.e. `&block`.
167
+ #
168
+ # @return [Boolean] whether the invoked method is a block pass
169
+ def block_argument?
170
+ arguments? && last_argument.block_pass_type?
171
+ end
172
+
173
+ # Checks whether any argument of the method invocation is a splat
174
+ # argument, i.e. `*splat`.
175
+ #
176
+ # @return [Boolean] whether the invoked method is a splat argument
177
+ def splat_argument?
178
+ arguments? && arguments.any?(&:splat_type?)
179
+ end
180
+
181
+ # Custom destructuring method. This can be used to normalize
182
+ # destructuring for different variations of the node.
183
+ #
184
+ # @return [Array] the different parts of the `send` node
185
+ def node_parts
186
+ [*self]
187
+ end
188
+ end
189
+ end
190
+ end