rubocop 0.46.0 → 0.47.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +77 -2
  4. data/config/default.yml +151 -74
  5. data/config/disabled.yml +9 -0
  6. data/config/enabled.yml +49 -9
  7. data/lib/rubocop.rb +36 -8
  8. data/lib/rubocop/ast/builder.rb +59 -0
  9. data/lib/rubocop/ast/node.rb +607 -0
  10. data/lib/rubocop/ast/node/array_node.rb +45 -0
  11. data/lib/rubocop/ast/node/case_node.rb +63 -0
  12. data/lib/rubocop/ast/node/for_node.rb +53 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +102 -0
  14. data/lib/rubocop/ast/node/if_node.rb +136 -0
  15. data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
  16. data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
  17. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
  18. data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
  19. data/lib/rubocop/ast/node/pair_node.rb +64 -0
  20. data/lib/rubocop/ast/node/until_node.rb +43 -0
  21. data/lib/rubocop/ast/node/when_node.rb +61 -0
  22. data/lib/rubocop/ast/node/while_node.rb +43 -0
  23. data/lib/rubocop/ast/sexp.rb +16 -0
  24. data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
  25. data/lib/rubocop/cli.rb +18 -14
  26. data/lib/rubocop/comment_config.rb +1 -3
  27. data/lib/rubocop/config.rb +93 -35
  28. data/lib/rubocop/config_loader.rb +1 -1
  29. data/lib/rubocop/cop/badge.rb +73 -0
  30. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
  32. data/lib/rubocop/cop/commissioner.rb +17 -6
  33. data/lib/rubocop/cop/cop.rb +25 -112
  34. data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
  35. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
  36. data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
  37. data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
  38. data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
  39. data/lib/rubocop/cop/lint/condition_position.rb +14 -16
  40. data/lib/rubocop/cop/lint/debugger.rb +28 -0
  41. data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
  43. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
  44. data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
  45. data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
  46. data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
  47. data/lib/rubocop/cop/lint/else_layout.rb +26 -29
  48. data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
  49. data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
  50. data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
  51. data/lib/rubocop/cop/lint/empty_when.rb +14 -16
  52. data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
  53. data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
  54. data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
  55. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
  57. data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
  58. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
  60. data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
  61. data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
  62. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
  63. data/lib/rubocop/cop/lint/loop.rb +36 -0
  64. data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
  65. data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
  66. data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
  67. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
  68. data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
  69. data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
  70. data/lib/rubocop/cop/lint/rand_one.rb +7 -3
  71. data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
  72. data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
  73. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
  75. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
  76. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
  77. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
  78. data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
  79. data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
  80. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
  81. data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
  82. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
  83. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  84. data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
  85. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
  86. data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
  87. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
  88. data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
  89. data/lib/rubocop/cop/lint/void.rb +52 -0
  90. data/lib/rubocop/cop/message_annotator.rb +102 -0
  91. data/lib/rubocop/cop/metrics/block_length.rb +6 -0
  92. data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
  93. data/lib/rubocop/cop/metrics/line_length.rb +11 -4
  94. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
  95. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
  96. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
  97. data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
  98. data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
  99. data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
  100. data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
  102. data/lib/rubocop/cop/mixin/duplication.rb +46 -0
  103. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
  105. data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
  106. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  107. data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
  108. data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
  109. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
  110. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
  111. data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
  112. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
  113. data/lib/rubocop/cop/offense.rb +1 -1
  114. data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
  115. data/lib/rubocop/cop/performance/detect.rb +2 -2
  116. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  117. data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
  118. data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
  119. data/lib/rubocop/cop/rails/delegate.rb +2 -2
  120. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
  121. data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
  122. data/lib/rubocop/cop/rails/file_path.rb +80 -0
  123. data/lib/rubocop/cop/rails/find_each.rb +5 -14
  124. data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
  125. data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
  126. data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
  127. data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
  128. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
  129. data/lib/rubocop/cop/rails/time_zone.rb +1 -1
  130. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
  131. data/lib/rubocop/cop/registry.rb +170 -0
  132. data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
  133. data/lib/rubocop/cop/security/marshal_load.rb +33 -0
  134. data/lib/rubocop/cop/security/yaml_load.rb +37 -0
  135. data/lib/rubocop/cop/style/align_hash.rb +138 -169
  136. data/lib/rubocop/cop/style/and_or.rb +1 -1
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
  138. data/lib/rubocop/cop/style/case_indentation.rb +36 -27
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
  140. data/lib/rubocop/cop/style/each_with_object.rb +4 -1
  141. data/lib/rubocop/cop/style/else_alignment.rb +14 -20
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
  143. data/lib/rubocop/cop/style/empty_else.rb +20 -22
  144. data/lib/rubocop/cop/style/empty_literal.rb +4 -4
  145. data/lib/rubocop/cop/style/empty_method.rb +12 -6
  146. data/lib/rubocop/cop/style/encoding.rb +1 -1
  147. data/lib/rubocop/cop/style/file_name.rb +24 -4
  148. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  149. data/lib/rubocop/cop/style/format_string.rb +17 -48
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
  151. data/lib/rubocop/cop/style/guard_clause.rb +11 -17
  152. data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
  153. data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
  154. data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
  155. data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
  156. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
  157. data/lib/rubocop/cop/style/indent_array.rb +1 -1
  158. data/lib/rubocop/cop/style/indentation_width.rb +29 -60
  159. data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
  160. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
  161. data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
  162. data/lib/rubocop/cop/style/missing_else.rb +40 -14
  163. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
  164. data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
  165. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
  166. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
  168. data/lib/rubocop/cop/style/negated_if.rb +3 -19
  169. data/lib/rubocop/cop/style/negated_while.rb +2 -17
  170. data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
  171. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
  172. data/lib/rubocop/cop/style/next.rb +23 -21
  173. data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
  174. data/lib/rubocop/cop/style/not.rb +1 -3
  175. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  176. data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
  177. data/lib/rubocop/cop/style/option_hash.rb +4 -15
  178. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
  179. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
  180. data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
  182. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
  183. data/lib/rubocop/cop/style/redundant_return.rb +4 -8
  184. data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
  185. data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
  186. data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
  187. data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
  188. data/lib/rubocop/cop/style/string_methods.rb +1 -3
  189. data/lib/rubocop/cop/style/symbol_array.rb +1 -5
  190. data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
  191. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  192. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
  193. data/lib/rubocop/cop/style/unless_else.rb +1 -5
  194. data/lib/rubocop/cop/style/when_then.rb +4 -2
  195. data/lib/rubocop/cop/style/while_until_do.rb +9 -13
  196. data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
  197. data/lib/rubocop/cop/style/word_array.rb +5 -9
  198. data/lib/rubocop/cop/team.rb +16 -15
  199. data/lib/rubocop/cop/util.rb +13 -3
  200. data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
  201. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  202. data/lib/rubocop/magic_comment.rb +196 -0
  203. data/lib/rubocop/options.rb +5 -4
  204. data/lib/rubocop/processed_source.rb +1 -1
  205. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  206. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  207. data/lib/rubocop/runner.rb +7 -2
  208. data/lib/rubocop/version.rb +1 -1
  209. metadata +41 -14
  210. data/lib/rubocop/ast_node.rb +0 -624
  211. data/lib/rubocop/ast_node/builder.rb +0 -30
  212. data/lib/rubocop/ast_node/sexp.rb +0 -13
  213. data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
  214. data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for nodes that have conditions:
