rubocop 0.82.0 → 0.86.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (280) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -19
  3. data/config/default.yml +111 -23
  4. data/lib/rubocop.rb +16 -59
  5. data/lib/rubocop/ast_aliases.rb +8 -0
  6. data/lib/rubocop/cli.rb +3 -3
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
  8. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +2 -6
  10. data/lib/rubocop/comment_config.rb +1 -1
  11. data/lib/rubocop/config.rb +6 -2
  12. data/lib/rubocop/config_loader.rb +19 -24
  13. data/lib/rubocop/config_loader_resolver.rb +45 -6
  14. data/lib/rubocop/config_store.rb +12 -2
  15. data/lib/rubocop/config_validator.rb +2 -1
  16. data/lib/rubocop/cop/autocorrect_logic.rb +1 -2
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +70 -1
  18. data/lib/rubocop/cop/commissioner.rb +0 -21
  19. data/lib/rubocop/cop/cop.rb +36 -21
  20. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -6
  21. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  23. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -3
  24. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  25. data/lib/rubocop/cop/generator.rb +4 -3
  26. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  27. data/lib/rubocop/cop/ignored_node.rb +1 -3
  28. data/lib/rubocop/cop/layout/case_indentation.rb +3 -3
  29. data/lib/rubocop/cop/layout/class_structure.rb +19 -16
  30. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
  31. data/lib/rubocop/cop/layout/condition_position.rb +12 -2
  32. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -6
  34. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +128 -0
  35. data/lib/rubocop/cop/layout/end_of_line.rb +3 -3
  36. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -4
  37. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -3
  38. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  39. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -3
  40. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  41. data/lib/rubocop/cop/layout/hash_alignment.rb +7 -7
  42. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -7
  43. data/lib/rubocop/cop/layout/heredoc_indentation.rb +20 -103
  44. data/lib/rubocop/cop/layout/indentation_width.rb +1 -3
  45. data/lib/rubocop/cop/layout/line_length.rb +21 -18
  46. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  47. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -3
  48. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +13 -4
  49. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  51. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -3
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -2
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  54. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  55. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
  56. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  57. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  58. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -3
  59. data/lib/rubocop/cop/layout/trailing_whitespace.rb +2 -2
  60. data/lib/rubocop/cop/lint/ambiguous_operator.rb +41 -0
  61. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +14 -0
  62. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  63. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +137 -0
  64. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -5
  65. data/lib/rubocop/cop/lint/empty_when.rb +29 -6
  66. data/lib/rubocop/cop/lint/ensure_return.rb +19 -2
  67. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -3
  68. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  69. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
  70. data/lib/rubocop/cop/lint/literal_as_condition.rb +10 -13
  71. data/lib/rubocop/cop/lint/loop.rb +1 -1
  72. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +69 -0
  73. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  74. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +7 -7
  75. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +33 -11
  76. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -4
  77. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  78. data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
  79. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +5 -8
  80. data/lib/rubocop/cop/lint/redundant_require_statement.rb +3 -3
  81. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  82. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  83. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  84. data/lib/rubocop/cop/lint/suppressed_exception.rb +11 -4
  85. data/lib/rubocop/cop/lint/syntax.rb +1 -3
  86. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  87. data/lib/rubocop/cop/lint/useless_access_modifier.rb +13 -3
  88. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -2
  89. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -1
  90. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  91. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
  92. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  93. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  94. data/lib/rubocop/cop/migration/department_name.rb +7 -7
  95. data/lib/rubocop/cop/mixin/alignment.rb +1 -3
  96. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -3
  97. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -9
  98. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -3
  99. data/lib/rubocop/cop/mixin/configurable_formatting.rb +2 -4
  100. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  102. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  103. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +10 -1
  105. data/lib/rubocop/cop/mixin/hash_transform_method.rb +8 -1
  106. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  107. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -2
  108. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  109. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  110. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -1
  111. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  112. data/lib/rubocop/cop/mixin/range_help.rb +1 -1
  113. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +43 -0
  114. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -23
  115. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  116. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  117. data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
  119. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +3 -3
  120. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  121. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +11 -1
  122. data/lib/rubocop/cop/naming/file_name.rb +28 -17
  123. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
  124. data/lib/rubocop/cop/naming/method_name.rb +1 -5
  125. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  126. data/lib/rubocop/cop/registry.rb +63 -10
  127. data/lib/rubocop/cop/severity.rb +1 -3
  128. data/lib/rubocop/cop/style/and_or.rb +2 -2
  129. data/lib/rubocop/cop/style/array_join.rb +1 -1
  130. data/lib/rubocop/cop/style/attr.rb +1 -3
  131. data/lib/rubocop/cop/style/bare_percent_literals.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +4 -12
  133. data/lib/rubocop/cop/style/case_equality.rb +1 -1
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  136. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -4
  138. data/lib/rubocop/cop/style/copyright.rb +5 -5
  139. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  140. data/lib/rubocop/cop/style/documentation.rb +2 -2
  141. data/lib/rubocop/cop/style/double_negation.rb +41 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
  143. data/lib/rubocop/cop/style/empty_literal.rb +1 -3
  144. data/lib/rubocop/cop/style/empty_method.rb +1 -5
  145. data/lib/rubocop/cop/style/encoding.rb +1 -1
  146. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  147. data/lib/rubocop/cop/style/format_string_token.rb +2 -3
  148. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -6
  149. data/lib/rubocop/cop/style/guard_clause.rb +25 -2
  150. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
  151. data/lib/rubocop/cop/style/hash_syntax.rb +16 -7
  152. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  153. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  154. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -0
  155. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  157. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  158. data/lib/rubocop/cop/style/lambda_call.rb +0 -20
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -3
  160. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -3
  161. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  162. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  163. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +16 -1
  165. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  166. data/lib/rubocop/cop/style/negated_unless.rb +3 -3
  167. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  168. data/lib/rubocop/cop/style/next.rb +2 -2
  169. data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
  170. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  171. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -6
  172. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  173. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  175. data/lib/rubocop/cop/style/redundant_fetch_block.rb +103 -0
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -7
  177. data/lib/rubocop/cop/style/redundant_percent_q.rb +3 -3
  178. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +89 -0
  179. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +121 -0
  180. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  181. data/lib/rubocop/cop/style/safe_navigation.rb +2 -6
  182. data/lib/rubocop/cop/style/sample.rb +1 -1
  183. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  184. data/lib/rubocop/cop/style/slicing_with_range.rb +39 -0
  185. data/lib/rubocop/cop/style/special_global_vars.rb +2 -6
  186. data/lib/rubocop/cop/style/struct_inheritance.rb +21 -0
  187. data/lib/rubocop/cop/style/symbol_array.rb +5 -5
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -4
  189. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +3 -3
  190. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +3 -3
  191. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +13 -13
  192. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +3 -3
  193. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -3
  194. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  195. data/lib/rubocop/cop/style/when_then.rb +1 -1
  196. data/lib/rubocop/cop/style/word_array.rb +1 -1
  197. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  198. data/lib/rubocop/cop/team.rb +69 -25
  199. data/lib/rubocop/cop/util.rb +27 -3
  200. data/lib/rubocop/cop/utils/format_string.rb +18 -0
  201. data/lib/rubocop/cop/variable_force.rb +3 -9
  202. data/lib/rubocop/cop/variable_force/assignment.rb +1 -0
  203. data/lib/rubocop/cop/variable_force/branch.rb +1 -3
  204. data/lib/rubocop/cop/variable_force/scope.rb +1 -0
  205. data/lib/rubocop/cop/variable_force/variable.rb +3 -6
  206. data/lib/rubocop/ext/processed_source.rb +18 -0
  207. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  208. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -13
  209. data/lib/rubocop/formatter/formatter_set.rb +2 -4
  210. data/lib/rubocop/formatter/junit_formatter.rb +14 -4
  211. data/lib/rubocop/magic_comment.rb +1 -1
  212. data/lib/rubocop/name_similarity.rb +18 -9
  213. data/lib/rubocop/options.rb +26 -11
  214. data/lib/rubocop/path_util.rb +2 -2
  215. data/lib/rubocop/platform.rb +1 -1
  216. data/lib/rubocop/remote_config.rb +1 -3
  217. data/lib/rubocop/result_cache.rb +5 -7
  218. data/lib/rubocop/rspec/cop_helper.rb +2 -25
  219. data/lib/rubocop/rspec/expect_offense.rb +58 -15
  220. data/lib/rubocop/rspec/shared_contexts.rb +54 -16
  221. data/lib/rubocop/runner.rb +20 -13
  222. data/lib/rubocop/target_finder.rb +8 -8
  223. data/lib/rubocop/target_ruby.rb +4 -1
  224. data/lib/rubocop/version.rb +5 -3
  225. metadata +51 -74
  226. data/lib/rubocop/ast/builder.rb +0 -85
  227. data/lib/rubocop/ast/node.rb +0 -637
  228. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  229. data/lib/rubocop/ast/node/and_node.rb +0 -29
  230. data/lib/rubocop/ast/node/args_node.rb +0 -29
  231. data/lib/rubocop/ast/node/array_node.rb +0 -70
  232. data/lib/rubocop/ast/node/block_node.rb +0 -121
  233. data/lib/rubocop/ast/node/break_node.rb +0 -17
  234. data/lib/rubocop/ast/node/case_match_node.rb +0 -56
  235. data/lib/rubocop/ast/node/case_node.rb +0 -56
  236. data/lib/rubocop/ast/node/class_node.rb +0 -31
  237. data/lib/rubocop/ast/node/def_node.rb +0 -82
  238. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  239. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  240. data/lib/rubocop/ast/node/float_node.rb +0 -12
  241. data/lib/rubocop/ast/node/for_node.rb +0 -53
  242. data/lib/rubocop/ast/node/forward_args_node.rb +0 -18
  243. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  244. data/lib/rubocop/ast/node/if_node.rb +0 -175
  245. data/lib/rubocop/ast/node/int_node.rb +0 -12
  246. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  247. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  248. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  249. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  250. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  251. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  252. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -269
  253. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  254. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  255. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  256. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  257. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  258. data/lib/rubocop/ast/node/module_node.rb +0 -24
  259. data/lib/rubocop/ast/node/or_node.rb +0 -29
  260. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  261. data/lib/rubocop/ast/node/range_node.rb +0 -18
  262. data/lib/rubocop/ast/node/regexp_node.rb +0 -33
  263. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  264. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  265. data/lib/rubocop/ast/node/return_node.rb +0 -24
  266. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  267. data/lib/rubocop/ast/node/send_node.rb +0 -13
  268. data/lib/rubocop/ast/node/str_node.rb +0 -16
  269. data/lib/rubocop/ast/node/super_node.rb +0 -21
  270. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  271. data/lib/rubocop/ast/node/until_node.rb +0 -35
  272. data/lib/rubocop/ast/node/when_node.rb +0 -53
  273. data/lib/rubocop/ast/node/while_node.rb +0 -35
  274. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  275. data/lib/rubocop/ast/sexp.rb +0 -16
  276. data/lib/rubocop/ast/traversal.rb +0 -202
  277. data/lib/rubocop/node_pattern.rb +0 -887
  278. data/lib/rubocop/processed_source.rb +0 -213
  279. data/lib/rubocop/string_util.rb +0 -14
  280. data/lib/rubocop/token.rb +0 -114
