rubocop 0.85.0 → 0.88.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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -17
  3. data/bin/rubocop-profile +31 -0
  4. data/config/default.yml +132 -11
  5. data/lib/rubocop.rb +17 -1
  6. data/lib/rubocop/cli.rb +2 -4
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
  8. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +1 -1
  10. data/lib/rubocop/config.rb +1 -1
  11. data/lib/rubocop/config_loader.rb +39 -67
  12. data/lib/rubocop/config_loader_resolver.rb +1 -1
  13. data/lib/rubocop/config_obsoletion.rb +0 -1
  14. data/lib/rubocop/config_store.rb +4 -0
  15. data/lib/rubocop/cop/autocorrect_logic.rb +14 -24
  16. data/lib/rubocop/cop/badge.rb +1 -1
  17. data/lib/rubocop/cop/base.rb +407 -0
  18. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
  19. data/lib/rubocop/cop/commissioner.rb +48 -50
  20. data/lib/rubocop/cop/cop.rb +91 -235
  21. data/lib/rubocop/cop/corrector.rb +38 -115
  22. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
  23. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +7 -2
  24. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  25. data/lib/rubocop/cop/generator.rb +1 -1
  26. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  27. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
  28. data/lib/rubocop/cop/layout/case_indentation.rb +18 -19
  29. data/lib/rubocop/cop/layout/class_structure.rb +2 -37
  30. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
  31. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  32. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
  33. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -8
  34. data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
  35. data/lib/rubocop/cop/layout/end_of_line.rb +1 -1
  36. data/lib/rubocop/cop/layout/first_argument_indentation.rb +5 -1
  37. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  38. data/lib/rubocop/cop/layout/hash_alignment.rb +2 -3
  39. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  40. data/lib/rubocop/cop/layout/multiline_block_layout.rb +17 -7
  41. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  42. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +22 -27
  43. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  44. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +27 -68
  45. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  46. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  47. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +4 -3
  48. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  49. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  50. data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
  51. data/lib/rubocop/cop/legacy/corrector.rb +29 -0
  52. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  53. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -4
  54. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
  55. data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
  56. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  57. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  58. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
  59. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +3 -2
  60. data/lib/rubocop/cop/lint/interpolation_check.rb +13 -0
  61. data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -1
  62. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +8 -1
  63. data/lib/rubocop/cop/lint/nested_method_definition.rb +14 -20
  64. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +69 -2
  65. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -3
  66. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  67. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  68. data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
  69. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  70. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +31 -25
  71. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +2 -2
  72. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  73. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +9 -1
  74. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  75. data/lib/rubocop/cop/lint/syntax.rb +11 -26
  76. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
  77. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
  78. data/lib/rubocop/cop/metrics/block_length.rb +22 -0
  79. data/lib/rubocop/cop/metrics/class_length.rb +25 -2
  80. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
  81. data/lib/rubocop/cop/metrics/method_length.rb +23 -0
  82. data/lib/rubocop/cop/metrics/module_length.rb +25 -2
  83. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  84. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +129 -0
  85. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  86. data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
  87. data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
  88. data/lib/rubocop/cop/mixin/code_length.rb +4 -0
  89. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
  90. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  91. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  92. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  93. data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
  94. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  95. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  96. data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
  97. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
  98. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  99. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  100. data/lib/rubocop/cop/mixin/range_help.rb +1 -1
  101. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +27 -0
  102. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
  103. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  104. data/lib/rubocop/cop/mixin/surrounding_space.rb +10 -5
  105. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -13
  106. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  107. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +6 -4
  108. data/lib/rubocop/cop/mixin/visibility_help.rb +50 -0
  109. data/lib/rubocop/cop/naming/ascii_identifiers.rb +27 -4
  110. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +3 -3
  111. data/lib/rubocop/cop/naming/file_name.rb +1 -3
  112. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
  113. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  114. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  115. data/lib/rubocop/cop/naming/predicate_name.rb +3 -5
  116. data/lib/rubocop/cop/naming/variable_name.rb +1 -1
  117. data/lib/rubocop/cop/naming/variable_number.rb +1 -1
  118. data/lib/rubocop/cop/offense.rb +16 -2
  119. data/lib/rubocop/cop/registry.rb +62 -7
  120. data/lib/rubocop/cop/style/accessor_grouping.rb +147 -0
  121. data/lib/rubocop/cop/style/array_coercion.rb +63 -0
  122. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +3 -2
  123. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -1
  124. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +146 -0
  125. data/lib/rubocop/cop/style/block_delimiters.rb +2 -4
  126. data/lib/rubocop/cop/style/case_like_if.rb +217 -0
  127. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  128. data/lib/rubocop/cop/style/class_vars.rb +21 -0
  129. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  130. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  131. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  132. data/lib/rubocop/cop/style/copyright.rb +3 -3
  133. data/lib/rubocop/cop/style/date_time.rb +1 -1
  134. data/lib/rubocop/cop/style/dir.rb +2 -2
  135. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  136. data/lib/rubocop/cop/style/documentation.rb +2 -2
  137. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
  138. data/lib/rubocop/cop/style/empty_literal.rb +5 -5
  139. data/lib/rubocop/cop/style/encoding.rb +1 -1
  140. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  141. data/lib/rubocop/cop/style/exponential_notation.rb +8 -10
  142. data/lib/rubocop/cop/style/float_division.rb +7 -10
  143. data/lib/rubocop/cop/style/format_string_token.rb +5 -5
  144. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  145. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +62 -0
  146. data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
  147. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  148. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  149. data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -11
  150. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -0
  151. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  152. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  153. data/lib/rubocop/cop/style/missing_else.rb +1 -11
  154. data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
  155. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  156. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
  157. data/lib/rubocop/cop/style/mutable_constant.rb +4 -4
  158. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -5
  159. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  160. data/lib/rubocop/cop/style/next.rb +2 -2
  161. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  162. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -4
  163. data/lib/rubocop/cop/style/parallel_assignment.rb +3 -3
  164. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  165. data/lib/rubocop/cop/style/proc.rb +1 -1
  166. data/lib/rubocop/cop/style/random_with_offset.rb +4 -10
  167. data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
  168. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  169. data/lib/rubocop/cop/style/redundant_exception.rb +14 -10
  170. data/lib/rubocop/cop/style/redundant_fetch_block.rb +122 -0
  171. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
  172. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  173. data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -2
  174. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
  175. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +4 -3
  176. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +14 -23
  177. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  178. data/lib/rubocop/cop/style/redundant_sort.rb +3 -2
  179. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
  180. data/lib/rubocop/cop/style/sample.rb +1 -1
  181. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  182. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  183. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
  184. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  185. data/lib/rubocop/cop/style/struct_inheritance.rb +23 -2
  186. data/lib/rubocop/cop/style/symbol_array.rb +5 -5
  187. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  189. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
  190. data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
  191. data/lib/rubocop/cop/style/word_array.rb +1 -1
  192. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  193. data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -2
  194. data/lib/rubocop/cop/team.rb +105 -81
  195. data/lib/rubocop/cop/util.rb +2 -2
  196. data/lib/rubocop/cop/utils/format_string.rb +19 -2
  197. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  198. data/lib/rubocop/file_finder.rb +12 -12
  199. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
  200. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  201. data/lib/rubocop/name_similarity.rb +7 -3
  202. data/lib/rubocop/options.rb +15 -8
  203. data/lib/rubocop/path_util.rb +4 -19
  204. data/lib/rubocop/platform.rb +1 -1
  205. data/lib/rubocop/rake_task.rb +6 -9
  206. data/lib/rubocop/result_cache.rb +12 -8
  207. data/lib/rubocop/rspec/cop_helper.rb +4 -4
  208. data/lib/rubocop/rspec/expect_offense.rb +65 -21
  209. data/lib/rubocop/rspec/shared_contexts.rb +19 -16
  210. data/lib/rubocop/runner.rb +34 -33
  211. data/lib/rubocop/target_finder.rb +3 -3
  212. data/lib/rubocop/target_ruby.rb +2 -2
  213. data/lib/rubocop/version.rb +1 -1
  214. metadata +34 -9
  215. data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # This module encapsulates the ability to allow certain methods when