6
+ # `if`, `while`, `until`, `case`.
7
+ # This currently doesn't include `when` nodes, because they have multiple
8
+ # conditions, and need to be checked for that.
9
+ module ConditionalNode
10
+ # Checks whether the condition of the node is written on a single line.
11
+ #
12
+ # @return [Boolean] whether the condition is on a single line
13
+ def single_line_condition?
14
+ loc.keyword.line == condition.source_range.line
15
+ end
16
+
17
+ # Checks whether the condition of the node is written on more than
18
+ # one line.
19
+ #
20
+ # @return [Boolean] whether the condition is on more than one line
21
+ def multiline_condition?
22
+ !single_line_condition?
23
+ end
24
+
25
+ # Returns the condition of the node. This works together with each node's
26
+ # custom destructuring method to select the correct part of the node.
27
+ #
28
+ # @return [Node, nil] the condition of the node
29
+ def condition
30
+ node_parts[0]
31
+ end
32
+
33
+ # Returns the body associated with the condition. This works together with
34
+ # each node's custom destructuring method to select the correct part of
35
+ # the node.
36
+ #
37
+ # @note For `if` nodes, this is the truthy branch.
38
+ #
39
+ # @return [Node, nil] the body of the node
40
+ def body
41
+ node_parts[1]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for nodes that can be used as hash elements:
6
+ # `pair`, `kwsplat`
7
+ module HashElementNode
8
+ # Returns the key of this `hash` element.
9
+ #
10
+ # @note For keyword splats, this returns the whole node
11
+ #
12
+ # @return [Node] the key of the hash element
13
+ def key
14
+ node_parts[0]
15
+ end
16
+
17
+ # Returns the value of this `hash` element.
18
+ #
19
+ # @note For keyword splats, this returns the whole node
20
+ #
21
+ # @return [Node] the value of the hash element
22
+ def value
23
+ node_parts[1]
24
+ end
25
+
26
+ # Checks whether this `hash` element is on the same line as `other`.
27
+ #
28
+ # @note A multiline element is considered to be on the same line if it
29
+ # shares any of its lines with `other`
30
+ #
31
+ # @return [Boolean] whether this element is on the same line as `other`
32
+ def same_line?(other)
33
+ loc.last_line == other.loc.line || loc.line == other.loc.last_line
34
+ end
35
+
36
+ # Returns the delta between this pair's key and the argument pair's.
37
+ #
38
+ # @note Keys on the same line always return a delta of 0
39
+ # @note Keyword splats always return a delta of 0 for right alignment
40
+ #
41
+ # @param [Symbol] alignment whether to check the left or right side
42
+ # @return [Integer] the delta between the two keys
43
+ def key_delta(other, alignment = :left)
44
+ HashElementDelta.new(self, other).key_delta(alignment)
45
+ end
46
+
47
+ # Returns the delta between this element's value and the argument's.
48
+ #
49
+ # @note Keyword splats always return a delta of 0
50
+ #
51
+ # @return [Integer] the delta between the two values
52
+ def value_delta(other)
53
+ HashElementDelta.new(self, other).value_delta
54
+ end
55
+
56
+ # Returns the delta between this element's delimiter and the argument's.
57
+ #
58
+ # @note Pairs with different delimiter styles return a delta of 0
59
+ #
60
+ # @return [Integer] the delta between the two delimiters
61
+ def delimiter_delta(other)
62
+ HashElementDelta.new(self, other).delimiter_delta
63
+ end
64
+
65
+ # A helper class for comparing the positions of different parts of a
66
+ # `pair` node.
67
+ class HashElementDelta
68
+ def initialize(first, second)
69
+ @first = first
70
+ @second = second
71
+
72
+ raise ArgumentError unless valid_argument_types?
73
+ end
74
+
75
+ def key_delta(alignment = :left)
76
+ return 0 if first.same_line?(second)
77
+ return 0 if keyword_splat? && alignment == :right
78
+
79
+ delta(first.key.loc, second.key.loc, alignment)
80
+ end
81
+
82
+ def value_delta
83
+ return 0 if first.same_line?(second)
84
+ return 0 if keyword_splat?
85
+
86
+ delta(first.value.loc, second.value.loc)
87
+ end
88
+
89
+ def delimiter_delta
90
+ return 0 if first.same_line?(second)
91
+ return 0 if first.delimiter != second.delimiter
92
+
93
+ delta(first.loc.operator, second.loc.operator)
94
+ end
95
+
96
+ private
97
+
98
+ attr_reader :first, :second
99
+
100
+ def valid_argument_types?
101
+ [first, second].all? do |argument|
102
+ argument.pair_type? || argument.kwsplat_type?
103
+ end
104
+ end
105
+
106
+ def delta(first, second, alignment = :left)
107
+ case alignment
108
+ when :left
109
+ first.column - second.column
110
+ when :right
111
+ first.last_column - second.last_column
112
+ else
113
+ 0
114
+ end
115
+ end
116
+
117
+ def keyword_splat?
118
+ [first, second].any?(&:kwsplat_type?)
119
+ end
120
+ end
121
+
122
+ private_constant :HashElementDelta
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for nodes that can be used as modifiers:
6
+ # `if`, `while`, `until`
7
+ module ModifierNode
8
+ # Checks whether the node is in a modifier form, i.e. a condition
9
+ # trailing behind an expression.
10
+ #
11
+ # @return [Boolean] whether the node is a modifier
12
+ def modifier_form?
13
+ loc.end.nil?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `pair` 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 `pair` nodes within RuboCop.
8
+ class PairNode < Node
9
+ include HashElementNode
10
+
11
+ HASH_ROCKET = '=>'.freeze
12
+ SPACED_HASH_ROCKET = ' => '.freeze
13
+ COLON = ':'.freeze
14
+ SPACED_COLON = ': '.freeze
15
+
16
+ # Checks whether the `pair` uses a hash rocket delimiter.
17
+ #
18
+ # @return [Boolean] whether this `pair` uses a hash rocket delimiter
19
+ def hash_rocket?
20
+ loc.operator.is?(HASH_ROCKET)
21
+ end
22
+
23
+ # Checks whether the `pair` uses a colon delimiter.
24
+ #
25
+ # @return [Boolean] whether this `pair` uses a colon delimiter
26
+ def colon?
27
+ loc.operator.is?(COLON)
28
+ end
29
+
30
+ # Returns the delimiter of the `pair` as a string. Returns `=>` for a
31
+ # colon delimited `pair`, and `:` for a hash rocket delimited `pair`.
32
+ #
33
+ # @param [Boolean] with_spacing whether to include spacing
34
+ # @return [String] the delimiter of the `pair`
35
+ def delimiter(with_spacing = false)
36
+ if with_spacing
37
+ hash_rocket? ? SPACED_HASH_ROCKET : SPACED_COLON
38
+ else
39
+ hash_rocket? ? HASH_ROCKET : COLON
40
+ end
41
+ end
42
+
43
+ # Returns the inverse delimiter of the `pair` as a string.
44
+ #
45
+ # @param [Boolean] with_spacing whether to include spacing
46
+ # @return [String] the inverse delimiter of the `pair`
47
+ def inverse_delimiter(with_spacing = false)
48
+ if with_spacing
49
+ hash_rocket? ? SPACED_COLON : SPACED_HASH_ROCKET
50
+ else
51
+ hash_rocket? ? COLON : HASH_ROCKET
52
+ end
53
+ end
54
+
55
+ # Custom destructuring method. This is used to normalize the branches
56
+ # for `pair` and `kwsplat` nodes, to add duck typing to `hash` elements.
57
+ #
58
+ # @return [Array<Node>] the different parts of the `pair`
59
+ def node_parts
60
+ [*self]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
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 UntilNode < Node
9
+ include ConditionalNode
10
+ include ModifierNode
11
+
12
+ # Returns the keyword of the `until` statement as a string.
13
+ #
14
+ # @return [String] the keyword of the `until` statement
15
+ def keyword
16
+ 'until'
17
+ end
18
+
19
+ # Returns the inverse keyword of the `until` node as a string.
20
+ # Returns `while` for `until` nodes and vice versa.
21
+ #
22
+ # @return [String] the inverse keyword of the `until` statement
23
+ def inverse_keyword
24
+ 'while'
25
+ end
26
+
27
+ # Checks whether the `until` node has a `do` keyword.
28
+ #
29
+ # @return [Boolean] whether the `until` node has a `do` keyword
30
+ def do?
31
+ loc.begin && loc.begin.is?('do')
32
+ end
33
+
34
+ # Custom destructuring method. This can be used to normalize
35
+ # destructuring for different variations of the node.
36
+ #
37
+ # @return [Array<Node>] the different parts of the `until` statement
38
+ def node_parts
39
+ [*self]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `when` 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 `when` nodes within RuboCop.
8
+ class WhenNode < Node
9
+ # Returns an array of all the conditions in the `when` branch.
10
+ #
11
+ # @return [Array<Node>] an array of condition nodes
12
+ def conditions
13
+ node_parts[0...-1]
14
+ end
15
+
16
+ # Calls the given block for each condition node in the `when` branch.
17
+ # If no block is given, an `Enumerator` is returned.
18
+ #
19
+ # @return [self] if a block is given
20
+ # @return [Enumerator] if no block is given
21
+ def each_condition
22
+ return conditions.to_enum(__method__) unless block_given?
23
+
24
+ conditions.each do |condition|
25
+ yield condition
26
+ end
27
+
28
+ self
29
+ end
30
+
31
+ # Returns the index of the `when` branch within the `case` statement.
32
+ #
33
+ # @return [Integer] the index of the `when` branch
34
+ def branch_index
35
+ parent.when_branches.index(self)
36
+ end
37
+
38
+ # Checks whether the `when` node has a `then` keyword.
39
+ #
40
+ # @return [Boolean] whether the `when` node has a `then` keyword
41
+ def then?
42
+ loc.begin && loc.begin.is?('then')
43
+ end
44
+
45
+ # Returns the body of the `when` node.
46
+ #
47
+ # @return [Node] the body of the `when` node
48
+ def body
49
+ node_parts[-1]
50
+ end
51
+
52
+ # Custom destructuring method. This can be used to normalize
53
+ # destructuring for different variations of the node.
54
+ #
55
+ # @return [Array<Node>] the different parts of the `until` statement
56
+ def node_parts
57
+ [*self]
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `while` 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 `while` nodes within RuboCop.
8
+ class WhileNode < Node
9
+ include ConditionalNode
10
+ include ModifierNode
11
+
12
+ # Returns the keyword of the `while` statement as a string.
13
+ #
14
+ # @return [String] the keyword of the `while` statement
15
+ def keyword
16
+ 'while'
17
+ end
18
+
19
+ # Returns the inverse keyword of the `while` node as a string.
20
+ # Returns `until` for `while` nodes and vice versa.
21
+ #
22
+ # @return [String] the inverse keyword of the `while` statement
23
+ def inverse_keyword
24
+ 'until'
25
+ end
26
+
27
+ # Checks whether the `until` node has a `do` keyword.
28
+ #
29
+ # @return [Boolean] whether the `until` node has a `do` keyword
30
+ def do?
31
+ loc.begin && loc.begin.is?('do')
32
+ end
33
+
34
+ # Custom destructuring method. This can be used to normalize
35
+ # destructuring for different variations of the node.
36
+ #
37
+ # @return [Array<Node>] the different parts of the `while` statement
38
+ def node_parts
39
+ [*self]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # This module provides a shorthand method to create a {Node} like
6
+ # `Parser::AST::Sexp`.
7
+ #
8
+ # @see http://rubydoc.info/gems/ast/AST/Sexp
9
+ module Sexp
10
+ # Creates a {Node} with type `type` and children `children`.
11
+ def s(type, *children)
12
+ Node.new(type, children)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuboCop
4
- class Node
4
+ module AST
5
5
  # Provides methods for traversing an AST.
