rubocop 0.48.1 → 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/config/default.yml +397 -357
  4. data/config/disabled.yml +29 -29
  5. data/config/enabled.yml +366 -326
  6. data/lib/rubocop.rb +85 -70
  7. data/lib/rubocop/ast/builder.rb +4 -1
  8. data/lib/rubocop/ast/node.rb +2 -2
  9. data/lib/rubocop/ast/node/and_node.rb +1 -1
  10. data/lib/rubocop/ast/node/args_node.rb +24 -0
  11. data/lib/rubocop/ast/node/block_node.rb +107 -0
  12. data/lib/rubocop/ast/node/case_node.rb +1 -1
  13. data/lib/rubocop/ast/node/ensure_node.rb +1 -1
  14. data/lib/rubocop/ast/node/for_node.rb +1 -1
  15. data/lib/rubocop/ast/node/if_node.rb +1 -1
  16. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +74 -0
  17. data/lib/rubocop/ast/node/or_node.rb +1 -1
  18. data/lib/rubocop/ast/node/pair_node.rb +1 -1
  19. data/lib/rubocop/ast/node/resbody_node.rb +1 -1
  20. data/lib/rubocop/ast/node/send_node.rb +36 -57
  21. data/lib/rubocop/ast/node/super_node.rb +42 -0
  22. data/lib/rubocop/ast/node/until_node.rb +1 -1
  23. data/lib/rubocop/ast/node/when_node.rb +1 -1
  24. data/lib/rubocop/ast/node/while_node.rb +1 -1
  25. data/lib/rubocop/cli.rb +10 -0
  26. data/lib/rubocop/config.rb +23 -7
  27. data/lib/rubocop/config_loader.rb +19 -3
  28. data/lib/rubocop/cop/badge.rb +1 -1
  29. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  30. data/lib/rubocop/cop/commissioner.rb +1 -1
  31. data/lib/rubocop/cop/cop.rb +10 -0
  32. data/lib/rubocop/cop/{style → layout}/access_modifier_indentation.rb +33 -3
  33. data/lib/rubocop/cop/{style → layout}/align_array.rb +16 -1
  34. data/lib/rubocop/cop/{style → layout}/align_hash.rb +1 -1
  35. data/lib/rubocop/cop/{style → layout}/align_parameters.rb +29 -1
  36. data/lib/rubocop/cop/{style → layout}/block_end_newline.rb +10 -5
  37. data/lib/rubocop/cop/{style → layout}/case_indentation.rb +64 -1
  38. data/lib/rubocop/cop/{style → layout}/closing_parenthesis_indentation.rb +2 -2
  39. data/lib/rubocop/cop/{style → layout}/comment_indentation.rb +1 -1
  40. data/lib/rubocop/cop/{style → layout}/dot_position.rb +1 -1
  41. data/lib/rubocop/cop/{style → layout}/else_alignment.rb +1 -1
  42. data/lib/rubocop/cop/{style → layout}/empty_line_after_magic_comment.rb +1 -1
  43. data/lib/rubocop/cop/{style → layout}/empty_line_between_defs.rb +1 -1
  44. data/lib/rubocop/cop/{style → layout}/empty_lines.rb +1 -1
  45. data/lib/rubocop/cop/{style → layout}/empty_lines_around_access_modifier.rb +2 -7
  46. data/lib/rubocop/cop/{style → layout}/empty_lines_around_begin_body.rb +1 -1
  47. data/lib/rubocop/cop/{style → layout}/empty_lines_around_block_body.rb +2 -4
  48. data/lib/rubocop/cop/{style → layout}/empty_lines_around_class_body.rb +1 -1
  49. data/lib/rubocop/cop/{style → layout}/empty_lines_around_exception_handling_keywords.rb +1 -1
  50. data/lib/rubocop/cop/{style → layout}/empty_lines_around_method_body.rb +1 -1
  51. data/lib/rubocop/cop/{style → layout}/empty_lines_around_module_body.rb +1 -1
  52. data/lib/rubocop/cop/{style → layout}/end_of_line.rb +1 -1
  53. data/lib/rubocop/cop/{style → layout}/extra_spacing.rb +1 -1
  54. data/lib/rubocop/cop/{style → layout}/first_array_element_line_break.rb +1 -1
  55. data/lib/rubocop/cop/{style → layout}/first_hash_element_line_break.rb +1 -1
  56. data/lib/rubocop/cop/{style → layout}/first_method_argument_line_break.rb +1 -1
  57. data/lib/rubocop/cop/{style → layout}/first_method_parameter_line_break.rb +1 -1
  58. data/lib/rubocop/cop/{style → layout}/first_parameter_indentation.rb +1 -1
  59. data/lib/rubocop/cop/{style → layout}/indent_array.rb +1 -1
  60. data/lib/rubocop/cop/{style → layout}/indent_assignment.rb +1 -1
  61. data/lib/rubocop/cop/{style → layout}/indent_hash.rb +2 -2
  62. data/lib/rubocop/cop/{style → layout}/indent_heredoc.rb +3 -3
  63. data/lib/rubocop/cop/{style → layout}/indentation_consistency.rb +1 -1
  64. data/lib/rubocop/cop/{style → layout}/indentation_width.rb +10 -12
  65. data/lib/rubocop/cop/{style → layout}/initial_indentation.rb +1 -1
  66. data/lib/rubocop/cop/{style → layout}/leading_comment_space.rb +1 -1
  67. data/lib/rubocop/cop/{style → layout}/multiline_array_brace_layout.rb +1 -1
  68. data/lib/rubocop/cop/{style → layout}/multiline_assignment_layout.rb +1 -1
  69. data/lib/rubocop/cop/{style → layout}/multiline_block_layout.rb +21 -36
  70. data/lib/rubocop/cop/{style → layout}/multiline_hash_brace_layout.rb +5 -1
  71. data/lib/rubocop/cop/{style → layout}/multiline_method_call_brace_layout.rb +1 -1
  72. data/lib/rubocop/cop/{style → layout}/multiline_method_call_indentation.rb +3 -3
  73. data/lib/rubocop/cop/{style → layout}/multiline_method_definition_brace_layout.rb +1 -1
  74. data/lib/rubocop/cop/{style → layout}/multiline_operation_indentation.rb +6 -5
  75. data/lib/rubocop/cop/{style → layout}/rescue_ensure_alignment.rb +1 -1
  76. data/lib/rubocop/cop/{style → layout}/space_after_colon.rb +2 -2
  77. data/lib/rubocop/cop/{style → layout}/space_after_comma.rb +2 -2
  78. data/lib/rubocop/cop/{style → layout}/space_after_method_name.rb +1 -1
  79. data/lib/rubocop/cop/{style → layout}/space_after_not.rb +1 -1
  80. data/lib/rubocop/cop/{style → layout}/space_after_semicolon.rb +2 -2
  81. data/lib/rubocop/cop/{style → layout}/space_around_block_parameters.rb +7 -5
  82. data/lib/rubocop/cop/{style → layout}/space_around_equals_in_parameter_default.rb +1 -1
  83. data/lib/rubocop/cop/{style → layout}/space_around_keyword.rb +1 -1
  84. data/lib/rubocop/cop/{style → layout}/space_around_operators.rb +6 -2
  85. data/lib/rubocop/cop/{style → layout}/space_before_block_braces.rb +6 -2
  86. data/lib/rubocop/cop/{style → layout}/space_before_comma.rb +1 -1
  87. data/lib/rubocop/cop/{style → layout}/space_before_comment.rb +1 -1
  88. data/lib/rubocop/cop/{style → layout}/space_before_first_arg.rb +4 -2
  89. data/lib/rubocop/cop/{style → layout}/space_before_semicolon.rb +1 -1
  90. data/lib/rubocop/cop/{style → layout}/space_in_lambda_literal.rb +1 -1
  91. data/lib/rubocop/cop/{style → layout}/space_inside_array_percent_literal.rb +1 -1
  92. data/lib/rubocop/cop/{style → layout}/space_inside_block_braces.rb +3 -4
  93. data/lib/rubocop/cop/{style → layout}/space_inside_brackets.rb +1 -1
  94. data/lib/rubocop/cop/{style → layout}/space_inside_hash_literal_braces.rb +1 -1
  95. data/lib/rubocop/cop/{style → layout}/space_inside_parens.rb +1 -1
  96. data/lib/rubocop/cop/{style → layout}/space_inside_percent_literal_delimiters.rb +8 -7
  97. data/lib/rubocop/cop/{style → layout}/space_inside_range_literal.rb +1 -1
  98. data/lib/rubocop/cop/{style → layout}/space_inside_string_interpolation.rb +1 -1
  99. data/lib/rubocop/cop/{style → layout}/tab.rb +1 -1
  100. data/lib/rubocop/cop/{style → layout}/trailing_blank_lines.rb +1 -1
  101. data/lib/rubocop/cop/{style → layout}/trailing_whitespace.rb +2 -2
  102. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  103. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -4
  104. data/lib/rubocop/cop/lint/debugger.rb +0 -15
  105. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -1
  106. data/lib/rubocop/cop/lint/rescue_type.rb +81 -0
  107. data/lib/rubocop/cop/lint/script_permission.rb +42 -0
  108. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
  109. data/lib/rubocop/cop/message_annotator.rb +23 -13
  110. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  111. data/lib/rubocop/cop/mixin/array_min_size.rb +59 -0
  112. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +10 -11
  113. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  114. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  115. data/lib/rubocop/cop/mixin/enforce_superclass.rb +36 -0
  116. data/lib/rubocop/cop/mixin/hash_alignment.rb +1 -1
  117. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -3
  118. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  119. data/lib/rubocop/cop/performance/caller.rb +41 -0
  120. data/lib/rubocop/cop/performance/compare_with_block.rb +60 -14
  121. data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
  122. data/lib/rubocop/cop/performance/redundant_merge.rb +2 -0
  123. data/lib/rubocop/cop/rails/action_filter.rb +1 -3
  124. data/lib/rubocop/cop/rails/application_job.rb +32 -0
  125. data/lib/rubocop/cop/rails/application_record.rb +32 -0
  126. data/lib/rubocop/cop/rails/blank.rb +9 -3
  127. data/lib/rubocop/cop/rails/output_safety.rb +59 -15
  128. data/lib/rubocop/cop/rails/present.rb +9 -3
  129. data/lib/rubocop/cop/rails/relative_date_constant.rb +35 -4
  130. data/lib/rubocop/cop/rails/reversible_migration.rb +82 -18
  131. data/lib/rubocop/cop/rails/save_bang.rb +7 -2
  132. data/lib/rubocop/cop/rails/skips_model_validations.rb +7 -0
  133. data/lib/rubocop/cop/registry.rb +4 -3
  134. data/lib/rubocop/cop/security/eval.rb +9 -3
  135. data/lib/rubocop/cop/style/and_or.rb +1 -1
  136. data/lib/rubocop/cop/style/block_delimiters.rb +11 -17
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  138. data/lib/rubocop/cop/style/collection_methods.rb +1 -3
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  140. data/lib/rubocop/cop/style/copyright.rb +2 -2
  141. data/lib/rubocop/cop/style/documentation_method.rb +1 -1
  142. data/lib/rubocop/cop/style/each_for_simple_loop.rb +2 -1
  143. data/lib/rubocop/cop/style/each_with_object.rb +10 -6
  144. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  145. data/lib/rubocop/cop/style/for.rb +4 -5
  146. data/lib/rubocop/cop/style/format_string.rb +49 -0
  147. data/lib/rubocop/cop/style/format_string_token.rb +141 -0
  148. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  149. data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
  150. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -1
  151. data/lib/rubocop/cop/style/inverse_methods.rb +10 -1
  152. data/lib/rubocop/cop/style/lambda.rb +9 -9
  153. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -0
  154. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -3
  155. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -2
  156. data/lib/rubocop/cop/style/method_name.rb +8 -2
  157. data/lib/rubocop/cop/style/mixin_grouping.rb +41 -3
  158. data/lib/rubocop/cop/style/multiline_block_chain.rb +7 -11
  159. data/lib/rubocop/cop/style/multiple_comparison.rb +77 -0
  160. data/lib/rubocop/cop/style/next.rb +11 -22
  161. data/lib/rubocop/cop/style/parallel_assignment.rb +10 -19
  162. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
  163. data/lib/rubocop/cop/style/self_assignment.rb +4 -0
  164. data/lib/rubocop/cop/style/single_line_block_params.rb +23 -17
  165. data/lib/rubocop/cop/style/symbol_array.rb +24 -13
  166. data/lib/rubocop/cop/style/symbol_proc.rb +4 -0
  167. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  168. data/lib/rubocop/cop/style/unneeded_interpolation.rb +4 -0
  169. data/lib/rubocop/cop/style/word_array.rb +33 -53
  170. data/lib/rubocop/cop/style/yoda_condition.rb +78 -0
  171. data/lib/rubocop/cop/team.rb +1 -14
  172. data/lib/rubocop/cop/util.rb +16 -0
  173. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -11
  174. data/lib/rubocop/node_pattern.rb +52 -52
  175. data/lib/rubocop/options.rb +25 -0
  176. data/lib/rubocop/path_util.rb +17 -1
  177. data/lib/rubocop/result_cache.rb +8 -7
  178. data/lib/rubocop/rspec/expect_offense.rb +167 -0
  179. data/lib/rubocop/rspec/shared_examples.rb +0 -8
  180. data/lib/rubocop/rspec/support.rb +1 -0
  181. data/lib/rubocop/runner.rb +12 -2
  182. data/lib/rubocop/target_finder.rb +5 -0
  183. data/lib/rubocop/version.rb +1 -1
  184. metadata +101 -72
