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
@@ -50,7 +50,7 @@ shared_examples_for 'misaligned' do |prefix, alignment_base, arg, end_kw, name|
50
50
  # style. In other cases, it won't match any style at all
51
51
  expect(cop.config_to_allow_offenses).to(
52
52
  eq('Enabled' => false).or(
53
- satisfy { |h| other_styles.include?(h['AlignWith']) }
53
+ satisfy { |h| other_styles.include?(h['EnforcedStyleAlignWith']) }
54
54
  )
55
55
  )
56
56
  end
@@ -142,7 +142,12 @@ module RuboCop
142
142
 
143
143
  def autocorrect_unneeded_disables(source, cop)
144
144
  cop.processed_source = source
145
- Cop::Team.new([], nil, @options).autocorrect(source.buffer, [cop])
145
+
146
+ Cop::Team.new(
147
+ RuboCop::Cop::Registry.new,
148
+ nil,
149
+ @options
150
+ ).autocorrect(source.buffer, [cop])
146
151
  end
147
152
 
148
153
  def file_started(file)
@@ -268,7 +273,7 @@ module RuboCop
268
273
 
269
274
  cop_classes.reject! { |c| c.match?(@options[:except]) }
270
275
 
271
- cop_classes
276
+ Cop::Registry.new(cop_classes)
272
277
  end
273
278
  end
274
279
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.46.0'.freeze
6
+ STRING = '0.47.0'.freeze
7
7
 
8
8
  MSG = '%s (using Parser %s, running on %s %s %s)'.freeze
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.46.0
4
+ version: 0.47.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-11-30 00:00:00.000000000 Z
13
+ date: 2017-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rainbow
@@ -38,7 +38,7 @@ dependencies:
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 2.3.1.1
41
+ version: 2.3.3.1
42
42
  - - "<"
43
43
  - !ruby/object:Gem::Version
44
44
  version: '3.0'
@@ -48,7 +48,7 @@ dependencies:
48
48
  requirements:
49
49
  - - ">="
50
50
  - !ruby/object:Gem::Version
51
- version: 2.3.1.1
51
+ version: 2.3.3.1
52
52
  - - "<"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
@@ -134,10 +134,23 @@ files:
134
134
  - config/disabled.yml
135
135
  - config/enabled.yml
136
136
  - lib/rubocop.rb
137
- - lib/rubocop/ast_node.rb
138
- - lib/rubocop/ast_node/builder.rb
139
- - lib/rubocop/ast_node/sexp.rb
140
- - lib/rubocop/ast_node/traversal.rb
137
+ - lib/rubocop/ast/builder.rb
138
+ - lib/rubocop/ast/node.rb
139
+ - lib/rubocop/ast/node/array_node.rb
140
+ - lib/rubocop/ast/node/case_node.rb
141
+ - lib/rubocop/ast/node/for_node.rb
142
+ - lib/rubocop/ast/node/hash_node.rb
143
+ - lib/rubocop/ast/node/if_node.rb
144
+ - lib/rubocop/ast/node/keyword_splat_node.rb
145
+ - lib/rubocop/ast/node/mixin/conditional_node.rb
146
+ - lib/rubocop/ast/node/mixin/hash_element_node.rb
147
+ - lib/rubocop/ast/node/mixin/modifier_node.rb
148
+ - lib/rubocop/ast/node/pair_node.rb
149
+ - lib/rubocop/ast/node/until_node.rb
150
+ - lib/rubocop/ast/node/when_node.rb
151
+ - lib/rubocop/ast/node/while_node.rb
152
+ - lib/rubocop/ast/sexp.rb
153
+ - lib/rubocop/ast/traversal.rb
141
154
  - lib/rubocop/cached_data.rb
142
155
  - lib/rubocop/cli.rb
143
156
  - lib/rubocop/comment_config.rb
@@ -146,6 +159,7 @@ files:
146
159
  - lib/rubocop/config_loader_resolver.rb
147
160
  - lib/rubocop/config_store.rb
148
161
  - lib/rubocop/cop/autocorrect_logic.rb
162
+ - lib/rubocop/cop/badge.rb
149
163
  - lib/rubocop/cop/bundler/duplicated_gem.rb
150
164
  - lib/rubocop/cop/bundler/ordered_gems.rb
151
165
  - lib/rubocop/cop/commissioner.rb
@@ -174,7 +188,6 @@ files:
174
188
  - lib/rubocop/cop/lint/end_alignment.rb
175
189
  - lib/rubocop/cop/lint/end_in_method.rb