6
6
  # Does not transform an AST; for that, use Parser::AST::Processor.
7
7
  # Override methods to perform custom processing. Remember to call `super`
@@ -104,28 +104,32 @@ module RuboCop
104
104
  def print_available_cops
105
105
  # Load the configs so the require()s are done for custom cops
106
106
  @config_store.for(Dir.pwd)
107
- cops = Cop::Cop.all
107
+ registry = Cop::Cop.registry
108
108
  show_all = @options[:show_cops].empty?
109
109
 
110
110
  if show_all
111
- puts "# Available cops (#{cops.length}) + config for #{Dir.pwd}: "
111
+ puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: "
112
112
  end
113
113
 
114
- cops.types.sort!.each { |type| print_cops_of_type(cops, type, show_all) }
114
+ registry.departments.sort!.each do |department|
115
+ print_cops_of_department(registry, department, show_all)
116
+ end
115
117
  end
116
118
 
117
- def print_cops_of_type(cops, type, show_all)
119
+ def print_cops_of_department(registry, department, show_all)
118
120
  selected_cops = if show_all
119
- cops_of_type(cops, type)
121
+ cops_of_department(registry, department)
120
122
  else
121
- selected_cops_of_type(cops, type)
123
+ selected_cops_of_department(registry, department)
122
124
  end
