rubocop 0.70.0 → 0.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -10
  3. data/bin/console +1 -0
  4. data/config/default.yml +91 -494
  5. data/lib/rubocop.rb +16 -54
  6. data/lib/rubocop/ast/builder.rb +2 -0
  7. data/lib/rubocop/ast/node.rb +9 -15
  8. data/lib/rubocop/ast/node/float_node.rb +12 -0
  9. data/lib/rubocop/ast/node/int_node.rb +12 -0
  10. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
  11. data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
  12. data/lib/rubocop/ast/node/resbody_node.rb +1 -6
  13. data/lib/rubocop/ast/traversal.rb +3 -3
  14. data/lib/rubocop/cached_data.rb +1 -1
  15. data/lib/rubocop/comment_config.rb +3 -2
  16. data/lib/rubocop/config.rb +21 -508
  17. data/lib/rubocop/config_loader.rb +22 -4
  18. data/lib/rubocop/config_loader_resolver.rb +2 -8
  19. data/lib/rubocop/config_obsoletion.rb +213 -0
  20. data/lib/rubocop/config_validator.rb +239 -0
  21. data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
  22. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  24. data/lib/rubocop/cop/commissioner.rb +3 -9
  25. data/lib/rubocop/cop/cop.rb +39 -12
  26. data/lib/rubocop/cop/corrector.rb +2 -3
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  28. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
  29. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  30. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  31. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  32. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  33. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
  34. data/lib/rubocop/cop/generator.rb +4 -4
  35. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  36. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  37. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
  38. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  39. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
  40. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
  42. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  43. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  44. data/lib/rubocop/cop/layout/class_structure.rb +2 -2
  45. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  46. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +3 -1
  47. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
  48. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -0
  49. data/lib/rubocop/cop/layout/indent_assignment.rb +9 -1
  50. data/lib/rubocop/cop/layout/indent_first_argument.rb +7 -3
  51. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  52. data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -4
  53. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  54. data/lib/rubocop/cop/layout/indentation_width.rb +28 -10
  55. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
  56. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  57. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +2 -0
  58. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -4
  59. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  60. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  61. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +1 -1
  62. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
  63. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  64. data/lib/rubocop/cop/layout/tab.rb +10 -22
  65. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  66. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
  67. data/lib/rubocop/cop/lint/debugger.rb +4 -6
  68. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  69. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  70. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  71. data/lib/rubocop/cop/lint/erb_new_arguments.rb +57 -1
  72. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
  73. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  74. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  75. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  76. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  77. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
  78. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  79. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  80. data/lib/rubocop/cop/lint/number_conversion.rb +4 -4
  81. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  82. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  83. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  84. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -5
  85. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  86. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  87. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  88. data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
  89. data/lib/rubocop/cop/lint/unneeded_cop_disable_directive.rb +1 -1
  90. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -1
  91. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +7 -2
  92. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  93. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  94. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
  95. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
  96. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  97. data/lib/rubocop/cop/message_annotator.rb +16 -7
  98. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  99. data/lib/rubocop/cop/metrics/line_length.rb +6 -0
  100. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  101. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  102. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  103. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  104. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  105. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  106. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
  107. data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
  108. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  109. data/lib/rubocop/cop/mixin/hash_alignment.rb +4 -0
  110. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  111. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  112. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  113. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  114. data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
  115. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  116. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  117. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  118. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  119. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  120. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +20 -22
  121. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  122. data/lib/rubocop/cop/offense.rb +18 -7
  123. data/lib/rubocop/cop/registry.rb +22 -1
  124. data/lib/rubocop/cop/security/eval.rb +1 -1
  125. data/lib/rubocop/cop/security/json_load.rb +1 -1
  126. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  127. data/lib/rubocop/cop/security/open.rb +1 -1
  128. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  129. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  130. data/lib/rubocop/cop/style/alias.rb +1 -1
  131. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  132. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +29 -10
  133. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  134. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  135. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  136. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -9
  137. data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
  138. data/lib/rubocop/cop/style/date_time.rb +3 -3
  139. data/lib/rubocop/cop/style/dir.rb +1 -1
  140. data/lib/rubocop/cop/style/documentation_method.rb +1 -1
  141. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
  142. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  143. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  144. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  145. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  146. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -3
  147. data/lib/rubocop/cop/style/float_division.rb +94 -0
  148. data/lib/rubocop/cop/style/format_string.rb +13 -9
  149. data/lib/rubocop/cop/style/format_string_token.rb +10 -40
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +18 -33
  151. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  152. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  153. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  154. data/lib/rubocop/cop/style/if_unless_modifier.rb +51 -15
  155. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  156. data/lib/rubocop/cop/style/inverse_methods.rb +2 -2
  157. data/lib/rubocop/cop/style/lambda.rb +0 -2
  158. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +12 -6
  159. data/lib/rubocop/cop/style/min_max.rb +1 -1
  160. data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
  161. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  162. data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
  163. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  164. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  165. data/lib/rubocop/cop/style/nested_modifier.rb +18 -2
  166. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
  167. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  168. data/lib/rubocop/cop/style/or_assignment.rb +8 -3
  169. data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
  170. data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
  171. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
  172. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  173. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  174. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
  175. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  176. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  177. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  178. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  179. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  180. data/lib/rubocop/cop/style/safe_navigation.rb +11 -2
  181. data/lib/rubocop/cop/style/sample.rb +1 -1
  182. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  183. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  184. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
  185. data/lib/rubocop/cop/style/strip.rb +1 -1
  186. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  187. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +32 -3
  189. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -0
  190. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  191. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  192. data/lib/rubocop/cop/style/unneeded_sort.rb +1 -1
  193. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  194. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  195. data/lib/rubocop/cop/style/word_array.rb +2 -2
  196. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
  197. data/lib/rubocop/cop/team.rb +15 -14
  198. data/lib/rubocop/cop/utils/format_string.rb +128 -0
  199. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  200. data/lib/rubocop/core_ext/string.rb +0 -24
  201. data/lib/rubocop/error.rb +23 -0
  202. data/lib/rubocop/formatter/emacs_style_formatter.rb +8 -5
  203. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  204. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  205. data/lib/rubocop/formatter/simple_text_formatter.rb +9 -1
  206. data/lib/rubocop/formatter/tap_formatter.rb +9 -1
  207. data/lib/rubocop/magic_comment.rb +4 -0
  208. data/lib/rubocop/node_pattern.rb +86 -7
  209. data/lib/rubocop/options.rb +18 -2
  210. data/lib/rubocop/path_util.rb +1 -1
  211. data/lib/rubocop/processed_source.rb +9 -1
  212. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  213. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  214. data/lib/rubocop/rspec/shared_contexts.rb +12 -17
  215. data/lib/rubocop/rspec/support.rb +0 -1
  216. data/lib/rubocop/runner.rb +20 -15
  217. data/lib/rubocop/target_finder.rb +6 -4
  218. data/lib/rubocop/version.rb +1 -1
  219. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  220. metadata +16 -70
  221. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  222. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  223. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  224. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  225. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  226. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  227. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  228. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  229. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  230. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  231. data/lib/rubocop/cop/rails/blank.rb +0 -164
  232. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  233. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  234. data/lib/rubocop/cop/rails/date.rb +0 -161
  235. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  236. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  237. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  238. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  239. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  240. data/lib/rubocop/cop/rails/exit.rb +0 -67
  241. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  242. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  243. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  244. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  245. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  246. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  247. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  248. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  249. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  250. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  251. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  252. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  253. data/lib/rubocop/cop/rails/output.rb +0 -49
  254. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  255. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  256. data/lib/rubocop/cop/rails/presence.rb +0 -124
  257. data/lib/rubocop/cop/rails/present.rb +0 -153
  258. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  259. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  260. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  261. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  262. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  263. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  264. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  265. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  266. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  267. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  268. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  269. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  270. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  271. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  272. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  273. data/lib/rubocop/cop/rails/validation.rb +0 -109
  274. data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -5,17 +5,25 @@ module RuboCop
