rubocop 0.31.0 → 0.35.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +315 -0
  3. data/README.md +199 -38
  4. data/config/default.yml +91 -12
  5. data/config/disabled.yml +45 -4
  6. data/config/enabled.yml +107 -9
  7. data/lib/rubocop/ast_node.rb +48 -0
  8. data/lib/rubocop/cli.rb +11 -1
  9. data/lib/rubocop/comment_config.rb +4 -1
  10. data/lib/rubocop/config.rb +26 -17
  11. data/lib/rubocop/config_loader.rb +61 -14
  12. data/lib/rubocop/cop/commissioner.rb +7 -12
  13. data/lib/rubocop/cop/cop.rb +43 -20
  14. data/lib/rubocop/cop/lint/block_alignment.rb +1 -1
  15. data/lib/rubocop/cop/lint/circular_argument_reference.rb +69 -0
  16. data/lib/rubocop/cop/lint/debugger.rb +9 -48
  17. data/lib/rubocop/cop/lint/def_end_alignment.rb +8 -4
  18. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +42 -23
  19. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  20. data/lib/rubocop/cop/lint/duplicated_key.rb +37 -0
  21. data/lib/rubocop/cop/lint/end_alignment.rb +33 -13
  22. data/lib/rubocop/cop/lint/eval.rb +6 -2
  23. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +175 -0
  24. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
  25. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +10 -0
  26. data/lib/rubocop/cop/lint/nested_method_definition.rb +31 -0
  27. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +19 -1
  28. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  29. data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
  30. data/lib/rubocop/cop/lint/unneeded_disable.rb +72 -0
  31. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
  32. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
  33. data/lib/rubocop/cop/metrics/abc_size.rb +17 -6
  34. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  35. data/lib/rubocop/cop/metrics/method_length.rb +1 -3
  36. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  37. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  38. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  39. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -2
  40. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +28 -4
  41. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
  42. data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
  43. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
  44. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
  45. data/lib/rubocop/cop/mixin/configurable_naming.rb +14 -3
  46. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -3
  47. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +10 -1
  48. data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
  49. data/lib/rubocop/cop/mixin/if_node.rb +10 -0
  50. data/lib/rubocop/cop/mixin/method_preference.rb +28 -0
  51. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  52. data/lib/rubocop/cop/mixin/on_method_def.rb +4 -5
  53. data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
  54. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -1
  55. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +8 -1
  56. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -7
  57. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  58. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  59. data/lib/rubocop/cop/mixin/surrounding_space.rb +5 -4
  60. data/lib/rubocop/cop/offense.rb +16 -3
  61. data/lib/rubocop/cop/performance/case_when_splat.rb +160 -0
  62. data/lib/rubocop/cop/performance/count.rb +35 -30
  63. data/lib/rubocop/cop/performance/detect.rb +16 -3
  64. data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
  65. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  66. data/lib/rubocop/cop/performance/sample.rb +103 -59
  67. data/lib/rubocop/cop/performance/size.rb +2 -1
  68. data/lib/rubocop/cop/performance/string_replacement.rb +187 -0
  69. data/lib/rubocop/cop/rails/action_filter.rb +31 -5
  70. data/lib/rubocop/cop/rails/date.rb +15 -14
  71. data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
  72. data/lib/rubocop/cop/rails/read_write_attribute.rb +1 -1
  73. data/lib/rubocop/cop/rails/time_zone.rb +46 -18
  74. data/lib/rubocop/cop/style/alias.rb +1 -0
  75. data/lib/rubocop/cop/style/align_hash.rb +8 -15
  76. data/lib/rubocop/cop/style/align_parameters.rb +19 -7
  77. data/lib/rubocop/cop/style/and_or.rb +42 -13
  78. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -1
  79. data/lib/rubocop/cop/style/block_comments.rb +4 -2
  80. data/lib/rubocop/cop/style/block_delimiters.rb +69 -24
  81. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +40 -12
  82. data/lib/rubocop/cop/style/case_indentation.rb +18 -4
  83. data/lib/rubocop/cop/style/collection_methods.rb +2 -20
  84. data/lib/rubocop/cop/style/command_literal.rb +2 -10
  85. data/lib/rubocop/cop/style/comment_annotation.rb +29 -8
  86. data/lib/rubocop/cop/style/copyright.rb +5 -3
  87. data/lib/rubocop/cop/style/documentation.rb +21 -12
  88. data/lib/rubocop/cop/style/dot_position.rb +6 -0
  89. data/lib/rubocop/cop/style/double_negation.rb +4 -15
  90. data/lib/rubocop/cop/style/each_with_object.rb +17 -4
  91. data/lib/rubocop/cop/style/else_alignment.rb +2 -1
  92. data/lib/rubocop/cop/style/empty_else.rb +25 -0
  93. data/lib/rubocop/cop/style/empty_line_between_defs.rb +39 -14
  94. data/lib/rubocop/cop/style/encoding.rb +10 -4
  95. data/lib/rubocop/cop/style/extra_spacing.rb +126 -5
  96. data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
  97. data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
  98. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
  99. data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
  100. data/lib/rubocop/cop/style/first_parameter_indentation.rb +5 -3
  101. data/lib/rubocop/cop/style/for.rb +2 -1
  102. data/lib/rubocop/cop/style/hash_syntax.rb +5 -0
  103. data/lib/rubocop/cop/style/if_unless_modifier.rb +32 -5
  104. data/lib/rubocop/cop/style/indent_hash.rb +67 -37
  105. data/lib/rubocop/cop/style/indentation_width.rb +36 -10
  106. data/lib/rubocop/cop/style/initial_indentation.rb +37 -0
  107. data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
  108. data/lib/rubocop/cop/style/method_call_parentheses.rb +28 -1
  109. data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
  110. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +21 -24
  111. data/lib/rubocop/cop/style/mutable_constant.rb +35 -0
  112. data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
  113. data/lib/rubocop/cop/style/next.rb +50 -15
  114. data/lib/rubocop/cop/style/non_nil_check.rb +12 -8
  115. data/lib/rubocop/cop/style/one_line_conditional.rb +8 -4
  116. data/lib/rubocop/cop/style/option_hash.rb +64 -0
  117. data/lib/rubocop/cop/style/optional_arguments.rb +49 -0
  118. data/lib/rubocop/cop/style/parallel_assignment.rb +218 -0
  119. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -66
  120. data/lib/rubocop/cop/style/predicate_name.rb +7 -2
  121. data/lib/rubocop/cop/style/redundant_begin.rb +2 -13
  122. data/lib/rubocop/cop/style/redundant_freeze.rb +37 -0
  123. data/lib/rubocop/cop/style/redundant_return.rb +32 -3
  124. data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
  125. data/lib/rubocop/cop/style/rescue_ensure_alignment.rb +81 -0
  126. data/lib/rubocop/cop/style/rescue_modifier.rb +30 -22
  127. data/lib/rubocop/cop/style/send.rb +18 -0
  128. data/lib/rubocop/cop/style/signal_exception.rb +24 -11
  129. data/lib/rubocop/cop/style/single_line_methods.rb +8 -9
  130. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
  131. data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
  132. data/lib/rubocop/cop/style/space_inside_string_interpolation.rb +61 -0
  133. data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
  134. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
  135. data/lib/rubocop/cop/style/string_methods.rb +32 -0
  136. data/lib/rubocop/cop/style/struct_inheritance.rb +11 -10
  137. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  138. data/lib/rubocop/cop/style/symbol_proc.rb +62 -13
  139. data/lib/rubocop/cop/style/trailing_blank_lines.rb +9 -1
  140. data/lib/rubocop/cop/style/trailing_comma.rb +17 -7
  141. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
  142. data/lib/rubocop/cop/style/trivial_accessors.rb +10 -1
  143. data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
  144. data/lib/rubocop/cop/style/variable_name.rb +5 -0
  145. data/lib/rubocop/cop/style/while_until_do.rb +1 -1
  146. data/lib/rubocop/cop/style/word_array.rb +15 -2
  147. data/lib/rubocop/cop/team.rb +25 -5
  148. data/lib/rubocop/cop/util.rb +7 -2
  149. data/lib/rubocop/cop/variable_force/locatable.rb +6 -6
  150. data/lib/rubocop/cop/variable_force.rb +10 -10
  151. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  152. data/lib/rubocop/formatter/disabled_config_formatter.rb +70 -8
  153. data/lib/rubocop/formatter/formatter_set.rb +27 -1
  154. data/lib/rubocop/formatter/progress_formatter.rb +10 -2
  155. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  156. data/lib/rubocop/node_pattern.rb +390 -0
  157. data/lib/rubocop/options.rb +148 -81
  158. data/lib/rubocop/processed_source.rb +7 -2
  159. data/lib/rubocop/rake_task.rb +1 -1
  160. data/lib/rubocop/remote_config.rb +60 -0
  161. data/lib/rubocop/result_cache.rb +123 -0
  162. data/lib/rubocop/runner.rb +85 -22
  163. data/lib/rubocop/target_finder.rb +4 -4
  164. data/lib/rubocop/token.rb +2 -1
  165. data/lib/rubocop/version.rb +1 -1
  166. data/lib/rubocop/warning.rb +11 -0
  167. data/lib/rubocop.rb +32 -3
  168. data/relnotes/v0.32.0.md +139 -0
  169. data/relnotes/v0.32.1.md +122 -0
  170. data/relnotes/v0.33.0.md +157 -0
  171. data/relnotes/v0.34.0.md +182 -0
  172. data/relnotes/v0.34.1.md +129 -0
  173. data/relnotes/v0.34.2.md +139 -0
  174. data/relnotes/v0.35.0.md +210 -0
  175. data/rubocop.gemspec +4 -4
  176. metadata +50 -12
  177. data/lib/rubocop/cop/performance/parallel_assignment.rb +0 -79