@@ -263,9 +263,7 @@ module RuboCop
263
263
  def offense(body_node, indentation, style)
264
264
  # This cop only auto-corrects the first statement in a def body, for
265
265
  # example.
266
- if body_node.begin_type? && !parentheses?(body_node)
267
- body_node = body_node.children.first
268
- end
266
+ body_node = body_node.children.first if body_node.begin_type? && !parentheses?(body_node)
269
267
 
270
268
  # Since autocorrect changes a number of lines, and not only the line
271
269
  # where the reported offending range is, we avoid auto-correction if
@@ -21,23 +21,23 @@ module RuboCop
21
21
  # are recommended to further format the broken lines.
22
22
  # (Many of these are enabled by default.)
23
23
  #
24
- # - ArgumentAlignment
25
- # - BlockAlignment
26
- # - BlockDelimiters
27
- # - BlockEndNewline
28
- # - ClosingParenthesisIndentation
29
- # - FirstArgumentIndentation
30
- # - FirstArrayElementIndentation
31
- # - FirstHashElementIndentation
32
- # - FirstParameterIndentation
33
- # - HashAlignment
34
- # - IndentationWidth
35
- # - MultilineArrayLineBreaks
36
- # - MultilineBlockLayout
37
- # - MultilineHashBraceLayout
38
- # - MultilineHashKeyLineBreaks
39
- # - MultilineMethodArgumentLineBreaks
40
- # - ParameterAlignment
24
+ # * ArgumentAlignment
25
+ # * BlockAlignment
26
+ # * BlockDelimiters
27
+ # * BlockEndNewline
28
+ # * ClosingParenthesisIndentation
29
+ # * FirstArgumentIndentation
30
+ # * FirstArrayElementIndentation
31
+ # * FirstHashElementIndentation
32
+ # * FirstParameterIndentation
33
+ # * HashAlignment
34
+ # * IndentationWidth
35
+ # * MultilineArrayLineBreaks
36
+ # * MultilineBlockLayout
37
+ # * MultilineHashBraceLayout
38
+ # * MultilineHashKeyLineBreaks
39
+ # * MultilineMethodArgumentLineBreaks
40
+ # * ParameterAlignment
41
41
  #