@@ -143,7 +143,8 @@ module RuboCop
143
143
 
144
144
  def source_location(node)
145
145
  range = node.location.expression
146
- "#{range.source_buffer.name}:#{range.line}"
146
+ path = smart_path(range.source_buffer.name)
147
+ "#{path}:#{range.line}"
147
148
  end
148
149
  end
149
150
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Check for arguments to `rescue` that will result in a `TypeError`
7
+ # if an exception is raised.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # begin
12
+ # bar
13
+ # rescue nil
14
+ # baz
15
+ # end
16
+ #
17
+ # # bad
18
+ # def foo
19
+ # bar
20
+ # rescue 1, 'a', "#{b}", 0.0, [], {}
21
+ # baz
22
+ # end
23
+ #
24
+ # # good
25
+ # begin
26
+ # bar
27
+ # rescue
28
+ # baz
29
+ # end
30
+ #
31
+ # # good
32
+ # def foo
33
+ # bar
34
+ # rescue NameError
35
+ # baz
36
+ # end
37
+ class RescueType < Cop
38
+ include RescueNode
39
+
40
+ MSG = 'Rescuing from `%s` will raise a `TypeError` instead of ' \
41
+ 'catching the actual exception.'.freeze
42
+ INVALID_TYPES = %i[array dstr float hash nil int str sym].freeze
43
+
44
+ def on_resbody(node)
45
+ rescued, _, _body = *node
46
+ return if rescued.nil?
47
+ exceptions = *rescued
48
+ invalid_exceptions = invalid_exceptions(exceptions)
49
+ return if invalid_exceptions.empty?
50
+
51
+ add_offense(node,
52
+ node.loc.keyword.join(rescued.loc.expression),
53
+ format(MSG, invalid_exceptions.map(&:source).join(', ')))
54
+ end
55
+
56
+ def autocorrect(node)
57
+ rescued, _, _body = *node
58
+ exceptions = *rescued
59
+ valid_exceptions = exceptions - invalid_exceptions(exceptions)
60
+ correction = valid_exceptions.map(&:source).join(', ')
61
+ correction = " #{correction}" unless correction.empty?
62
+ range = Parser::Source::Range.new(node.loc.expression,
63
+ node.loc.keyword.end_pos,
64
+ rescued.loc.expression.end_pos)
65
+
66
+ lambda do |corrector|
67
+ corrector.replace(range, correction)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def invalid_exceptions(exceptions)
74
+ exceptions.select do |exception|
75
+ INVALID_TYPES.include?(exception.type)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks if a file which has a shebang line as
7
+ # its first line is granted execute permission.
8
+ class ScriptPermission < Cop
9
+ MSG = "Script file %s doesn't have execute permission.".freeze
10
+ SHEBANG = '#!'.freeze
11
+
12
+ def investigate(processed_source)
13
+ return if Platform.windows?
14
+ return unless start_with_shebang?(processed_source)
15
+ return if executable?(processed_source)
16
+ comment = processed_source.comments[0]
17
+ message = format_message_from(processed_source)
18
+ add_offense(comment, :expression, message)
19
+ end
20
+
21
+ private
22
+
23
+ def start_with_shebang?(processed_source)
24
+ return false if processed_source[0].nil?
25
+ processed_source[0].start_with?(SHEBANG)
26
+ end
27
+
28
+ def executable?(processed_source)
29
+ # Returns true if stat is executable or if the operating system
30
+ # doesn't distinguish executable files from nonexecutable files.
31
+ # See at: https://github.com/ruby/ruby/blob/ruby_2_4/file.c#L5362
32
+ File.stat(processed_source.buffer.name).executable?
33
+ end
34
+
35
+ def format_message_from(processed_source)
36
+ basename = File.basename(processed_source.buffer.name)
37
+ format(MSG, basename)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -104,7 +104,7 @@ module RuboCop
104
104
  def on_block(node)