5
5
  # This module encapsulates the logic for autocorrect behavior for a cop.
6
6
  module AutocorrectLogic
7
7
  def autocorrect?
8
- autocorrect_requested? && support_autocorrect? && autocorrect_enabled?
8
+ autocorrect_requested? && correctable? && autocorrect_enabled?
9
9
  end
10
10
 
11
11
  def autocorrect_requested?
12
12
  @options.fetch(:auto_correct, false)
13
13
  end
14
14
 
15
+ def correctable?
16
+ support_autocorrect? || disable_uncorrectable?
17
+ end
18
+
15
19
  def support_autocorrect?
16
20
  respond_to?(:autocorrect)
17
21
  end
18
22
 
23
+ def disable_uncorrectable?
24
+ @options[:disable_uncorrectable] == true
25
+ end
26
+
19
27
  def autocorrect_enabled?
20
28
  # allow turning off autocorrect on a cop by cop basis
21
29
  return true unless cop_config
@@ -28,6 +36,68 @@ module RuboCop
28
36
 
29
37
  true
30
38
  end
39
+
40
+ def disable_offense(node)
41
+ range = node.location.expression
42
+ eol_comment = " # rubocop:todo #{cop_name}"
43
+ needed_line_length = range.column +
44
+ (range.source_line + eol_comment).length
45
+ if needed_line_length <= max_line_length
46
+ disable_offense_at_end_of_line(range_of_first_line(range),
47
+ eol_comment)
48
+ else
49
+ disable_offense_before_and_after(range_by_lines(range))
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def range_of_first_line(range)
56
+ begin_of_first_line = range.begin_pos - range.column
57
+ end_of_first_line = begin_of_first_line + range.source_line.length
58
+
59
+ Parser::Source::Range.new(range.source_buffer,
60
+ begin_of_first_line,
61
+ end_of_first_line)
62
+ end
63
+
64
+ # Expand the given range to include all of any lines it covers. Does not
65
+ # include newline at end of the last line.
66
+ def range_by_lines(range)
67
+ begin_of_first_line = range.begin_pos - range.column
68
+
69
+ last_line = range.source_buffer.source_line(range.last_line)
70
+ last_line_offset = last_line.length - range.last_column
71
+ end_of_last_line = range.end_pos + last_line_offset
72
+
73
+ Parser::Source::Range.new(range.source_buffer,
74
+ begin_of_first_line,
75
+ end_of_last_line)
76
+ end
77
+
78
+ def max_line_length
79
+ config.for_cop('Metrics/LineLength')['Max'] || 80
80
+ end
81
+
82
+ def disable_offense_at_end_of_line(range, eol_comment)
83
+ ->(corrector) { corrector.insert_after(range, eol_comment) }
84
+ end
85
+
86
+ def disable_offense_before_and_after(range_by_lines)
87
+ lambda do |corrector|
88
+ range_with_newline = range_by_lines.resize(range_by_lines.size + 1)
89
+ leading_whitespace = range_by_lines.source_line[/^\s*/]
90
+
91
+ corrector.insert_before(
92
+ range_with_newline,
93
+ "#{leading_whitespace}# rubocop:todo #{cop_name}\n"
94
+ )
95
+ corrector.insert_after(
96
+ range_with_newline,
97
+ "#{leading_whitespace}# rubocop:enable #{cop_name}\n"
98
+ )
99
+ end
100
+ end
31
101
  end