@@ -29,16 +29,45 @@ module RuboCop
29
29
 
30
30
  def autocorrect(node)
31
31
  lambda do |corrector|
32
+ unless arguments?(node.children)
33
+ corrector.replace(node.loc.expression, 'nil')
34
+ next
35
+ end
36
+
37
+ return_value, = *node
32
38
  if node.children.size > 1
33
- kids = node.children.map { |child| child.loc.expression }
34
- corrector.insert_before(kids.first, '[')
35
- corrector.insert_after(kids.last, ']')
39
+ add_brackets(corrector, node)
40
+ elsif return_value.hash_type?
41
+ add_braces(corrector, return_value) unless braces?(return_value)
36
42
  end
37
43
  return_kw = range_with_surrounding_space(node.loc.keyword, :right)
38
44
  corrector.remove(return_kw)
39
45
  end
40
46
  end
41
47
 
48
+ def braces?(arg)
49
+ arg.loc.begin
50
+ end
51
+
52
+ def add_brackets(corrector, node)
53
+ kids = node.children.map { |child| child.loc.expression }
54
+ corrector.insert_before(kids.first, '[')
55
+ corrector.insert_after(kids.last, ']')
56
+ end
57
+
58
+ def add_braces(corrector, node)
59
+ kids = node.children.map { |child| child.loc.expression }
60
+ corrector.insert_before(kids.first, '{')
61
+ corrector.insert_after(kids.last, '}')
62
+ end
63
+
64
+ def arguments?(args)
65
+ return false if args.empty?
66
+ return true if args.size > 1
67
+
68
+ !args.first.begin_type? || !args.first.children.empty?
69
+ end
70
+
42
71
  def on_method_def(_node, _method_name, _args, body)