6
+ # parsing.
7
+ module AllowedMethods
8
+ private
9
+
10
+ def allowed_method?(name)
11
+ allowed_methods.include?(name.to_s)
12
+ end
13
+
14
+ def allowed_methods
15
+ cop_config.fetch('AllowedMethods', [])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # extend this module to signal autocorrection support
6
+ module AutoCorrector
7
+ def support_autocorrect?
8
+ true
9
+ end
10
+ end
11
+ end
12
+ end
@@ -16,6 +16,10 @@ module RuboCop
16
16
  cop_config['CountComments']
17
17
  end
18
18
 
19
+ def count_as_one
20
+ Array(cop_config['CountAsOne']).map(&:to_sym)
21
+ end
22
+
19
23
  def check_code_length(node)
20
24
  length = code_length(node)
21
25
 
@@ -10,7 +10,7 @@ module RuboCop
10
10
  if valid_name?(node, name)
11
11
  correct_style_detected
12
12
  else
13
- add_offense(node, location: name_range, message: message(style)) do
13
+ add_offense(name_range, message: message(style)) do
14
14
  report_opposing_styles(node, name)
15
15
  end
16
16
  end
@@ -9,7 +9,7 @@ module RuboCop
9
9
 
10
10
  FORMATS = {
11
11
  snake_case: /^@{0,2}[\da-z_]+[!?=]?$/,
12
- camelCase: /^@{0,2}_?[a-z][\da-zA-Z]+[!?=]?$/
12
+ camelCase: /^@{0,2}(?:_|_?[a-z][\da-zA-Z]*)[!?=]?$/
13
13
  }.freeze