32
102
  end
33
103
  end
@@ -33,7 +33,7 @@ module RuboCop
33
33
  "Please change your source to 'https://rubygems.org' " \
34
34
  "if possible, or 'http://rubygems.org' if not."
35
35
 
36
- def_node_matcher :insecure_protocol_source?, <<-PATTERN
36
+ def_node_matcher :insecure_protocol_source?, <<~PATTERN
37
37
  (send nil? :source
38
38
  (sym ${:gemcutter :rubygems :rubyforge}))
39
39
  PATTERN
@@ -64,7 +64,7 @@ module RuboCop
64
64
  declarations.to_a[node_index - 1]
65
65
  end
66
66
 
67
- def_node_search :gem_declarations, <<-PATTERN
67
+ def_node_search :gem_declarations, <<~PATTERN
68
68
  (:send nil? :gem str ...)
69
69
  PATTERN
70
70
  end
@@ -7,8 +7,6 @@ module RuboCop
7
7
  class Commissioner
8
8
  include RuboCop::AST::Traversal
9
9
 
10
- CopError = Struct.new(:error, :line, :column)
11
-
12
10
  attr_reader :errors
13
11
 
14
12
  def initialize(cops, forces = [], options = {})
@@ -62,7 +60,7 @@ module RuboCop
62
60
  end