43
72
  return unless body
44
73
 
@@ -47,7 +47,7 @@ module RuboCop
47
47
  def check_slash_literal(node)
48
48
  return if style == :slashes && !contains_disallowed_slash?(node)
49
49
  return if style == :mixed &&
50
- single_line?(node) &&
50
+ node.single_line? &&
51
51
  !contains_disallowed_slash?(node)
52
52
 
53
53
  add_offense(node, :expression, MSG_USE_PERCENT_R)
@@ -56,7 +56,7 @@ module RuboCop
56
56
  def check_percent_r_literal(node)
57
57
  return if style == :slashes && contains_disallowed_slash?(node)
58
58
  return if style == :percent_r
59
- return if style == :mixed && multi_line?(node)
59
+ return if style == :mixed && node.multiline?
60
60
  return if style == :mixed && contains_disallowed_slash?(node)
61
61
 
62
62
  add_offense(node, :expression, MSG_USE_SLASHES)
@@ -83,14 +83,6 @@ module RuboCop
83
83
  node.loc.begin.source == '/'
84
84
  end
85
85
 
86
- def single_line?(node)
87
- !multi_line?(node)
88
- end
89
-
90
- def multi_line?(node)
91
- block_length(node) > 1
92
- end
93
-
94
86
  def preferred_delimiters