42
42
  # Together, these cops will pretty print hashes, arrays,
43
43
  # method calls, etc. For example, let's say the max columns
@@ -160,7 +160,10 @@ module RuboCop
160
160
  end
161
161
 
162
162
  def highlight_start(line)
163
- max - indentation_difference(line)
163
+ # TODO: The max with 0 is a quick fix to avoid crashes when a line
164
+ # begins with many tabs, but getting a correct highlighting range
165
+ # when tabs are used for indentation doesn't work currently.
166
+ [max - indentation_difference(line), 0].max
164
167
  end
165
168
 
166
169
  def check_line(line, line_index)
@@ -121,7 +121,7 @@ module RuboCop
121
121
  end
122
122
 
123
123
  def autocorrect_body(corrector, node, block_body)
124
- first_node = if block_body.begin_type?
124
+ first_node = if block_body.begin_type? && !block_body.source.start_with?('(')
125
125
  block_body.children.first
126
126
  else
127
127
  block_body
@@ -37,9 +37,7 @@ module RuboCop
37
37
  # ...then each key/value pair is treated as a method 'argument'
38
38
  # when determining where line breaks should appear.
39
39
  if (last_arg = args.last)
40
- if last_arg.hash_type? && !last_arg.braces?
41
- args = args.concat(args.pop.children)
42
- end
40
+ args = args.concat(args.pop.children) if last_arg.hash_type? && !last_arg.braces?
43
41
  end