63
61
 
64
62
  def reset_errors
65
- @errors = Hash.new { |hash, k| hash[k] = [] }
63
+ @errors = []
66
64
  end
67
65
 
68
66
  def remove_irrelevant_cops(filename)
@@ -131,12 +129,8 @@ module RuboCop
131
129
  rescue StandardError => e
132
130
  raise e if @options[:raise_error]
133
131
 
134
- if node
135
- line = node.first_line
136
- column = node.loc.column
137
- end
138
- error = CopError.new(e, line, column)
139
- @errors[cop] << error
132
+ err = ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop)
133
+ @errors << err
140
134
  end
141
135
  end
142
136
  end
@@ -31,6 +31,16 @@ module RuboCop
31
31
  include IgnoredNode
32
32
  include AutocorrectLogic
33
33
 
34
+ Correction = Struct.new(:lambda, :node, :cop) do
35
+ def call(corrector)
36
+ lambda.call(corrector)
37
+ rescue StandardError => e
38
+ raise ErrorWithAnalyzedFileLocation.new(
39
+ cause: e, node: node, cop: cop
40
+ )
41
+ end
42
+ end
43
+
34
44
  attr_reader :config, :offenses, :corrections
35
45
  attr_accessor :processed_source # TODO: Bad design.
36
46
 
@@ -48,10 +58,6 @@ module RuboCop
48
58
  registry.qualified_cop_name(name, origin)
49
59
  end
50
60
 
51
- def self.non_rails
52
- registry.without_department(:Rails)
53
- end
54
-
55
61
  def self.inherited(subclass)
56
62
  registry.enlist(subclass)
57
63
  end
@@ -145,16 +151,37 @@ module RuboCop
145
151
  end
146
152
 
147
153
  def correct(node)
148
- return :unsupported unless support_autocorrect?
154
+ reason = reason_to_not_correct(node)
155
+ return reason if reason
156
+
157
+ @corrected_nodes[node] = true
158
+ if support_autocorrect?
159
+ correction = autocorrect(node)
160
+ return :uncorrected unless correction
161
+
162
+ @corrections << Correction.new(correction, node, self)
163
+ :corrected
164
+ elsif disable_uncorrectable?
165
+ disable_uncorrectable(node)
166
+ :corrected_with_todo
167
+ end
168
+ end
169
+
170
+ def reason_to_not_correct(node)
171
+ return :unsupported unless correctable?
149
172
  return :uncorrected unless autocorrect?
150
173
  return :already_corrected if @corrected_nodes.key?(node)
151
174
 
152
- @corrected_nodes[node] = true
153
- correction = autocorrect(node)
154
- return :uncorrected unless correction
175
+ nil
176
+ end
177
+
178
+ def disable_uncorrectable(node)
179
+ @disabled_lines ||= {}
180
+ line = node.location.line
181
+ return if @disabled_lines.key?(line)
155
182
 
156
- @corrections << correction
157
- :corrected
183
+ @disabled_lines[line] = true
184
+ @corrections << Correction.new(disable_offense(node), node, self)
158
185
  end
159
186
 
160
187
  def config_to_allow_offenses
@@ -198,8 +225,8 @@ module RuboCop
198
225
 
199
226
  def annotate(message)
200
227
  RuboCop::Cop::MessageAnnotator.new(
201
- config, cop_config, @options
202
- ).annotate(message, name)
228
+ config, cop_name, cop_config, @options
229
+ ).annotate(message)
203
230
  end
204
231
 
205
232
  def file_name_matches_any?(file, parameter, default_result)
@@ -57,16 +57,15 @@ module RuboCop
57
57
  #
58
58
  # @return [String]
59
59
  def rewrite
60
- # rubocop:disable Lint/HandleExceptions
61
60
  @corrections.each do |correction|
62
61
  begin
63
62
  @source_rewriter.transaction do
64
63
  correction.call(self)
65
64
  end