176
190
  - lib/rubocop/cop/lint/ensure_return.rb
177
- - lib/rubocop/cop/lint/eval.rb
178
191
  - lib/rubocop/cop/lint/float_out_of_range.rb
179
192
  - lib/rubocop/cop/lint/format_parameter_mismatch.rb
180
193
  - lib/rubocop/cop/lint/handle_exceptions.rb
@@ -185,6 +198,7 @@ files:
185
198
  - lib/rubocop/cop/lint/literal_in_condition.rb
186
199
  - lib/rubocop/cop/lint/literal_in_interpolation.rb
187
200
  - lib/rubocop/cop/lint/loop.rb
201
+ - lib/rubocop/cop/lint/multiple_compare.rb
188
202
  - lib/rubocop/cop/lint/nested_method_definition.rb
189
203
  - lib/rubocop/cop/lint/next_without_accumulator.rb
190
204
  - lib/rubocop/cop/lint/non_local_exit_from_iterator.rb
@@ -194,6 +208,7 @@ files:
194
208
  - lib/rubocop/cop/lint/rand_one.rb
195
209
  - lib/rubocop/cop/lint/require_parentheses.rb
196
210
  - lib/rubocop/cop/lint/rescue_exception.rb
211
+ - lib/rubocop/cop/lint/safe_navigation_chain.rb
197
212
  - lib/rubocop/cop/lint/shadowed_exception.rb
198
213
  - lib/rubocop/cop/lint/shadowing_outer_local_variable.rb
199
214
  - lib/rubocop/cop/lint/string_conversion_in_interpolation.rb
@@ -211,6 +226,7 @@ files:
211
226
  - lib/rubocop/cop/lint/useless_else_without_rescue.rb
212
227
  - lib/rubocop/cop/lint/useless_setter_call.rb
213
228
  - lib/rubocop/cop/lint/void.rb
229
+ - lib/rubocop/cop/message_annotator.rb
214
230
  - lib/rubocop/cop/metrics/abc_size.rb
215
231
  - lib/rubocop/cop/metrics/block_length.rb
216
232
  - lib/rubocop/cop/metrics/block_nesting.rb
@@ -230,17 +246,18 @@ files:
230
246
  - lib/rubocop/cop/mixin/classish_length.rb
231
247
  - lib/rubocop/cop/mixin/code_length.rb
232
248
  - lib/rubocop/cop/mixin/configurable_enforced_style.rb
249
+ - lib/rubocop/cop/mixin/configurable_formatting.rb
233
250
  - lib/rubocop/cop/mixin/configurable_max.rb
234
251
  - lib/rubocop/cop/mixin/configurable_naming.rb
235
252
  - lib/rubocop/cop/mixin/configurable_numbering.rb
236
253
  - lib/rubocop/cop/mixin/def_node.rb
237
254
  - lib/rubocop/cop/mixin/documentation_comment.rb
255
+ - lib/rubocop/cop/mixin/duplication.rb
238
256
  - lib/rubocop/cop/mixin/empty_lines_around_body.rb
239
257
  - lib/rubocop/cop/mixin/end_keyword_alignment.rb
240
258
  - lib/rubocop/cop/mixin/first_element_line_break.rb
241
259
  - lib/rubocop/cop/mixin/frozen_string_literal.rb
242
- - lib/rubocop/cop/mixin/hash_node.rb
243
- - lib/rubocop/cop/mixin/if_node.rb
260
+ - lib/rubocop/cop/mixin/hash_alignment.rb
244
261
  - lib/rubocop/cop/mixin/integer_node.rb
245
262
  - lib/rubocop/cop/mixin/match_range.rb
246
263
  - lib/rubocop/cop/mixin/method_complexity.rb
@@ -264,6 +281,7 @@ files:
264
281
  - lib/rubocop/cop/mixin/string_help.rb
265
282
  - lib/rubocop/cop/mixin/string_literals_help.rb
266
283
  - lib/rubocop/cop/mixin/surrounding_space.rb
284
+ - lib/rubocop/cop/mixin/target_ruby_version.rb
267
285
  - lib/rubocop/cop/mixin/too_many_lines.rb
268
286
  - lib/rubocop/cop/mixin/trailing_comma.rb
269
287
  - lib/rubocop/cop/mixin/unused_argument.rb
@@ -284,6 +302,7 @@ files:
284
302
  - lib/rubocop/cop/performance/redundant_match.rb
285
303
  - lib/rubocop/cop/performance/redundant_merge.rb