105
105
  return unless eval_call?(node)
106
106
 
107
- check_node(node.children[2]) # block body
107
+ check_node(node.body)
108
108
  end
109
109
 
110
110
  def on_sclass(node)
@@ -15,6 +15,12 @@ module RuboCop
15
15
  class MessageAnnotator
16
16
  attr_reader :options, :config, :cop_config
17
17
 
18
+ @style_guide_urls = {}
19
+
20
+ class << self
21
+ attr_reader :style_guide_urls
22
+ end
23
+
18
24
  # @param config [RuboCop::Config] Check configs for all cops
19
25
  # @note Message Annotator specifically checks the
20
26
  # following config options for_all_cops
@@ -28,14 +34,14 @@ module RuboCop
28
34
  # @option cop_config [String] :Reference Full reference URL
29
35
  # @option cop_config [String] :Details
30
36
  #
31
- # @param [Hash, nil] optional options
32
- # @option option [Boolean] :display_style_guide
37
+ # @param [Hash, nil] options optional
38
+ # @option options [Boolean] :display_style_guide
33
39
  # Include style guide and reference URLs
34
- # @option option [Boolean] :extra_details
40
+ # @option options [Boolean] :extra_details
35
41
  # Include cop specific details
36
- # @option option [Boolean] :debug
42
+ # @option options [Boolean] :debug
37
43
  # Include debug output