66
- rescue ::Parser::ClobberingError
65
+ rescue ErrorWithAnalyzedFileLocation => e
66
+ raise e unless e.cause.is_a?(::Parser::ClobberingError)
67
67
  end
68
68
  end
69
- # rubocop:enable Lint/HandleExceptions
70
69
 
71
70
  @source_rewriter.process
72
71
  end
@@ -19,10 +19,12 @@ module RuboCop
19
19
  expr = node.respond_to?(:loc) ? node.loc.expression : node
20
20
  return if block_comment_within?(expr)
21
21
 
22
+ taboo_ranges = inside_string_ranges(node)
23
+
22
24
  lambda do |corrector|
23
25
  each_line(expr) do |line_begin_pos|
24
26
  autocorrect_line(corrector, line_begin_pos, expr, column_delta,
25
- heredoc_ranges(node))
27
+ taboo_ranges)
26
28
  end
27
29
  end
28
30
  end
@@ -39,27 +41,48 @@ module RuboCop
39
41
  private
40
42
 
41
43
  def autocorrect_line(corrector, line_begin_pos, expr, column_delta,
42
- heredoc_ranges)
44
+ taboo_ranges)
43
45
  range = calculate_range(expr, line_begin_pos, column_delta)
44
- # We must not change indentation of heredoc strings.
45
- return if heredoc_ranges.any? { |h| within?(range, h) }
46
+ # We must not change indentation of heredoc strings or inside other
47
+ # string literals
48
+ return if taboo_ranges.any? { |t| within?(range, t) }
46
49
 
47
50
  if column_delta.positive?
48
- unless range.source == "\n"
49
- # TODO: Fix ranges instead of using `begin`
50
- corrector.insert_before(range.begin, ' ' * column_delta)
51
+ unless range.resize(1).source == "\n"
52
+ corrector.insert_before(range, ' ' * column_delta)
51
53
  end
52
54
  elsif range.source =~ /\A[ \t]+\z/
53
55
  remove(range, corrector)
54
56
  end
55
57
  end
56
58
 
57
- def heredoc_ranges(node)
59
+ def inside_string_ranges(node)
58
60
  return [] unless node.is_a?(Parser::AST::Node)
59
61
 
60
- node.each_node(:dstr)
61
- .select(&:heredoc?)
62
- .map { |n| n.loc.heredoc_body.join(n.loc.heredoc_end) }
62
+ node.each_node(:str, :dstr, :xstr).map { |n| inside_string_range(n) }
63
+ .compact
64
+ end
65
+
66
+ def inside_string_range(node)
67
+ loc = node.location
68
+
69
+ if node.heredoc?
70
+ loc.heredoc_body.join(loc.heredoc_end)
71
+ elsif delimited_string_literal?(node)
72
+ loc.begin.end.join(loc.end.begin)
73
+ end
74
+ end
75
+
76
+ # Some special kinds of string literals are not composed of literal
77
+ # characters between two delimiters:
78
+ # - The source map of `?a` responds to :begin and :end but its end is
79
+ # nil.
80
+ # - The source map of `__FILE__` responds to neither :begin nor :end.
81
+ def delimited_string_literal?(node)
82
+ loc = node.location
83
+
84
+ loc.respond_to?(:begin) && loc.begin &&
85
+ loc.respond_to?(:end) && loc.end
63
86
  end
64
87
 
65
88
  def block_comment_within?(expr)
@@ -69,15 +92,18 @@ module RuboCop
69
92
  end
70
93
 
71
94
  def calculate_range(expr, line_begin_pos, column_delta)
95
+ if column_delta.positive?
96
+ return range_between(line_begin_pos, line_begin_pos)
97
+ end
98
+
72
99
  starts_with_space =
73
100
  expr.source_buffer.source[line_begin_pos].start_with?(' ')
74
- pos_to_remove = if column_delta.positive? || starts_with_space
75
- line_begin_pos
76
- else
77
- line_begin_pos - column_delta.abs
78
- end
79
101
 
80
- range_between(pos_to_remove, pos_to_remove + column_delta.abs)
102
+ if starts_with_space
103
+ range_between(line_begin_pos, line_begin_pos + column_delta.abs)
104
+ else
105
+ range_between(line_begin_pos - column_delta.abs, line_begin_pos)
106
+ end
81
107
  end