44
42
 
45
43
  check_line_breaks(node, args)
@@ -6,30 +6,39 @@ module RuboCop
6
6
  # This cop checks the indentation of the right hand side operand in
7
7
  # binary operations that span more than one line.
8
8
  #
9
+ # The `aligned` style checks that operators are aligned if they are part
10
+ # of an `if` or `while` condition, a `return` statement, etc. In other
11
+ # contexts, the second operand should be indented regardless of enforced
12
+ # style.
13
+ #
9
14
  # @example EnforcedStyle: aligned (default)
10
15
  # # bad
11
16
  # if a +
12
17
  # b
13
- # something
18
+ # something &&
19
+ # something_else
14
20
  # end
15
21
  #
16
22
  # # good
17
23
  # if a +
18
24
  # b
19
- # something
25
+ # something &&
26
+ # something_else
20
27
  # end
21
28
  #
22
29
  # @example EnforcedStyle: indented
23
30
  # # bad
24
31
  # if a +
25
32
  # b
26
- # something
33
+ # something &&
34
+ # something_else
27
35
  # end
28
36
  #
29
37
  # # good
30
38
  # if a +
31
39
  # b
32
- # something
40
+ # something &&
41
+ # something_else
33
42
  # end
34
43
  #
35
44
  class MultilineOperationIndentation < Cop
@@ -39,7 +39,7 @@ module RuboCop
39
39
  private
40
40
 
41
41
  def followed_by_space?(colon)
42
- colon.source_buffer.source[colon.end_pos] =~ /\s/
42
+ /\s/.match?(colon.source_buffer.source[colon.end_pos])
43
43
  end
44
44
  end
45
45
  end
@@ -186,7 +186,7 @@ module RuboCop
186
186
  pos = range.begin_pos - 1
187
187
  return false if pos.negative?
188
188
 