38
- # @option option [Boolean] :display_cop_names
44
+ # @option options [Boolean] :display_cop_names
39
45
  # Include cop name
40
46
  def initialize(config, cop_config, options)
41
47
  @config = config
@@ -49,7 +55,7 @@ module RuboCop
49
55
  # @return [String] annotated message
50
56
  def annotate(message, name)
51
57
  message = "#{name}: #{message}" if display_cop_names?
52
- message += " #{details}" if extra_details?
58
+ message += " #{details}" if extra_details? && details
53
59
  if display_style_guide?
54
60
  links = urls.join(', ')
55
61
  message = "#{message} (#{links})"
@@ -67,16 +73,20 @@ module RuboCop
67
73
  url = cop_config['StyleGuide']
68
74
  return nil if url.nil? || url.empty?
69
75
 
70
- base_url = config.for_all_cops['StyleGuideBaseURL']
71
- return url if base_url.nil? || base_url.empty?
72
-
73
- URI.join(base_url, url).to_s
76
+ self.class.style_guide_urls[url] ||= begin
77
+ base_url = config.for_all_cops['StyleGuideBaseURL']
78
+ if base_url.nil? || base_url.empty?
79
+ url
80
+ else
81
+ URI.join(base_url, url).to_s
82
+ end
83
+ end
74
84
  end