14
14
  end
15
15
  end
@@ -41,11 +41,11 @@ module RuboCop
41
41
  end
42
42
 
43
43
  def interpreter_directive_comment?(comment)
44
- comment.text =~ /^#\s*(frozen_string_literal|encoding):/
44
+ /^#\s*(frozen_string_literal|encoding):/.match?(comment.text)
45
45
  end
46
46
 
47
47
  def rubocop_directive_comment?(comment)
48
- comment.text =~ CommentConfig::COMMENT_DIRECTIVE_REGEXP
48
+ CommentConfig::COMMENT_DIRECTIVE_REGEXP.match?(comment.text)
49
49
  end
50
50
  end
51
51
  end
@@ -51,7 +51,7 @@ module RuboCop
51
51
 
52
52
  def accept_end_kw_alignment?(end_loc)
53
53
  end_loc.nil? || # Discard modifier forms of if/while/until.
54
- processed_source.lines[end_loc.line - 1] !~ /\A[ \t]*end/
54
+ !/\A[ \t]*end/.match?(processed_source.lines[end_loc.line - 1])
55
55
  end
56
56
 
57
57
  def style_parameter_name
@@ -10,7 +10,9 @@ module RuboCop
10
10
  PATTERN
11
11
 
12
12
  base.def_node_matcher :class_new_definition, <<~PATTERN