123
125
 
124
- if show_all
125
- puts "# Type '#{type.to_s.capitalize}' (#{selected_cops.size}):"
126
- end
126
+ puts "# Department '#{department}' (#{selected_cops.length}):" if show_all
127
+
128
+ print_cop_details(selected_cops)
129
+ end
127
130
 
128
- selected_cops.each do |cop|
131
+ def print_cop_details(cops)
132
+ cops.each do |cop|
129
133
  puts '# Supports --auto-correct' if cop.new.support_autocorrect?
130
134
  puts "#{cop.cop_name}:"
131
135
  puts config_lines(cop)
@@ -133,14 +137,14 @@ module RuboCop
133
137
  end
134
138
  end
135
139
 
136
- def selected_cops_of_type(cops, type)
137
- cops_of_type(cops, type).select do |cop|
140
+ def selected_cops_of_department(cops, department)
141
+ cops_of_department(cops, department).select do |cop|
138
142
  @options[:show_cops].include?(cop.cop_name)
139
143
  end
140
144
  end
141
145
 
142
- def cops_of_type(cops, type)
143
- cops.with_type(type).sort_by!(&:cop_name)
146
+ def cops_of_department(cops, department)
147
+ cops.with_department(department).sort!
144
148
  end
145
149
 
146
150
  def config_lines(cop)