75
85
 
76
86
  def display_style_guide?
77
- !urls.empty? &&
78
- (options[:display_style_guide] ||
79
- config.for_all_cops['DisplayStyleGuide'])
87
+ (options[:display_style_guide] ||
88
+ config.for_all_cops['DisplayStyleGuide']) &&
89
+ !urls.empty?
80
90
  end
81
91
 
82
92
  def reference_url
@@ -13,7 +13,7 @@ module RuboCop
13
13
  LABEL = 'Block'.freeze
14
14
 
15
15
  def on_block(node)
16
- return if excluded_methods.include?(node.method_name.to_s)
16
+ return if excluded_methods.include?(node.send_node.method_name.to_s)
17
17
  check_code_length(node)
18
18
  end
19
19
 
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Handles the `MinSize` configuration option for array-based cops
6
+ # `Style/SymbolArray` and `Style/WordArray`, which check for use of the
7
+ # relevant percent literal syntax such as `%i[...]` and `%w[...]`
8
+ module ArrayMinSize
9
+ private
10
+
11
+ def below_array_length?(node)
12
+ node.values.length < min_size_config
13
+ end
14
+
15
+ def min_size_config
16
+ cop_config['MinSize']
17
+ end
18
+
19
+ def array_style_detected(style, ary_size)
20
+ cfg = config_to_allow_offenses
21
+ return if cfg['Enabled'] == false
22
+
23
+ largest_brackets = largest_brackets_size(style, ary_size)
24
+ smallest_percent = smallest_percent_size(style, ary_size)
25
+
26
+ if cfg['EnforcedStyle'] == style.to_s
27
+ # do nothing
28
+ elsif cfg['EnforcedStyle'].nil?
29
+ cfg['EnforcedStyle'] = style.to_s
30
+ elsif smallest_percent <= largest_brackets
31
+ self.config_to_allow_offenses = { 'Enabled' => false }
32
+ else
33
+ cfg['EnforcedStyle'] = 'percent'
34
+ cfg['MinSize'] = largest_brackets + 1
35
+ end
36
+ end
37
+
38
+ def largest_brackets_size(style, ary_size)
39
+ self.class.largest_brackets ||= -Float::INFINITY
40
+
41
+ if style == :brackets && ary_size > self.class.largest_brackets
42
+ self.class.largest_brackets = ary_size
43
+ end
44
+
45
+ self.class.largest_brackets
46
+ end
47
+
48
+ def smallest_percent_size(style, ary_size)
49
+ @smallest_percent ||= Float::INFINITY
50
+
51
+ if style == :percent && ary_size < @smallest_percent
52
+ @smallest_percent = ary_size
53
+ end
54
+
55
+ @smallest_percent
56
+ end
57
+ end
58
+ end
59
+ end
@@ -27,12 +27,17 @@ module RuboCop
27
27
  # (if there is more than one which matches the observed code)