13
- [!^(casgn nil? :#{base::SUPERCLASS} ...) (send (const nil? :Class) :new #{base::BASE_PATTERN})]
13
+ [!^(casgn {nil? cbase} :#{base::SUPERCLASS} ...)
14
+ !^^(casgn {nil? cbase} :#{base::SUPERCLASS} (block ...))
15
+ (send (const {nil? cbase} :Class) :new #{base::BASE_PATTERN})]
14
16
  PATTERN
15
17
  end
16
18
 
@@ -17,7 +17,7 @@ module RuboCop
17
17
 
18
18
  def method_uses_parens?(node, limit)
19
19
  source = node.source_range.source_line[0...limit.loc.column]
20
- source =~ /\s*\(\s*$/
20
+ /\s*\(\s*$/.match?(source)
21
21
  end
22
22
 
23
23
  def check_children_line_break(node, children, start = node)
@@ -152,7 +152,7 @@ module RuboCop
152
152
  expression
153
153
  end
154
154
 
155
- def argument_in_method_call(node, kind)
155
+ def argument_in_method_call(node, kind) # rubocop:todo Metrics/CyclomaticComplexity
156
156
  node.each_ancestor(:send, :block).find do |a|
157
157
  # If the node is inside a block, it makes no difference if that block
158
158
  # is an argument in a method call. It doesn't count.
@@ -7,19 +7,17 @@ module RuboCop
7
7
  # 2. Added to NilClass by explicitly requiring any standard libraries
8
8
  # 3. Cop's configuration parameter AllowedMethods.
9
9
  module NilMethods
10
+ include AllowedMethods
11
+
10
12
  private
11
13
 
12
14
  def nil_methods
13
- nil.methods + other_stdlib_methods + allowed_methods
15
+ nil.methods + other_stdlib_methods + allowed_methods.map(&:to_sym)
14
16
  end
15
17
 
16
18
  def other_stdlib_methods
17
19
  [:to_d]
18
20
  end
19
-
20
- def allowed_methods
21
- cop_config['AllowedMethods'].map(&:to_sym)
22
- end
23
21
  end
24
22
  end
25
23
  end
@@ -15,8 +15,13 @@ module RuboCop
15
15
  node.source_range
16
16
  end
17
17
 
18
+ def gem_canonical_name(name)
19
+ name = name.tr('-_', '') unless cop_config['ConsiderPunctuation']
20
+ name.downcase
21
+ end
22
+
18
23
  def case_insensitive_out_of_order?(string_a, string_b)
19
- string_a.downcase < string_b.downcase
24
+ gem_canonical_name(string_a) < gem_canonical_name(string_b)
20
25
  end
21
26
 
22
27
  def consecutive_lines(previous, current)
@@ -9,8 +9,7 @@ module RuboCop
9
9
  def parens_required?(node)
10
10
  range = node.source_range
11
11
  source = range.source_buffer.source
12
- source[range.begin_pos - 1] =~ /[a-z]/ ||
13
- source[range.end_pos] =~ /[a-z]/
12
+ /[a-z]/.match?(source[range.begin_pos - 1]) || /[a-z]/.match?(source[range.end_pos])
14
13
  end
15
14
  end
16
15
  end
@@ -87,7 +87,7 @@ module RuboCop
87
87
  end
88
88
 
89
89
  def aligned_words?(range, line)
90
- line[range.column - 1, 2] =~ /\s\S/
90
+ /\s\S/.match?(line[range.column - 1, 2])
91
91
  end
92
92
 
93
93
  def aligned_char?(range, line)
@@ -109,7 +109,7 @@ module RuboCop
109
109
 
110
110
  def move_pos(src, pos, step, condition, regexp)
111
111
  offset = step == -1 ? -1 : 0
112
- pos += step while condition && src[pos + offset] =~ regexp
112
+ pos += step while condition && regexp.match?(src[pos + offset])
113
113
  pos.negative? ? 0 : pos
114
114
  end
115
115
  end
@@ -11,6 +11,33 @@ module RuboCop
11
11
 
12
12
  regopt.children.include?(:x)
13
13
  end
14
+
15
+ def pattern_source(node)
16
+ freespace_mode = freespace_mode_regexp?(node)
17
+
18
+ node.children.reject(&:regopt_type?).map do |child|
19
+ source_with_comments_and_interpolations_blanked(child, freespace_mode)
20
+ end.join
21
+ end
22
+
23
+ def source_with_comments_and_interpolations_blanked(child, freespace_mode)
24
+ source = child.source
25
+
26
+ # We don't want to consider the contents of interpolations or free-space mode comments as
27
+ # part of the pattern source, but need to preserve their width, to allow offsets to
28
+ # correctly line up with the original source: spaces have no effect, and preserve width.
29
+ if child.begin_type?
30
+ replace_match_with_spaces(source, /.*/) # replace all content
31
+ elsif freespace_mode
32
+ replace_match_with_spaces(source, /(?<!\\)#.*/) # replace any comments
33
+ else
34
+ source
35
+ end
36
+ end
37
+
38
+ def replace_match_with_spaces(source, pattern)
39
+ source.sub(pattern) { ' ' * Regexp.last_match[0].length }
40
+ end
14
41
  end
15
42
  end
16
43
  end
@@ -17,9 +17,9 @@ module RuboCop
17
17
  end
18
18
 
19
19
  def non_eligible_node?(node)
20
- node.nonempty_line_count > 3 ||
21
- !node.modifier_form? &&
22
- processed_source.commented?(node.loc.end)
20
+ node.modifier_form? ||
21
+ node.nonempty_line_count > 3 ||
22
+ processed_source.commented?(node.loc.end)
23
23
  end
24
24
 
25
25
  def non_eligible_body?(body)
@@ -15,7 +15,7 @@ module RuboCop
15
15
  if style == :single_quotes
16
16
  !double_quotes_required?(src)
17
17
  else
18
- src !~ /" | \\[^'] | \#(@|\{)/x
18
+ !/" | \\[^'] | \#(@|\{)/x.match?(src)
19
19
  end
20
20
  end
21
21
  end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  private
15
15
 
16
16
  def side_space_range(range:, side:)
17
- buffer = @processed_source.buffer
17
+ buffer = processed_source.buffer
18
18
  src = buffer.source
19
19
 
20
20
  begin_pos = range.begin_pos
@@ -47,7 +47,7 @@ module RuboCop
47
47
  def token_table
48
48
  @token_table ||= begin
49
49
  table = {}
50
- @processed_source.tokens.each_with_index do |t, ix|
50
+ processed_source.tokens.each_with_index do |t, ix|
51
51
  table[t.line] ||= {}
52
52
  table[t.line][t.column] = ix
53
53
  end
@@ -55,6 +55,11 @@ module RuboCop
55
55
  end
56
56
  end
57
57
 
58
+ def on_new_investigation
59
+ @token_table = nil
60
+ super
61
+ end
62
+
58
63
  def no_space_offenses(node, # rubocop:disable Metrics/ParameterLists
59
64
  left_token,
60
65
  right_token,
@@ -87,15 +92,15 @@ module RuboCop
87
92
  return false unless token
88
93
 
89
94
  if side == :left
90
- String(token.space_after?) =~ SINGLE_SPACE_REGEXP
95
+ SINGLE_SPACE_REGEXP.match?(String(token.space_after?))
91
96
  else
92
- String(token.space_before?) =~ SINGLE_SPACE_REGEXP
97
+ SINGLE_SPACE_REGEXP.match?(String(token.space_before?))
93
98
  end
94
99
  end
95
100
 
96
101
  def reposition(src, pos, step)
97
102
  offset = step == -1 ? -1 : 0
98
- pos += step while src[pos + offset] =~ SINGLE_SPACE_REGEXP
103
+ pos += step while SINGLE_SPACE_REGEXP.match?(src[pos + offset])
99
104
  pos.negative? ? 0 : pos
100
105
  end
101
106
 
@@ -16,19 +16,9 @@ module RuboCop
16
16
  end
17
17
 
18
18
  def code_length(node)
19
- body = extract_body(node)
20
- lines = body&.source&.lines || []
21
-
22
- lines.count { |line| !irrelevant_line(line) }
23
- end
24
-
25
- def extract_body(node)
26
- case node.type
27
- when :block, :def, :defs
28
- node.body
29
- else
30
- node
31
- end
19
+ Metrics::Utils::CodeLengthCalculator.new(node,
20
+ count_comments: count_comments?,
21
+ foldable_types: count_as_one).calculate
32
22
  end
33
23
  end
34
24
  end
@@ -31,7 +31,7 @@ module RuboCop
31
31
  # If there is any heredoc in items, then match the comma succeeding
32
32
  # any whitespace (except newlines), otherwise allow for newlines
33
33
  comma_regex = any_heredoc?(items) ? /\A[^\S\n]*,/ : /\A\s*,/
34
- range.source =~ comma_regex && range.source.index(',')
34
+ comma_regex.match?(range.source) && range.source.index(',')
35
35
  end
36
36
 
37
37
  def check_comma(node, kind, comma_pos)
@@ -15,11 +15,13 @@ module RuboCop
15
15
  args.each do |arg|
16
16
  # Argument names might be "_" or prefixed with "_" to indicate they
17
17
  # are unused. Trim away this prefix and only analyse the basename.
18
- full_name = arg.children.first.to_s
18
+ name_child = arg.children.first
19
+ next if name_child.nil?
20
+
21
+ full_name = name_child.to_s
19
22
  next if full_name == '_'
20
23
 
21
24
  name = full_name.gsub(/\A(_+)/, '')
22
- next if (arg.restarg_type? || arg.kwrestarg_type?) && name.empty?
23
25
  next if allowed_names.include?(name)
24
26
 
25
27
  range = arg_range(arg, name.size)
@@ -44,7 +46,7 @@ module RuboCop
44
46
  end
45
47
 
46
48
  def uppercase?(name)
47
- name =~ /[[:upper:]]/
49
+ /[[:upper:]]/.match?(name)
48
50
  end
49
51
 
50
52
  def name_type(node)
@@ -62,7 +64,7 @@ module RuboCop
62
64
  end
63
65
 
64
66
  def ends_with_num?(name)
65
- name[-1] =~ /\d/
67
+ /\d/.match?(name[-1])
66
68
  end
67
69
 
68
70
  def length_offense(node, range)
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Help methods for determining node visibility.
6
+ module VisibilityHelp
7
+ extend NodePattern::Macros
8
+
9
+ VISIBILITY_SCOPES = %i[private protected public].freeze
10
+
11
+ private
12
+
13
+ def node_visibility(node)
14
+ scope = find_visibility_start(node)
15
+ scope&.method_name || :public
16
+ end
17
+
18
+ def find_visibility_start(node)
19
+ left_siblings_of(node)
20
+ .reverse
21
+ .find(&method(:visibility_block?))
22
+ end
23
+
24
+ # Navigate to find the last protected method
25
+ def find_visibility_end(node)
26
+ possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
27
+ right = right_siblings_of(node)
28
+ right.find do |child_node|
29
+ possible_visibilities.include?(node_visibility(child_node))
30
+ end || right.last
31
+ end
32
+
33
+ def left_siblings_of(node)
34
+ siblings_of(node)[0, node.sibling_index]
35
+ end
36
+
37
+ def right_siblings_of(node)
38
+ siblings_of(node)[node.sibling_index..-1]
39
+ end
40
+
41
+ def siblings_of(node)
42
+ node.parent.children
43
+ end
44
+
45
+ def_node_matcher :visibility_block?, <<~PATTERN
46
+ (send nil? { :private :protected :public })
47
+ PATTERN
48
+ end
49
+ end
50
+ end
@@ -5,7 +5,9 @@
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Naming
8
- # This cop checks for non-ascii characters in identifier names.
8
+ # This cop checks for non-ascii characters in identifier and constant names.
9
+ # Identifiers are always checked and whether constants are checked
10
+ # can be controlled using AsciiConstants config.
9
11
  #
10
12
  # @example
11
13
  # # bad
@@ -36,21 +38,42 @@ module RuboCop
36
38
  # # good
37
39
  # params[:width_gteq]
38
40
  #
41
+ # @example AsciiConstants: true (default)
42
+ # # bad
43
+ # class Foö
44
+ # end
45
+ #
46
+ # FOÖ = "foo"
47
+ #
48
+ # @example AsciiConstants: false
49
+ # # good
50
+ # class Foö
51
+ # end
52
+ #
53
+ # FOÖ = "foo"
54
+ #
39
55
  class AsciiIdentifiers < Cop
40
56
  include RangeHelp
41
57
 
42
- MSG = 'Use only ascii symbols in identifiers.'
58
+ IDENTIFIER_MSG = 'Use only ascii symbols in identifiers.'
59
+ CONSTANT_MSG = 'Use only ascii symbols in constants.'
43
60
 
44
61
  def investigate(processed_source)
45
62
  processed_source.each_token do |token|
46
- next unless token.type == :tIDENTIFIER && !token.text.ascii_only?
63
+ next if !should_check?(token) || token.text.ascii_only?
47
64
 
48
- add_offense(token, location: first_offense_range(token))
65
+ message = token.type == :tIDENTIFIER ? IDENTIFIER_MSG : CONSTANT_MSG
66
+ add_offense(token, location: first_offense_range(token), message: message)
49
67
  end
50
68
  end
51
69
 
52
70
  private
53
71
 
72
+ def should_check?(token)
73
+ token.type == :tIDENTIFIER ||
74
+ (token.type == :tCONSTANT && cop_config['AsciiConstants'])
75
+ end
76
+
54
77
  def first_offense_range(identifier)
55
78
  expression = identifier.pos
56
79
  first_offense = first_non_ascii_chars(identifier.text)