286
304
  - lib/rubocop/cop/performance/redundant_sort_by.rb
305
+ - lib/rubocop/cop/performance/regexp_match.rb
287
306
  - lib/rubocop/cop/performance/reverse_each.rb
288
307
  - lib/rubocop/cop/performance/sample.rb
289
308
  - lib/rubocop/cop/performance/size.rb
@@ -297,6 +316,7 @@ files:
297
316
  - lib/rubocop/cop/rails/dynamic_find_by.rb
298
317
  - lib/rubocop/cop/rails/enum_uniqueness.rb
299
318
  - lib/rubocop/cop/rails/exit.rb
319
+ - lib/rubocop/cop/rails/file_path.rb
300
320
  - lib/rubocop/cop/rails/find_by.rb
301
321
  - lib/rubocop/cop/rails/find_each.rb
302
322
  - lib/rubocop/cop/rails/has_and_belongs_to_many.rb
@@ -307,13 +327,19 @@ files:
307
327
  - lib/rubocop/cop/rails/pluralization_grammar.rb
308
328
  - lib/rubocop/cop/rails/read_write_attribute.rb
309
329
  - lib/rubocop/cop/rails/request_referer.rb
330
+ - lib/rubocop/cop/rails/reversible_migration.rb
310
331
  - lib/rubocop/cop/rails/safe_navigation.rb
311
332
  - lib/rubocop/cop/rails/save_bang.rb
312
333
  - lib/rubocop/cop/rails/scope_args.rb
334
+ - lib/rubocop/cop/rails/skips_model_validations.rb
313
335
  - lib/rubocop/cop/rails/time_zone.rb
314
336
  - lib/rubocop/cop/rails/uniq_before_pluck.rb
315
337
  - lib/rubocop/cop/rails/validation.rb
338
+ - lib/rubocop/cop/registry.rb
339
+ - lib/rubocop/cop/security/eval.rb
316
340
  - lib/rubocop/cop/security/json_load.rb
341
+ - lib/rubocop/cop/security/marshal_load.rb
342
+ - lib/rubocop/cop/security/yaml_load.rb
317
343
  - lib/rubocop/cop/severity.rb
318
344
  - lib/rubocop/cop/style/access_modifier_indentation.rb
319
345
  - lib/rubocop/cop/style/accessor_method_name.rb
@@ -405,7 +431,8 @@ files:
405
431
  - lib/rubocop/cop/style/lambda_call.rb
406
432
  - lib/rubocop/cop/style/leading_comment_space.rb
407
433
  - lib/rubocop/cop/style/line_end_concatenation.rb
408
- - lib/rubocop/cop/style/method_call_parentheses.rb
434
+ - lib/rubocop/cop/style/method_call_with_args_parentheses.rb
435
+ - lib/rubocop/cop/style/method_call_without_args_parentheses.rb
409
436
  - lib/rubocop/cop/style/method_called_on_do_end_block.rb
410
437
  - lib/rubocop/cop/style/method_def_parentheses.rb
411
438
  - lib/rubocop/cop/style/method_missing.rb
@@ -545,6 +572,7 @@ files:
545
572
  - lib/rubocop/formatter/simple_text_formatter.rb
546
573
  - lib/rubocop/formatter/text_util.rb
547
574
  - lib/rubocop/formatter/worst_offenders_formatter.rb
575
+ - lib/rubocop/magic_comment.rb
548
576
  - lib/rubocop/name_similarity.rb
549
577
  - lib/rubocop/node_pattern.rb
550
578
  - lib/rubocop/options.rb
@@ -585,9 +613,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
585
613
  version: '0'
586
614
  requirements: []
587
615
  rubyforge_project:
588
- rubygems_version: 2.4.5
616
+ rubygems_version: 2.5.2
589
617
  signing_key:
590
618
  specification_version: 4
591
619
  summary: Automatic Ruby code style checking tool.
592
620
  test_files: []