95
87
  config.for_cop('Style/PercentLiteralDelimiters') \
96
88
  ['PreferredDelimiters']['%r'].split(//)
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks whether the rescue and ensure keywords are aligned
7
+ # properly.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # begin
13
+ # something
14
+ # rescue
15
+ # puts 'error'
16
+ # end
17
+ #
18
+ # # good
19
+ # begin
20
+ # something
21
+ # rescue
22
+ # puts 'error'
23
+ # end
24
+ class RescueEnsureAlignment < Cop
25
+ MSG = '`%s` at %d, %d is not aligned with `end` at %d, %d.'
26
+
27
+ def on_resbody(node)
28
+ check(node) unless modifier?(node)
29
+ end
30
+
31
+ def on_ensure(node)
32
+ check(node)
33
+ end
34
+
35
+ def investigate(processed_source)
36
+ @modifier_locations =
37
+ processed_source.tokens.each_with_object([]) do |token, locations|
38
+ next unless token.type == :kRESCUE_MOD
39
+ locations << token.pos
40
+ end
41
+ end
42
+
43
+ def autocorrect(node)
44
+ source_buffer = node.loc.keyword.source_buffer
45
+ begin_pos = node.loc.keyword.begin_pos
46
+ current_column = node.loc.keyword.column
47
+ whitespace = Parser::Source::Range.new(source_buffer,
48
+ begin_pos - current_column,
49
+ begin_pos)
50
+ return false unless whitespace.source.strip.empty?
51
+
52
+ new_column = ancestor_node(node).loc.end.column
53
+ ->(corrector) { corrector.replace(whitespace, ' ' * new_column) }
54
+ end
55
+
56
+ private
57
+
58
+ def check(node)
59
+ end_loc = ancestor_node(node).loc.end
60
+ return if end_loc.column == node.loc.keyword.column
61
+ return if end_loc.line == node.loc.keyword.line
62
+
63
+ kw_loc = node.loc.keyword
64
+
65
+ add_offense(node, kw_loc,
66
+ format(MSG, kw_loc.source, kw_loc.line, kw_loc.column,
67
+ end_loc.line, end_loc.column))
68
+ end
69
+
70
+ def modifier?(node)
71
+ return false unless @modifier_locations.respond_to?(:include?)
72
+ @modifier_locations.include?(node.loc.keyword)
73
+ end
74
+
75
+ def ancestor_node(node)
76
+ node.each_ancestor(:kwbegin, :def, :defs).first
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -5,37 +5,45 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for uses of rescue in its modifier form.
7
7
  class RescueModifier < Cop
8
- include OnMethodDef
8
+ include AutocorrectAlignment
9
9
 
10
10
  MSG = 'Avoid using `rescue` in its modifier form.'
11
11
 
12
- def on_rescue(node)
13
- return if ignored_node?(node)
14
-
15
- add_offense(node, :expression)
12
+ def investigate(processed_source)
13
+ @modifier_locations = processed_source.tokens
14
+ .select { |t| t.type == :kRESCUE_MOD }
15
+ .map(&:pos)
16
16
  end
17
17
 
18
- def on_kwbegin(node)
19
- body, *_ = *node
20
- check(body)
18
+ def on_resbody(node)
19
+ return unless modifier?(node)
20
+ add_offense(node.parent, :expression)
21
21
  end
22
22
 
23
- def on_method_def(_node, _method_name, _args, body)
24
- check(body)
23
+ def autocorrect(node)
24
+ operation, rescue_modifier, = *node
25
+ *_, rescue_args = *rescue_modifier
26
+
27
+ correction =
28
+ "begin\n" <<
29
+ indentation(node) << operation.loc.expression.source <<
30
+ "\n#{offset(node)}rescue\n" <<
31
+ indentation(node) << rescue_args.loc.expression.source <<
32
+ "\n#{offset(node)}end"
33
+ range = Parser::Source::Range.new(node.loc.expression.source_buffer,
34
+ node.loc.expression.begin_pos,
35
+ node.loc.expression.end_pos)
36
+
37
+ lambda do |corrector|
38
+ corrector.replace(range, correction)
39
+ end
25
40
  end
26
41
 
27
- def check(body)
28
- return unless body
29
-
30
- case body.type
31
- when :rescue
32
- ignore_node(body)
33
- when :ensure
34
- first_child = body.children.first
35
- if first_child && first_child.type == :rescue
36
- ignore_node(first_child)
37
- end
38
- end
42
+ private
43
+
44
+ def modifier?(node)
45
+ return false unless @modifier_locations.respond_to?(:include?)
46
+ @modifier_locations.include?(node.loc.keyword)
39
47
  end
40
48
  end
41
49
  end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for the use of the send method.
7
+ class Send < Cop
8
+ MSG = 'Prefer `Object#__send__` or `Object#public_send` to `send`.'
9
+
10
+ def on_send(node)
11
+ _receiver, method_name, *args = *node
12
+ return unless method_name == :send && args.length > 0
13
+ add_offense(node, :selector)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -37,7 +37,8 @@ module RuboCop
37
37
  lambda do |corrector|
38
38
  name =
39
39
  case style
40
- when :semantic then command?(:raise, node) ? 'fail' : 'raise'
40
+ when :semantic
41
+ command_or_kernel_call?(:raise, node) ? 'fail' : 'raise'
41
42
  when :only_raise then 'raise'
42
43
  when :only_fail then 'fail'
43
44
  end
@@ -63,30 +64,42 @@ module RuboCop
63
64
  return unless node
64
65
 
65
66
  if style == :semantic
66
- each_command(method_name, node) do |send_node|
67
+ each_command_or_kernel_call(method_name, node) do |send_node|
67
68
  next if ignored_node?(send_node)
68
69
 
69
70
  add_offense(send_node, :selector, message(method_name))
70
71
  ignore_node(send_node)
71
72
  end
72
- else
73
- _receiver, selector, _args = *node
74
-
75
- if [:raise, :fail].include?(selector) && selector != method_name
76
- add_offense(node, :selector, message(method_name))
77
- end
73
+ elsif command_or_kernel_call?(method_name == :raise ? :fail : :raise,
74
+ node)
75
+ add_offense(node, :selector, message(method_name))
78
76
  end
79
77
  end
80
78
 
79
+ def command_or_kernel_call?(name, node)
80
+ command?(name, node) || kernel_call?(name, node)
81
+ end
82
+
83
+ def kernel_call?(name, node)
84
+ return false unless node.type == :send
85
+ receiver, selector, _args = *node
86
+
87
+ return false unless name == selector
88
+ return false unless receiver.const_type?
89
+
90
+ _, constant = *receiver
91
+ constant == :Kernel
92
+ end
93
+
81
94
  def allow(method_name, node)
82
- each_command(method_name, node) do |send_node|
95
+ each_command_or_kernel_call(method_name, node) do |send_node|
83
96
  ignore_node(send_node)
84
97
  end
85
98
  end
86
99
 
87
- def each_command(method_name, node)
100
+ def each_command_or_kernel_call(method_name, node)
88
101
  on_node(:send, node, :rescue) do |send_node|
89
- yield send_node if command?(method_name, send_node)
102
+ yield send_node if command_or_kernel_call?(method_name, send_node)
90
103
  end
91
104
  end
92
105
  end
@@ -6,6 +6,7 @@ module RuboCop
6
6
  # This cop checks for single-line method definitions.
7
7
  # It can optionally accept single-line methods with no body.
8
8
  class SingleLineMethods < Cop
9
+ include AutocorrectAlignment
9
10
  include OnMethodDef
10
11
 
11
12
  MSG = 'Avoid single-line method definitions.'
@@ -33,12 +34,14 @@ module RuboCop
33
34
  c.loc.line == node.loc.expression.line
34
35
  end
35
36
  lambda do |corrector|
36
- if body.type == :begin
37
- body.children.each do |part|
38
- break_line_before(part.loc.expression, node, corrector, 1)
37
+ if body
38
+ if body.type == :begin
39
+ body.children.each do |part|
40
+ break_line_before(part.loc.expression, node, corrector, 1)
41
+ end
42
+ else
43
+ break_line_before(body.loc.expression, node, corrector, 1)
39
44
  end
40
- else
41
- break_line_before(body.loc.expression, node, corrector, 1)
42
45
  end
43
46
 
44
47
  break_line_before(node.loc.end, node, corrector, 0)
@@ -55,10 +58,6 @@ module RuboCop
55
58
  )