189
- range.source_buffer.source[pos] !~ /[\s\(\|\{\[;,\*\=]/
189
+ !/[\s(|{\[;,*=]/.match?(range.source_buffer.source[pos])
190
190
  end
191
191
 
192
192
  def space_after_missing?(range)
@@ -198,7 +198,7 @@ module RuboCop
198
198
  return false if accept_namespace_operator?(range) &&
199
199
  namespace_operator?(range, pos)
200
200
 
201
- char !~ /[\s;,#\\\)\}\]\.]/
201
+ !/[\s;,#\\)}\].]/.match?(char)
202
202
  end
203
203
 
204
204
  def accepted_opening_delimiter?(range, char)
@@ -121,9 +121,7 @@ module RuboCop
121
121
 
122
122
  def right_token_for_auto_correction(operator)
123
123
  right_token = next_token(operator)
124
- if !right_token.comment? && valid_right_token?(right_token, operator)
125
- return right_token
126
- end
124
+ return right_token if !right_token.comment? && valid_right_token?(right_token, operator)
127
125
 
128
126
  operator
129
127
  end
@@ -134,12 +134,12 @@ module RuboCop
134
134
 
135
135
  def autocorrect(range)
136
136
  lambda do |corrector|
137
- if range.source =~ /\*\*/ && !space_around_exponent_operator?
137
+ if /\*\*/.match?(range.source) && !space_around_exponent_operator?
138
138
  corrector.replace(range, '**')
139
139
  elsif range.source.end_with?("\n")
140
140
  corrector.replace(range, " #{range.source.strip}\n")
141
141
  else
142
- corrector.replace(range, " #{range.source.strip} ")
142
+ enclose_operator_with_space(corrector, range)
143
143
  end
144
144
  end
145
145
  end
@@ -170,6 +170,19 @@ module RuboCop
170
170
  yield msg if msg
171
171
  end
172
172
 
173
+ def enclose_operator_with_space(corrector, range)
174
+ operator = range.source
175
+
176
+ # If `ForceEqualSignAlignment` is true, `Layout/ExtraSpacing` cop
177
+ # inserts spaces before operator. If `Layout/SpaceAroundOperators` cop
178
+ # inserts a space, it collides and raises the infinite loop error.
179
+ if force_equal_sign_alignment?
180
+ corrector.insert_after(range, ' ') unless operator.end_with?(' ')
181
+ else
182
+ corrector.replace(range, " #{operator.strip} ")
183
+ end
184
+ end
185
+
173
186
  def offense_message(type, operator, with_space, right_operand)
174
187
  if should_not_have_surrounding_space?(operator)
175
188
  return if with_space.is?(operator.source)
@@ -216,6 +229,10 @@ module RuboCop
216
229
  cop_config['EnforcedStyleForExponentOperator'] == 'space'
217
230
  end
218
231
 
232
+ def force_equal_sign_alignment?
233
+ config.for_cop('Layout/ExtraSpacing')['ForceEqualSignAlignment']
234
+ end
235
+
219
236
  def should_not_have_surrounding_space?(operator)
220
237
  operator.is?('**') ? !space_around_exponent_operator? : false
221
238
  end
@@ -27,6 +27,20 @@ module RuboCop
27
27
  # foo.map{ |a|
28
28
  # a.bar.to_s
29
29
  # }
30
+ #
31
+ # @example EnforcedStyleForEmptyBraces: space (default)
32
+ # # bad
33
+ # 7.times{}
34
+ #
35
+ # # good
36
+ # 7.times {}
37
+ #
38
+ # @example EnforcedStyleForEmptyBraces: no_space
39
+ # # bad
40
+ # 7.times {}
41
+ #
42
+ # # good
43
+ # 7.times{}
30
44
  class SpaceBeforeBlockBraces < Cop
31
45
  include ConfigurableEnforcedStyle
32
46
  include RangeHelp
@@ -20,9 +20,7 @@ module RuboCop
20
20
  next unless token2.comment?
21
21
  next unless token1.line == token2.line
22
22
 
23
- if token1.pos.end == token2.pos.begin
24
- add_offense(token2.pos, location: token2.pos)
25
- end
23
+ add_offense(token2.pos, location: token2.pos) if token1.pos.end == token2.pos.begin
26
24
  end
27
25
  end
28
26
 
@@ -78,9 +78,7 @@ module RuboCop
78
78
  return unless node.square_brackets?
79
79
 
80
80
  left, right = array_brackets(node)
81
- if empty_brackets?(left, right)
82
- return empty_offenses(node, left, right, EMPTY_MSG)
83
- end
81
+ return empty_offenses(node, left, right, EMPTY_MSG) if empty_brackets?(left, right)
84
82
 
85
83
  start_ok = next_to_newline?(node, left)
86
84
  end_ok = node.single_line? ? false : end_has_own_line?(right)
@@ -132,7 +130,7 @@ module RuboCop
132
130
  line, col = line_and_column_for(token)
133
131
  return true if col == -1
134
132
 
135
- processed_source.lines[line][0..col] !~ /\S/
133
+ !/\S/.match?(processed_source.lines[line][0..col])
136
134
  end
137
135
 
138
136
  def index_for(node, token)
@@ -150,7 +150,7 @@ module RuboCop
150
150
  end
151
151
 
152
152
  def check_right_brace(inner, left_brace, right_brace, single_line)
153
- if single_line && inner =~ /\S$/
153
+ if single_line && /\S$/.match?(inner)
154
154
  no_space(right_brace.begin_pos, right_brace.end_pos,
155
155
  'Space missing inside }.')
156
156
  else
@@ -182,7 +182,7 @@ module RuboCop
182
182
  def range_of_space_to_the_right(range)
183
183
  src = range.source_buffer.source
184
184
  end_pos = range.end_pos
185
- end_pos += 1 while src[end_pos] =~ /[ \t]/
185
+ end_pos += 1 while /[ \t]/.match?(src[end_pos])
186
186
 
187
187
  range_between(range.begin_pos + 1, end_pos)
188
188
  end
@@ -190,7 +190,7 @@ module RuboCop
190
190
  def range_of_space_to_the_left(range)
191
191
  src = range.source_buffer.source
192
192
  begin_pos = range.begin_pos
193
- begin_pos -= 1 while src[begin_pos - 1] =~ /[ \t]/
193
+ begin_pos -= 1 while /[ \t]/.match?(src[begin_pos - 1])
194
194
 
195
195
  range_between(begin_pos, range.end_pos - 1)
196
196
  end
@@ -130,9 +130,7 @@ module RuboCop
130
130
  tokens[i..-1].each do |token|
131
131
  inner_left_brackets_needing_closure += 1 if token.left_bracket?
132
132
  inner_left_brackets_needing_closure -= 1 if token.right_bracket?
133
- if inner_left_brackets_needing_closure.zero? && token.right_bracket?
134
- return token
135
- end
133
+ return token if inner_left_brackets_needing_closure.zero? && token.right_bracket?
136
134
  end
137
135
  end
138
136
 
@@ -14,14 +14,14 @@ module RuboCop
14
14
  # # good
15
15
  # x = 0
16
16
  #
17
- # @example AllowInHeredoc: false (default)
17
+ # @example AllowInHeredoc: false
18
18
  # # The line in this example contains spaces after the 0.
19
19
  # # bad
20
20
  # code = <<~RUBY
21
21
  # x = 0
22
22
  # RUBY
23
23
  #
24
- # @example AllowInHeredoc: true
24
+ # @example AllowInHeredoc: true (default)
25
25
  # # The line in this example contains spaces after the 0.
26
26
  # # good
27
27
  # code = <<~RUBY
@@ -38,17 +38,58 @@ module RuboCop
38
38
  'a whitespace to the right of the `%<operator>s` if it ' \
39
39
  'should be a %<possible>s.'
40
40
 
41
+ def autocorrect(node)
42
+ lambda do |corrector|
43
+ add_parentheses(node, corrector)
44
+ end
45
+ end
46
+
41
47
  private
42
48
 
43
49
  def relevant_diagnostic?(diagnostic)
44
50
  diagnostic.reason == :ambiguous_prefix
45
51
  end
46
52
 
53
+ def find_offense_node_by(diagnostic)
54
+ ast = processed_source.ast
55
+ ast.each_node(:splat, :block_pass, :kwsplat) do |node|
56
+ next unless offense_position?(node, diagnostic)
57
+
58
+ offense_node = offense_node(node)
59
+ return offense_node if offense_node
60
+ end
61
+
62
+ ast.each_node(:send).find do |send_node|
63
+ first_argument = send_node.first_argument
64
+
65
+ first_argument &&
66
+ offense_position?(first_argument, diagnostic) &&
67
+ unary_operator?(first_argument, diagnostic)
68
+ end
69
+ end
70
+
47
71
  def alternative_message(diagnostic)
48
72
  operator = diagnostic.location.source
49
73
  hash = AMBIGUITIES[operator]
50
74
  format(MSG_FORMAT, hash)
51
75
  end
76
+
77
+ def offense_position?(node, diagnostic)
78
+ node.source_range.begin_pos == diagnostic.location.begin_pos
79
+ end
80
+
81
+ def offense_node(node)
82
+ case node.type
83
+ when :splat, :block_pass
84
+ node.parent
85
+ when :kwsplat
86
+ node.parent.parent
87
+ end
88
+ end
89
+
90
+ def unary_operator?(node, diagnostic)
91
+ node.source.start_with?(diagnostic.arguments[:prefix])
92
+ end
52
93
  end
53
94
  end
54
95
  end
@@ -28,12 +28,26 @@ module RuboCop
28
28
  "if it's surely a regexp literal, or add a whitespace to the " \
29
29
  'right of the `/` if it should be a division.'
30
30
 
31
+ def autocorrect(node)
32
+ lambda do |corrector|
33
+ add_parentheses(node, corrector)
34
+ end
35
+ end
36
+
31
37
  private
32
38
 
33
39
  def relevant_diagnostic?(diagnostic)
34
40
  diagnostic.reason == :ambiguous_literal
35
41
  end
36
42
 
43
+ def find_offense_node_by(diagnostic)
44
+ node = processed_source.ast.each_node(:regexp).find do |regexp_node|
45
+ regexp_node.source_range.begin_pos == diagnostic.location.begin_pos
46
+ end
47
+
48
+ node.parent
49
+ end
50
+
37
51
  def alternative_message(_diagnostic)
38
52
  MSG
39
53
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Check that certain constants are fully qualified.
7
+ #
8
+ # This is not enabled by default because it would mark a lot of offenses
9
+ # unnecessarily.
10
+ #
11
+ # Generally, gems should fully qualify all constants to avoid conflicts with
12
+ # the code that uses the gem. Enable this cop without using `Only`/`Ignore`
13
+ #
14
+ # Large projects will over time end up with one or two constant names that
15
+ # are problematic because of a conflict with a library or just internally
16
+ # using the same name a namespace and a class. To avoid too many unnecessary
17
+ # offenses, Enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
18
+ #
19
+ # @example
20
+ # # By default checks every constant
21
+ #
22
+ # # bad
23
+ # User
24
+ #
25
+ # # bad
26
+ # User::Login
27
+ #
28
+ # # good
29
+ # ::User
30
+ #
31
+ # # good
32
+ # ::User::Login
33
+ #
34
+ # @example Only: ['Login']
35
+ # # Restrict this cop to only being concerned about certain constants
36
+ #
37
+ # # bad
38
+ # Login
39
+ #
40
+ # # good
41
+ # ::Login
42
+ #
43
+ # # good
44
+ # User::Login
45
+ #
46
+ # @example Ignore: ['Login']
47
+ # # Restrict this cop not being concerned about certain constants
48
+ #
49
+ # # bad
50
+ # User
51
+ #
52
+ # # good
53
+ # ::User::Login
54
+ #
55
+ # # good
56
+ # Login
57
+ #
58
+ class ConstantResolution < Cop
59
+ MSG = 'Fully qualify this constant to avoid possibly ambiguous resolution.'
60
+
61
+ def_node_matcher :unqualified_const?, <<~PATTERN
62
+ (const nil? #const_name?)
63
+ PATTERN
64
+
65
+ def on_const(node)
66
+ return unless unqualified_const?(node)
67
+
68
+ add_offense(node)
69
+ end
70
+
71
+ private
72
+
73
+ def const_name?(name)
74
+ name = name.to_s
75
+ (allowed_names.empty? || allowed_names.include?(name)) &&
76
+ !ignored_names.include?(name)
77
+ end
78
+
79
+ def allowed_names
80
+ cop_config['Only']
81
+ end
82
+
83
+ def ignored_names
84
+ cop_config['Ignore']
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end