593
- has_rdoc:
@@ -1,624 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- # `RuboCop::Node` is a subclass of `Parser::AST::Node`. It provides access to
5
- # parent nodes and an object-oriented way to traverse an AST with the power
6
- # of `Enumerable`.
7
- #
8
- # It has predicate methods for every node type, like this:
9
- #
10
- # @example
11
- # node.send_type? # Equivalent to: `node.type == :send`
12
- # node.op_asgn_type? # Equivalent to: `node.type == :op_asgn`
13
- #
14
- # # Non-word characters (other than a-zA-Z0-9_) in type names are omitted.
15
- # node.defined_type? # Equivalent to: `node.type == :defined?`
16
- #
17
- # # Find the first lvar node under the receiver node.
18
- # lvar_node = node.each_descendant.find(&:lvar_type?)
19
- #
20
- class Node < Parser::AST::Node # rubocop:disable Metrics/ClassLength
21
- include RuboCop::Sexp
22
-
23
- COMPARISON_OPERATORS = [:!, :==, :===, :!=, :<=, :>=, :>, :<, :<=>].freeze
24
-
25
- TRUTHY_LITERALS = [:str, :dstr, :xstr, :int, :float, :sym, :dsym, :array,
26
- :hash, :regexp, :true, :irange, :erange, :complex,
27
- :rational, :regopt].freeze
28
- FALSEY_LITERALS = [:false, :nil].freeze
29
- LITERALS = (TRUTHY_LITERALS + FALSEY_LITERALS).freeze
30
- COMPOSITE_LITERALS = [:dstr, :xstr, :dsym, :array, :hash, :irange,
31
- :erange, :regexp].freeze
32
- BASIC_LITERALS = (LITERALS - COMPOSITE_LITERALS).freeze
33
- MUTABLE_LITERALS = [:str, :dstr, :xstr, :array, :hash].freeze
34
- IMMUTABLE_LITERALS = (LITERALS - MUTABLE_LITERALS).freeze
35
-
36
- VARIABLES = [:ivar, :gvar, :cvar, :lvar].freeze
37
- REFERENCES = [:nth_ref, :back_ref].freeze
38
- KEYWORDS = [:alias, :and, :break, :case, :class, :def, :defs, :defined?,
39
- :kwbegin, :do, :else, :ensure, :for, :if, :module, :next, :not,
40
- :or, :postexe, :redo, :rescue, :retry, :return, :self, :super,
41
- :zsuper, :then, :undef, :until, :when, :while, :yield].freeze
42
- OPERATOR_KEYWORDS = [:and, :or].freeze
43
- SPECIAL_KEYWORDS = %w(__FILE__ __LINE__ __ENCODING__).freeze
44
-
45
- # def_matcher can be used to define a pattern-matching method on Node
46
- class << self
47
- def def_matcher(method_name, pattern_str)
48
- compiler = RuboCop::NodePattern::Compiler.new(pattern_str, 'self')
49
- src = "def #{method_name}(" \
50
- "#{compiler.emit_param_list});" \
51
- "#{compiler.emit_method_code};end"
52
-
53
- file, lineno = *caller.first.split(':')
54
- class_eval(src, file, lineno.to_i)
55
- end
56
- end
57
-
58
- # @see http://rubydoc.info/gems/ast/AST/Node:initialize
59
- def initialize(type, children = [], properties = {})
60
- @mutable_attributes = {}
61
-
62
- # ::AST::Node#initialize freezes itself.
63
- super
64
-
65
- # #parent= may be invoked multiple times for a node because there are
66
- # pending nodes while constructing AST and they are replaced later.
67
- # For example, `lvar` and `send` type nodes are initially created as an
68
- # `ident` type node and fixed to the appropriate type later.
69
- # So, the #parent attribute needs to be mutable.
70
- each_child_node do |child_node|
71
- child_node.parent = self unless child_node.complete?
72
- end
73
- end
74
-
75
- Parser::Meta::NODE_TYPES.each do |node_type|
76
- method_name = "#{node_type.to_s.gsub(/\W/, '')}_type?"
77
- define_method(method_name) do
78
- type == node_type
79
- end
80
- end
81
-
82
- # Returns the parent node, or `nil` if the receiver is a root node.
83
- #
84
- # @return [Node, nil] the parent node or `nil`
85
- def parent
86
- @mutable_attributes[:parent]
87
- end
88
-
89
- def parent=(node)
90
- @mutable_attributes[:parent] = node
91
- end
92
-
93
- def complete!
94
- @mutable_attributes.freeze
95
- each_child_node(&:complete!)
96
- end
97
-
98
- def complete?
99
- @mutable_attributes.frozen?
100
- end
101
-
102
- protected :parent=
103
-
104
- # Override `AST::Node#updated` so that `AST::Processor` does not try to
105
- # mutate our ASTs. Since we keep references from children to parents and
106
- # not just the other way around, we cannot update an AST and share identical
107
- # subtrees. Rather, the entire AST must be copied any time any part of it
108
- # is changed.
109
- #
110
- def updated(type = nil, children = nil, properties = {})
111
- properties[:location] ||= @location
112
- Node.new(type || @type, children || @children, properties)
113
- end
114
-
115
- # Returns the index of the receiver node in its siblings. (Sibling index
116
- # uses zero based numbering.)
117
- #
118
- # @return [Integer] the index of the receiver node in its siblings
119
- def sibling_index
120
- parent.children.index { |sibling| sibling.equal?(self) }
121
- end
122
-
123
- # Calls the given block for each ancestor node from parent to root.
124
- # If no block is given, an `Enumerator` is returned.
125
- #
126
- # @overload each_ancestor
127
- # Yield all nodes.
128
- # @overload each_ancestor(type)
129
- # Yield only nodes matching the type.
130
- # @param [Symbol] type a node type
131
- # @overload each_ancestor(type_a, type_b, ...)
132
- # Yield only nodes matching any of the types.
133
- # @param [Symbol] type_a a node type
134
- # @param [Symbol] type_b a node type
135
- # @overload each_ancestor(types)
136
- # Yield only nodes matching any of types in the array.
137
- # @param [Array<Symbol>] types an array containing node types
138
- # @yieldparam [Node] node each ancestor node
139
- # @return [self] if a block is given
140
- # @return [Enumerator] if no block is given
141
- def each_ancestor(*types, &block)
142
- return to_enum(__method__, *types) unless block_given?
143
-
144
- if types.empty?
145
- visit_ancestors(&block)
146
- else
147
- visit_ancestors_with_types(types, &block)
148
- end
149
-
150
- self
151
- end
152
-
153
- # Returns an array of ancestor nodes.
154
- # This is a shorthand for `node.each_ancestor.to_a`.
155
- #
156
- # @return [Array<Node>] an array of ancestor nodes
157
- def ancestors
158
- each_ancestor.to_a
159
- end
160
-
161
- # Calls the given block for each child node.
162
- # If no block is given, an `Enumerator` is returned.
163
- #
164
- # Note that this is different from `node.children.each { |child| ... }`
165
- # which yields all children including non-node elements.
166
- #
167
- # @overload each_child_node
168
- # Yield all nodes.
169
- # @overload each_child_node(type)
170
- # Yield only nodes matching the type.
171
- # @param [Symbol] type a node type
172
- # @overload each_child_node(type_a, type_b, ...)
173
- # Yield only nodes matching any of the types.
174
- # @param [Symbol] type_a a node type
175
- # @param [Symbol] type_b a node type
176
- # @overload each_child_node(types)
177
- # Yield only nodes matching any of types in the array.
178
- # @param [Array<Symbol>] types an array containing node types
179
- # @yieldparam [Node] node each child node
180
- # @return [self] if a block is given
181
- # @return [Enumerator] if no block is given
182
- def each_child_node(*types)
183
- return to_enum(__method__, *types) unless block_given?
184
-
185
- children.each do |child|
186
- next unless child.is_a?(Node)
187
- yield child if types.empty? || types.include?(child.type)
188
- end
189
-
190
- self
191
- end
192
-
193
- # Returns an array of child nodes.
194
- # This is a shorthand for `node.each_child_node.to_a`.
195
- #
196
- # @return [Array<Node>] an array of child nodes
197
- def child_nodes
198
- each_child_node.to_a
199
- end
200
-
201
- # Calls the given block for each descendant node with depth first order.
202
- # If no block is given, an `Enumerator` is returned.
203
- #
204
- # @overload each_descendant
205
- # Yield all nodes.
206
- # @overload each_descendant(type)
207
- # Yield only nodes matching the type.
208
- # @param [Symbol] type a node type
209
- # @overload each_descendant(type_a, type_b, ...)
210
- # Yield only nodes matching any of the types.
211
- # @param [Symbol] type_a a node type
212
- # @param [Symbol] type_b a node type
213
- # @overload each_descendant(types)
214
- # Yield only nodes matching any of types in the array.
215
- # @param [Array<Symbol>] types an array containing node types
216
- # @yieldparam [Node] node each descendant node
217
- # @return [self] if a block is given
218
- # @return [Enumerator] if no block is given
219
- def each_descendant(*types, &block)
220
- return to_enum(__method__, *types) unless block_given?
221
-
222
- if types.empty?
223
- visit_descendants(&block)
224
- else
225
- visit_descendants_with_types(types, &block)
226
- end
227
-
228
- self
229
- end
230
-
231
- # Returns an array of descendant nodes.
232
- # This is a shorthand for `node.each_descendant.to_a`.
233
- #
234
- # @return [Array<Node>] an array of descendant nodes
235
- def descendants
236
- each_descendant.to_a
237
- end
238
-
239
- # Calls the given block for the receiver and each descendant node in
240
- # depth-first order.
241
- # If no block is given, an `Enumerator` is returned.
242
- #
243
- # This method would be useful when you treat the receiver node as the root
244
- # of a tree and want to iterate over all nodes in the tree.
245
- #
246
- # @overload each_node
247
- # Yield all nodes.
248
- # @overload each_node(type)
249
- # Yield only nodes matching the type.
250
- # @param [Symbol] type a node type
251
- # @overload each_node(type_a, type_b, ...)
252
- # Yield only nodes matching any of the types.
253
- # @param [Symbol] type_a a node type
254
- # @param [Symbol] type_b a node type
255
- # @overload each_node(types)
256
- # Yield only nodes matching any of types in the array.
257
- # @param [Array<Symbol>] types an array containing node types
258
- # @yieldparam [Node] node each node
259
- # @return [self] if a block is given
260
- # @return [Enumerator] if no block is given
261
- def each_node(*types, &block)
262
- return to_enum(__method__, *types) unless block_given?
263
-
264
- yield self if types.empty? || types.include?(type)
265
-
266
- if types.empty?
267
- visit_descendants(&block)
268
- else
269
- visit_descendants_with_types(types, &block)
270
- end
271
-
272
- self
273
- end
274
-
275
- def source
276
- loc.expression.source
277
- end
278
-
279
- def source_range
280
- loc.expression
281
- end
282
-
283
- ## Destructuring
284
-
285
- def_matcher :receiver, '{(send $_ ...) (block (send $_ ...) ...)}'
286
- def_matcher :method_name, '{(send _ $_ ...) (block (send _ $_ ...) ...)}'
287
- def_matcher :method_args, '{(send _ _ $...) (block (send _ _ $...) ...)}'
288
- # Note: for masgn, #asgn_rhs will be an array node
289
- def_matcher :asgn_rhs, '[assignment? (... $_)]'
290
- def_matcher :str_content, '(str $_)'
291
-
292
- def const_name
293
- return unless const_type?
294
- namespace, name = *self
295
- if namespace && !namespace.cbase_type?
296
- "#{namespace.const_name}::#{name}"
297
- else
298
- name.to_s
299
- end
300
- end
301
-
302
- def_matcher :defined_module0, <<-PATTERN
303
- {(class (const $_ $_) ...)
304
- (module (const $_ $_) ...)
305
- (casgn $_ $_ (send (const nil {:Class :Module}) :new ...))
306
- (casgn $_ $_ (block (send (const nil {:Class :Module}) :new ...) ...))}
307
- PATTERN
308
- private :defined_module0
309
-
310
- def defined_module
311
- namespace, name = *defined_module0
312
- s(:const, namespace, name) if name
313
- end
314
-
315
- def defined_module_name
316
- (const = defined_module) && const.const_name
317
- end
318
-
319
- ## Searching the AST
320
-
321
- def parent_module_name
322
- # what class or module is this method/constant/etc definition in?
323
- # returns nil if answer cannot be determined
324
- ancestors = each_ancestor(:class, :module, :sclass, :casgn, :block)
325
- result = ancestors.map do |ancestor|
326
- parent_module_name_part(ancestor) { |full_name| return full_name }
327
- end.compact.reverse.join('::')
328
- result.empty? ? 'Object' : result
329
- end
330
-
331
- ## Predicates
332
-
333
- def modifier_form?
334
- loc.respond_to?(:end) && loc.end.nil?
335
- end
336
-
337
- def multiline?
338
- expr = loc.expression
339
- expr && (expr.first_line != expr.last_line)
340
- end
341
-
342
- def single_line?
343
- !multiline?
344
- end
345
-
346
- def asgn_method_call?
347
- !COMPARISON_OPERATORS.include?(method_name) &&
348
- method_name.to_s.end_with?('='.freeze)
349
- end
350
-
351
- def_matcher :equals_asgn?, '{lvasgn ivasgn cvasgn gvasgn casgn masgn}'
352
- def_matcher :shorthand_asgn?, '{op_asgn or_asgn and_asgn}'
353
- def_matcher :assignment?, '{equals_asgn? shorthand_asgn? asgn_method_call?}'
354
-
355
- def literal?
356
- LITERALS.include?(type)
357
- end
358
-
359
- def basic_literal?
360
- BASIC_LITERALS.include?(type)
361
- end
362
-
363
- def truthy_literal?
364
- TRUTHY_LITERALS.include?(type)
365
- end
366
-
367
- def falsey_literal?
368
- FALSEY_LITERALS.include?(type)
369
- end
370
-
371
- def mutable_literal?
372
- MUTABLE_LITERALS.include?(type)
373
- end
374
-
375
- def immutable_literal?
376
- IMMUTABLE_LITERALS.include?(type)
377
- end
378
-
379
- [:literal, :basic_literal].each do |kind|
380
- recursive_kind = :"recursive_#{kind}?"
381
- kind_filter = :"#{kind}?"
382
- define_method(recursive_kind) do
383
- case type
384
- when :send
385
- receiver, method_name, *args = *self
386
- COMPARISON_OPERATORS.include?(method_name) &&
387
- receiver.send(recursive_kind) &&
388
- args.all?(&recursive_kind)
389
- when :begin, :pair, *OPERATOR_KEYWORDS, *COMPOSITE_LITERALS
390
- children.all?(&recursive_kind)
391
- else
392
- send(kind_filter)
393
- end
394
- end
395
- end
396
-
397
- def variable?
398
- VARIABLES.include?(type)
399
- end
400
-
401
- def reference?
402
- REFERENCES.include?(type)
403
- end
404
-
405
- def keyword?
406
- return true if special_keyword? || keyword_not?
407
- return false unless KEYWORDS.include?(type)
408
-
409
- !OPERATOR_KEYWORDS.include?(type) || loc.operator.is?(type.to_s)
410
- end
411
-
412
- def special_keyword?
413
- SPECIAL_KEYWORDS.include?(source)
414
- end
415
-
416
- def keyword_not?
417
- _receiver, method_name, *args = *self
418
- args.empty? && method_name == :! && loc.selector.is?('not'.freeze)
419
- end
420
-
421
- def keyword_bang?
422
- _receiver, method_name, *args = *self
423
- args.empty? && method_name == :! && loc.selector.is?('!'.freeze)
424
- end
425
-
426
- def unary_operation?
427
- return false unless loc.respond_to?(:selector) && loc.selector
428
- Cop::Util.operator?(loc.selector.source.to_sym) &&
429
- source_range.begin_pos == loc.selector.begin_pos
430
- end
431
-
432
- def binary_operation?
433
- return false unless loc.respond_to?(:selector) && loc.selector
434
- Cop::Util.operator?(method_name) &&
435
- source_range.begin_pos != loc.selector.begin_pos
436
- end
437
-
438
- def chained?
439
- return false if parent.nil? || !parent.send_type?
440
- receiver, _method_name, *_args = *parent
441
- equal?(receiver)
442
- end
443
-
444
- def_matcher :command?, '(send nil %1 ...)'
445
- def_matcher :lambda?, '(block (send nil :lambda) ...)'
446
- def_matcher :proc?, <<-PATTERN
447
- {(block (send nil :proc) ...)
448
- (block (send (const nil :Proc) :new) ...)
449
- (send (const nil :Proc) :new)}
450
- PATTERN
451
- def_matcher :lambda_or_proc?, '{lambda? proc?}'
452
-
453
- def_matcher :class_constructor?, <<-PATTERN
454
- { (send (const nil {:Class :Module}) :new ...)
455
- (block (send (const nil {:Class :Module}) :new ...) ...)}
456
- PATTERN
457
-
458
- def_matcher :module_definition?, <<-PATTERN
459
- {class module (casgn _ _ class_constructor?)}
460
- PATTERN
461
-
462
- # Some expressions are evaluated for their value, some for their side
463
- # effects, and some for both
464
- # If we know that an expression is useful only for its side effects, that
465
- # means we can transform it in ways which preserve the side effects, but
466
- # change the return value
467
- # So, does the return value of this node matter? If we changed it to
468
- # `(...; nil)`, might that affect anything?
469
- #
470
- # rubocop:disable Metrics/MethodLength
471
- def value_used?
472
- # Be conservative and return true if we're not sure
473
- return false if parent.nil?
474
-
475
- case parent.type
476
- when :array, :defined?, :dstr, :dsym, :eflipflop, :erange, :float,
477
- :hash, :iflipflop, :irange, :not, :pair, :regexp, :str, :sym, :when,
478
- :xstr
479
- parent.value_used?
480
- when :begin, :kwbegin
481
- begin_value_used?
482
- when :for
483
- for_value_used?
484
- when :case, :if
485
- case_if_value_used?
486
- when :while, :until, :while_post, :until_post
487
- while_until_value_used?
488
- else
489
- true
490
- end
491
- end
492
- # rubocop:enable Metrics/MethodLength
493
-
494
- # Some expressions are evaluated for their value, some for their side
495
- # effects, and some for both
496
- # If we know that expressions are useful only for their return values, and
497
- # have no side effects, that means we can reorder them, change the number
498
- # of times they are evaluated, or replace them with other expressions which
499
- # are equivalent in value
500
- # So, is evaluation of this node free of side effects?
501
- #
502
- def pure?
503
- # Be conservative and return false if we're not sure
504
- case type
505
- when :__FILE__, :__LINE__, :const, :cvar, :defined?, :false, :float,
506
- :gvar, :int, :ivar, :lvar, :nil, :str, :sym, :true, :regopt
507
- true
508
- when :and, :array, :begin, :case, :dstr, :dsym, :eflipflop, :ensure,
509
- :erange, :for, :hash, :if, :iflipflop, :irange, :kwbegin, :not, :or,
510
- :pair, :regexp, :until, :until_post, :when, :while, :while_post
511
- child_nodes.all?(&:pure?)
512
- else
513
- false
514
- end
515
- end
516
-
517
- protected
518
-
519
- def visit_descendants(&block)
520
- children.each do |child|
521
- next unless child.is_a?(Node)
522
- yield child
523
- child.visit_descendants(&block)
524
- end
525
- end
526
-
527
- def visit_descendants_with_types(types, &block)
528
- children.each do |child|
529
- next unless child.is_a?(Node)
530
- yield child if types.include?(child.type)
531
- child.visit_descendants_with_types(types, &block)
532
- end
533
- end
534
-
535
- private
536
-
537
- def visit_ancestors
538
- last_node = self
539
-
540
- while (current_node = last_node.parent)
541
- yield current_node
542
- last_node = current_node
543
- end
544
- end
545
-
546
- def visit_ancestors_with_types(types)
547
- last_node = self
548
-
549
- while (current_node = last_node.parent)
550
- yield current_node if types.include?(current_node.type)
551
- last_node = current_node
552
- end
553
- end
554
-
555
- def begin_value_used?
556
- # the last child node determines the value of the parent
557
- sibling_index == parent.children.size - 1 ? parent.value_used? : false
558
- end
559
-
560
- def for_value_used?
561
- # `for var in enum; body; end`
562
- # (for <var> <enum> <body>)
563
- sibling_index == 2 ? parent.value_used? : true
564
- end
565
-
566
- def case_if_value_used?
567
- # (case <condition> <when...>)
568
- # (if <condition> <truebranch> <falsebranch>)
569
- sibling_index.zero? ? true : parent.value_used?
570
- end
571
-
572
- def while_until_value_used?
573
- # (while <condition> <body>) -> always evaluates to `nil`
574
- sibling_index.zero?
575
- end
576
-
577
- def parent_module_name_part(node)
578
- case node.type
579
- when :class, :module, :casgn
580
- # TODO: if constant name has cbase (leading ::), then we don't need
581
- # to keep traversing up through nested classes/modules
582
- node.defined_module_name
583
- when :sclass
584
- yield parent_module_name_for_sclass(node)
585
- else # block
586
- parent_module_name_for_block(node) { yield nil }
587
- end
588
- end
589
-
590
- def parent_module_name_for_sclass(sclass_node)
591
- # TODO: look for constant definition and see if it is nested
592
- # inside a class or module
593
- subject = sclass_node.children[0]
594
-
595
- if subject.const_type?
596
- "#<Class:#{subject.const_name}>"
597
- elsif subject.self_type?
598
- "#<Class:#{sclass_node.parent_module_name}>"
599
- end
600
- end
601
-
602
- def parent_module_name_for_block(ancestor)
603
- if ancestor.method_name == :class_eval
604
- # `class_eval` with no receiver applies to whatever module or class
605
- # we are currently in
606
- return unless (receiver = ancestor.receiver)
607
- yield unless receiver.const_type?
608
- receiver.const_name
609
- elsif !new_class_or_module_block?(ancestor)
610
- yield
611
- end
612
- end
613
-
614
- def new_class_or_module_block?(block_node)
615
- receiver = block_node.receiver
616
-
617
- block_node.method_name == :new &&
618
- receiver && receiver.const_type? &&
619
- (receiver.const_name == 'Class' || receiver.const_name == 'Module') &&
620
- block_node.parent &&
621
- block_node.parent.casgn_type?
622
- end
623
- end
624
- end