82
108
 
83
109
  def remove(range, corrector)
@@ -9,9 +9,9 @@ module RuboCop
9
9
  offense_style, range = node
10
10
  lambda do |corrector|
11
11
  case offense_style
12
- when :no_empty_lines then
12
+ when :no_empty_lines
13
13
  corrector.remove(range)
14
- when :empty_lines then
14
+ when :empty_lines
15
15
  corrector.insert_before(range, "\n")
16
16
  end
17
17
  end
@@ -40,8 +40,8 @@ module RuboCop
40
40
  range_with_surrounding_space(range: node.loc.end, side: :left)
41
41
  )
42
42
 
43
- corrector.insert_after(
44
- last_element_range_with_trailing_comma(node),
43
+ corrector.insert_before(
44
+ last_element_range_with_trailing_comma(node).end,
45
45
  node.loc.end.source
46
46
  )
47
47
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  MSG = '`%<assignment>s` method calls already given on line '\
41
41
  '%<line_of_first_occurrence>d of the gemspec.'
42
42
 
43
- def_node_search :gem_specification, <<-PATTERN
43
+ def_node_search :gem_specification, <<~PATTERN
44
44
  (block
45
45
  (send
46
46
  (const
@@ -49,7 +49,7 @@ module RuboCop
49
49
  (arg $_)) ...)
50
50
  PATTERN
51
51
 
52
- def_node_search :assignment_method_declarations, <<-PATTERN
52
+ def_node_search :assignment_method_declarations, <<~PATTERN
53
53
  (send
54
54
  (lvar #match_block_variable_name?) #assignment_method? ...)
55
55
  PATTERN
@@ -97,7 +97,7 @@ module RuboCop
97
97
  node.method_name
98
98
  end
99
99
 
100
- def_node_search :dependency_declarations, <<-PATTERN
100
+ def_node_search :dependency_declarations, <<~PATTERN
101
101
  (send (lvar _) {:add_dependency :add_runtime_dependency :add_development_dependency} ...)
102
102
  PATTERN
103
103
  end
@@ -41,7 +41,7 @@ module RuboCop
41
41
  '(%<target_ruby_version>s, which may be specified in ' \
42
42
  '.rubocop.yml) should be equal.'
43
43
 
44
- def_node_search :required_ruby_version, <<-PATTERN
44
+ def_node_search :required_ruby_version, <<~PATTERN
45
45
  (send _ :required_ruby_version= ${(str _) (array (str _))})
46
46
  PATTERN
47
47
 
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Gemspec
6
+ # Checks that `RUBY_VERSION` constant is not used in gemspec.
7
+ # Using `RUBY_VERSION` is dangerous because value of the
8
+ # constant is determined by `rake release`.
9
+ # It's possible to have dependency based on ruby version used
10
+ # to execute `rake release` and not user's ruby version.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ # Gem::Specification.new do |spec|
16
+ # if RUBY_VERSION >= '2.5'
17
+ # spec.add_runtime_dependency 'gem_a'
18
+ # else
19
+ # spec.add_runtime_dependency 'gem_b'
20
+ # end
21
+ # end
22
+ #
23
+ # # good
24
+ # Gem::Specification.new do |spec|
25
+ # spec.add_runtime_dependency 'gem_a'
26
+ # end
27
+ #
28
+ class RubyVersionGlobalsUsage < Cop
29
+ MSG = 'Do not use `RUBY_VERSION` in gemspec file.'
30
+
31
+ def_node_matcher :ruby_version?, '(const nil? :RUBY_VERSION)'
32
+
33
+ def_node_search :gem_specification?, <<~PATTERN
34
+ (block
35
+ (send
36
+ (const
37
+ (const {cbase nil?} :Gem) :Specification) :new)
38
+ ...)
39
+ PATTERN
40
+
41
+ def on_const(node)
42
+ return unless gem_spec_with_ruby_version?(node)
43
+
44
+ add_offense(node)
45
+ end
46
+
47
+ private
48
+
49
+ def gem_spec_with_ruby_version?(node)
50
+ gem_specification?(processed_source.ast) && ruby_version?(node)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end