56
59
  end
57
60
 
58
- def configured_indentation_width
59
- config.for_cop('IndentationWidth')['Width']
60
- end
61
-
62
61
  def move_comment(eol_comment, node, corrector)
63
62
  text = eol_comment.loc.expression.source
64
63
  corrector.insert_before(node.loc.expression,
@@ -20,7 +20,7 @@ module RuboCop
20
20
  _receiver, method_name, *args = *node
21
21
  return if args.empty?
22
22
  return if operator?(method_name)
23
- return if method_name.to_s.end_with?('=')
23
+ return if node.asgn_method_call?
24
24
 
25
25
  arg1 = args.first.loc.expression
26
26
  return if arg1.line > node.loc.line
@@ -57,6 +57,8 @@ module RuboCop
57
57
 
58
58
  def check_operator(op)
59
59
  with_space = range_with_surrounding_space(op)
60
+ return if with_space.source.start_with?("\n")
61
+
60
62
  if op.is?('**')
61
63
  unless with_space.is?('**')
62
64
  add_offense(with_space, op,
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for whitespace within string interpolations.
7
+ #
8
+ # @example
9
+ # # Good if EnforcedStyle is no_space, bad if space.
10
+ # var = "This is the #{no_space} example"
11
+ #
12
+ # # Good if EnforceStyle is space, bad if no_space.
13
+ # var = "This is the #{ space } example"
14
+ class SpaceInsideStringInterpolation < Cop
15
+ include ConfigurableEnforcedStyle
16
+
17
+ NO_SPACE_MSG = 'Space inside string interpolation detected.'
18
+ SPACE_MSG = 'Missing space around string interpolation detected.'
19
+
20
+ def on_dstr(node)
21
+ node.children.select { |n| n.type == :begin }.each do |begin_node|
22
+ final_node = begin_node.children.last
23
+ next unless final_node
24
+
25
+ interp = final_node.loc.expression
26
+ interp_with_surrounding_space = range_with_surrounding_space(interp)
27
+ if style == :no_space
28
+ if interp_with_surrounding_space != interp
29
+ add_offense(final_node, :expression, NO_SPACE_MSG)
30
+ end
31
+ elsif style == :space
32
+ if interp_with_surrounding_space.source != " #{interp.source} "
33
+ add_offense(final_node, :expression, SPACE_MSG)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def autocorrect(node)
42
+ if style == :no_space
43
+ lambda do |corrector|
44
+ corrector.replace(
45
+ range_with_surrounding_space(node.loc.expression),
46
+ node.loc.expression.source
47
+ )
48
+ end
49
+ elsif style == :space
50
+ lambda do |corrector|
51
+ corrector.replace(
52
+ range_with_surrounding_space(node.loc.expression),
53
+ " #{node.loc.expression.source} "
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -5,8 +5,10 @@ module RuboCop
5
5
  module Style
6
6
  # This cop looks for uses of Perl-style global variables.
7
7
  class SpecialGlobalVars < Cop
8
- MSG_BOTH = 'Prefer `%s` from the English library, or `%s` over `%s`.'
9
- MSG_ENGLISH = 'Prefer `%s` from the English library over `%s`.'
8
+ MSG_BOTH = 'Prefer `%s` from the stdlib \'English\' module, ' \
9
+ 'or `%s` over `%s`.'
10
+ MSG_ENGLISH = 'Prefer `%s` from the stdlib \'English\' module ' \
11
+ 'over `%s`.'
10
12
  MSG_REGULAR = 'Prefer `%s` over `%s`.'
11
13
 
12
14
  PREFERRED_VARS = {
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+ module RuboCop
3
+ module Cop
4
+ module Style
5
+ # Check for parentheses around stabby lambda arguments.
6
+ # There are two different styles. Defaults to `require_parentheses`.
7
+ #
8
+ # @example
9
+ # # require_parentheses - bad
10
+ # ->a,b,c { a + b + c }
11
+ #
12
+ # # require_parentheses - good
13
+ # ->(a,b,c) { a + b + c}
14
+ #
15
+ # # require_no_parentheses - bad
16
+ # ->(a,b,c) { a + b + c }
17
+ #
18
+ # # require_parentheses - good
19
+ # ->a,b,c { a + b + c}
20
+ class StabbyLambdaParentheses < Cop
21
+ MSG_REQUIRE = 'Wrap stabby lambda arguments with parentheses.'
22
+ MSG_NO_REQUIRE = 'Do not wrap stabby lambda arguments with parentheses.'
23
+
24
+ include ConfigurableEnforcedStyle
25
+
26
+ def on_send(node)
27
+ return unless lambda_with_args?(node)
28
+
29
+ if style == :require_parentheses
30
+ if parentheses?(node)
31
+ correct_style_detected
32
+ else
33
+ missing_parentheses(node)
34
+ end
35
+ elsif parentheses?(node)
36
+ unwanted_parentheses(node)
37
+ else
38
+ correct_style_detected
39
+ end
40
+ end
41
+
42
+ def autocorrect(node)
43
+ if style == :require_parentheses
44
+ missing_parentheses_corrector(node)
45
+ elsif style == :require_no_parentheses
46
+ unwanted_parentheses_corrector(node)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def missing_parentheses(node)
53
+ add_offense(node_args(node), :expression, MSG_REQUIRE) do
54
+ opposite_style_detected
55
+ end
56
+ end
57
+
58
+ def unwanted_parentheses(node)
59
+ add_offense(node_args(node), :expression, MSG_NO_REQUIRE) do
60
+ opposite_style_detected
61
+ end
62
+ end
63
+
64
+ def missing_parentheses_corrector(node)
65
+ lambda do |corrector|
66
+ args_loc = node_args(node).loc.expression
67
+
68
+ corrector.insert_before(args_loc, '(')
69
+ corrector.insert_after(args_loc, ')')
70
+ end
71
+ end
72
+
73
+ def unwanted_parentheses_corrector(node)
74
+ lambda do |corrector|
75
+ args_loc = node_args(node).loc
76
+
77
+ corrector.replace(args_loc.begin, '')
78
+ corrector.remove(args_loc.end)
79
+ end
80
+ end
81
+
82
+ def lambda_with_args?(node)
83
+ lambda_node?(node) && args?(node)
84
+ end
85
+
86
+ def lambda_node?(node)
87
+ _nil, call = *node
88
+ call == :lambda
89
+ end
90
+
91
+ def node_args(node)
92
+ _call, args, _body = *node.parent
93
+ args
94
+ end
95
+
96
+ def args?(node)
97
+ args = node_args(node)
98
+ args.children.count > 0
99
+ end
100
+
101
+ def parentheses?(node)
102
+ args = node_args(node)
103
+ args.loc.begin
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces the use of consistent method names
7
+ # from the String class.
8
+ class StringMethods < Cop
9
+ include MethodPreference
10
+
11
+ MSG = 'Prefer `%s` over `%s`.'
12
+
13
+ def on_send(node)
14
+ _receiver, method_name, *_args = *node
15
+ return unless preferred_methods[method_name]
16
+ add_offense(node, :selector,
17
+ format(MSG,
18
+ preferred_method(method_name),
19
+ method_name)
20
+ )
21
+ end
22
+
23
+ def autocorrect(node)
24
+ lambda do |corrector|
25
+ corrector.replace(node.loc.selector,
26
+ preferred_method(node.loc.selector.source))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -25,16 +25,17 @@ module RuboCop
25
25
  private
26
26
 
27
27
  def struct_constructor?(node)
28
- if node && node.send_type?
29
- receiver, method_name = *node
30
-
31
- receiver &&
32
- receiver.const_type? &&
33
- receiver.children.last == :Struct &&
34
- method_name == :new
35
- else
36
- false
37
- end
28
+ return false unless node
29
+
30
+ send_node = node.block_type? ? node.children.first : node
31
+ return false unless send_node.send_type?
32
+
33
+ receiver, method_name = *send_node
34
+
35
+ receiver &&
36
+ receiver.const_type? &&
37
+ receiver.children.last == :Struct &&
38
+ method_name == :new
38
39
  end
39
40
  end
40
41
  end
@@ -27,7 +27,7 @@ module RuboCop
27
27
  lambda do |corrector|
28
28
  current_name = node.loc.expression.source
29
29
  corrector.replace(node.loc.expression,
30
- current_name.gsub(/["']/, ''))
30
+ current_name.delete(%q('")))
31
31
  end
32
32
  end
33
33
  end