28
28
  detected_as_strings = Array(detected).map(&:to_s)
29
29
 
30
- if !detected_style # we haven't observed any specific style yet
31
- self.detected_style = detected_as_strings
32
- elsif detected_style.is_a?(Array)
33
- self.detected_style &= detected_as_strings
34
- elsif !detected.include?(detected_style)
30
+ updated_list = if detected_style
31
+ detected_style & detected_as_strings
32
+ else
33
+ # We haven't observed any specific style yet.
34
+ detected_as_strings
35
+ end
36
+ if updated_list.empty?
35
37
  no_acceptable_style!
38
+ else
39
+ self.detected_style = updated_list
40
+ config_to_allow_offenses[style_parameter_name] = updated_list.first
36
41
  end
37
42
  end
38
43
 
@@ -42,7 +47,6 @@ module RuboCop
42
47
 
43
48
  def no_acceptable_style!
44
49
  self.config_to_allow_offenses = { 'Enabled' => false }
45
- Formatter::DisabledConfigFormatter.detected_styles[cop_name] = []
46
50
  end
47
51
 
48
52
  def detected_style
@@ -51,11 +55,6 @@ module RuboCop
51
55
 
52
56
  def detected_style=(style)
53
57
  Formatter::DisabledConfigFormatter.detected_styles[cop_name] = style
54
-
55
- return no_acceptable_style! if style.nil?
56
- return no_acceptable_style! if style.empty?
57
-
58
- config_to_allow_offenses[style_parameter_name] = style.first
59
58
  end
60
59
 
61
60
  alias conflicting_styles_detected no_acceptable_style!
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- # Common functionality for checking if nodes.
5
+ # Common functionality for checking def nodes.
6
6
  module DefNode
7
7
  extend NodePattern::Macros
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Layout
6
6
  # Common functionality for checking if presence/absence of empty lines
7
7
  # around some kind of body matches the configuration.
8
8
  module EmptyLinesAroundBody
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for enforcing a specific superclass
6
+ module EnforceSuperclass
7
+ def self.included(base)
8
+ base.def_node_matcher :class_definition, <<-PATTERN
9
+ (class (const _ !:#{base::SUPERCLASS}) #{base::BASE_PATTERN} ...)
10
+ PATTERN
11
+
12
+ base.def_node_matcher :class_new_definition, <<-PATTERN
13
+ [!^(casgn nil :#{base::SUPERCLASS} ...) (send (const nil :Class) :new #{base::BASE_PATTERN})]
14
+ PATTERN
15
+ end
16
+
17
+ def on_class(node)
18
+ class_definition(node) do
19
+ add_offense(node.children[1], :expression, self.class::MSG)
20
+ end
21
+ end
22
+
23
+ def on_send(node)
24
+ class_new_definition(node) do
25
+ add_offense(node.children.last, :expression, self.class::MSG)
26
+ end
27
+ end
28
+
29
+ def autocorrect(node)
30
+ lambda do |corrector|
31
+ corrector.replace(node.source_range, self.class::SUPERCLASS)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- # Common funcitonality for checking hash alignment.
5
+ # Common functionality for checking hash alignment.
6
6
  module HashAlignment
7
7
  # Handles calculation of deltas when the enforced style is 'key'.
8
8
  class KeyAlignment
@@ -49,7 +49,7 @@ module RuboCop
49
49
  if kw_node_with_special_indentation(node)
50
50
  # This cop could have its own IndentationWidth configuration
51
51
  configured_indentation_width +
52
- @config.for_cop('Style/IndentationWidth')['Width']
52
+ @config.for_cop('Layout/IndentationWidth')['Width']
53
53
  else
54
54
  configured_indentation_width
55
55
  end
@@ -105,7 +105,7 @@ module RuboCop
105
105
  end
106
106
  end
107
107
 
108
- def argument_in_method_call(node)
108
+ def argument_in_method_call(node, kind)
109
109
  node.each_ancestor(:send, :block).find do |a|
110
110
  # If the node is inside a block, it makes no difference if that block
111
111
  # is an argument in a method call. It doesn't count.
@@ -113,7 +113,11 @@ module RuboCop
113
113
 
114
114
  next if a.setter_method?
115
115
 
116
- a.arguments.any? { |arg| within_node?(node, arg) }
116
+ a.arguments.any? do |arg|
117
+ within_node?(node, arg) && (kind == :with_or_without_parentheses ||
118
+ kind == :with_parentheses &&
119
+ parentheses?(node.parent))
120
+ end
117
121
  end
118
122
  end
119
123
 
@@ -35,7 +35,7 @@ module RuboCop
35
35
  end
36
36
 
37
37
  def space_required_after_lcurly?
38
- cfg = config.for_cop('Style/SpaceInsideBlockBraces')
38
+ cfg = config.for_cop('Layout/SpaceInsideBlockBraces')
39
39
  style = cfg['EnforcedStyle'] || 'space'
40
40
  style == 'space'
41
41
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # This cop identifies places where `caller[n]`
7
+ # can be replaced by `caller(n..n).first`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # caller[n]
12
+ # caller.first
13
+ #
14
+ # # good
15
+ # caller(n..n).first
16
+ # caller(1..1).first
17
+ class Caller < Cop
18
+ MSG = 'Use `caller(n..n)` instead of `caller[n]`.'.freeze
19
+ SCOPE_METHODS = %i[first []].freeze
20
+
21
+ def_node_matcher :caller_with_scope_method?, <<-PATTERN
22
+ (send (send nil :caller ...) ${#{SCOPE_METHODS.map(&:inspect).join(' ')}} ...)
23
+ PATTERN
24
+
25
+ def on_send(node)
26
+ return unless caller_with_scope_method?(node) && slow_caller?(node)
27
+ add_offense(node, :selector)
28
+ end
29
+
30
+ private
31
+
32
+ def slow_caller?(node)
33
+ arguments = node.receiver.arguments
34
+
35
+ arguments.empty? ||
36
+ (arguments.length == 1 && arguments[0].int_type?)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end