rubocop 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -1
  4. data/CHANGELOG.md +44 -0
  5. data/CONTRIBUTING.md +40 -8
  6. data/Gemfile +6 -0
  7. data/README.md +65 -20
  8. data/Rakefile +0 -1
  9. data/config/default.yml +15 -3
  10. data/config/enabled.yml +143 -109
  11. data/lib/rubocop.rb +45 -26
  12. data/lib/rubocop/cli.rb +26 -27
  13. data/lib/rubocop/config.rb +0 -1
  14. data/lib/rubocop/config_loader.rb +16 -23
  15. data/lib/rubocop/cop/commissioner.rb +2 -7
  16. data/lib/rubocop/cop/cop.rb +24 -51
  17. data/lib/rubocop/cop/ignored_node.rb +31 -0
  18. data/lib/rubocop/cop/lint/ambiguous_operator.rb +50 -0
  19. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +36 -0
  20. data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -11
  21. data/lib/rubocop/cop/lint/block_alignment.rb +6 -20
  22. data/lib/rubocop/cop/lint/condition_position.rb +52 -0
  23. data/lib/rubocop/cop/lint/else_layout.rb +57 -0
  24. data/lib/rubocop/cop/lint/end_alignment.rb +33 -8
  25. data/lib/rubocop/cop/lint/invalid_character_literal.rb +37 -0
  26. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -4
  27. data/lib/rubocop/cop/lint/syntax.rb +6 -12
  28. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +25 -0
  29. data/lib/rubocop/cop/mixin/array_syntax.rb +20 -0
  30. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +76 -0
  31. data/lib/rubocop/cop/mixin/check_assignment.rb +26 -0
  32. data/lib/rubocop/cop/{check_methods.rb → mixin/check_methods.rb} +0 -0
  33. data/lib/rubocop/cop/mixin/code_length.rb +33 -0
  34. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +53 -0
  35. data/lib/rubocop/cop/mixin/configurable_max.rb +19 -0
  36. data/lib/rubocop/cop/mixin/configurable_naming.rb +45 -0
  37. data/lib/rubocop/cop/{style → mixin}/if_node.rb +0 -0
  38. data/lib/rubocop/cop/mixin/if_then_else.rb +23 -0
  39. data/lib/rubocop/cop/mixin/negative_conditional.rb +24 -0
  40. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +34 -0
  41. data/lib/rubocop/cop/mixin/safe_assignment.rb +19 -0
  42. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +32 -0
  43. data/lib/rubocop/cop/mixin/space_inside.rb +31 -0
  44. data/lib/rubocop/cop/mixin/statement_modifier.rb +59 -0
  45. data/lib/rubocop/cop/mixin/string_help.rb +32 -0
  46. data/lib/rubocop/cop/mixin/surrounding_space.rb +42 -0
  47. data/lib/rubocop/cop/rails/default_scope.rb +3 -1
  48. data/lib/rubocop/cop/style/accessor_method_name.rb +4 -12
  49. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +16 -1
  50. data/lib/rubocop/cop/style/case_indentation.rb +33 -16
  51. data/lib/rubocop/cop/style/character_literal.rb +10 -0
  52. data/lib/rubocop/cop/style/dot_position.rb +23 -6
  53. data/lib/rubocop/cop/style/empty_lines_around_body.rb +5 -5
  54. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -32
  55. data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +20 -0
  56. data/lib/rubocop/cop/style/hash_syntax.rb +5 -1
  57. data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
  58. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
  59. data/lib/rubocop/cop/style/indentation_consistency.rb +51 -0
  60. data/lib/rubocop/cop/style/indentation_width.rb +0 -26
  61. data/lib/rubocop/cop/style/lambda_call.rb +12 -5
  62. data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -11
  63. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -9
  64. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +22 -0
  65. data/lib/rubocop/cop/style/{ternary_operator.rb → nested_ternary_operator.rb} +0 -15
  66. data/lib/rubocop/cop/style/numeric_literals.rb +30 -2
  67. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -1
  68. data/lib/rubocop/cop/style/parameter_lists.rb +7 -3
  69. data/lib/rubocop/cop/style/parentheses_around_condition.rb +9 -11
  70. data/lib/rubocop/cop/style/predicate_name.rb +4 -12
  71. data/lib/rubocop/cop/style/raise_args.rb +19 -11
  72. data/lib/rubocop/cop/style/regexp_literal.rb +19 -6
  73. data/lib/rubocop/cop/style/space_after_colon.rb +36 -0
  74. data/lib/rubocop/cop/style/space_after_comma.rb +16 -0
  75. data/lib/rubocop/cop/style/space_after_semicolon.rb +16 -0
  76. data/lib/rubocop/cop/style/space_around_block_braces.rb +38 -38
  77. data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
  78. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +6 -2
  79. data/lib/rubocop/cop/style/string_literals.rb +5 -5
  80. data/lib/rubocop/cop/style/trailing_comma.rb +94 -0
  81. data/lib/rubocop/cop/style/unless_else.rb +2 -2
  82. data/lib/rubocop/cop/style/while_until_modifier.rb +32 -0
  83. data/lib/rubocop/cop/style/word_array.rb +9 -1
  84. data/lib/rubocop/cop/util.rb +14 -0
  85. data/lib/rubocop/cop/variable_inspector.rb +11 -6
  86. data/lib/rubocop/cop/variable_inspector/scope.rb +4 -3
  87. data/lib/rubocop/file_inspector.rb +22 -6
  88. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  89. data/lib/rubocop/formatter/colorizable.rb +37 -0
  90. data/lib/rubocop/formatter/disabled_config_formatter.rb +27 -6
  91. data/lib/rubocop/formatter/progress_formatter.rb +1 -1
  92. data/lib/rubocop/formatter/simple_text_formatter.rb +9 -5
  93. data/lib/rubocop/options.rb +19 -4
  94. data/lib/rubocop/target_finder.rb +4 -0
  95. data/lib/rubocop/version.rb +1 -1
  96. data/rubocop-todo.yml +10 -2
  97. data/rubocop.gemspec +3 -2
  98. data/spec/project_spec.rb +12 -7
  99. data/spec/rubocop/cli_spec.rb +262 -99
  100. data/spec/rubocop/config_loader_spec.rb +5 -5
  101. data/spec/rubocop/config_spec.rb +3 -3
  102. data/spec/rubocop/config_store_spec.rb +12 -11
  103. data/spec/rubocop/cop/commissioner_spec.rb +21 -5
  104. data/spec/rubocop/cop/cop_spec.rb +1 -1
  105. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
  106. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
  107. data/spec/rubocop/cop/lint/block_alignment_spec.rb +2 -2
  108. data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
  109. data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
  110. data/spec/rubocop/cop/lint/end_alignment_spec.rb +41 -1
  111. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
  112. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +3 -3
  113. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +12 -12
  114. data/spec/rubocop/cop/lint/syntax_spec.rb +2 -2
  115. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +72 -54
  116. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
  117. data/spec/rubocop/cop/offence_spec.rb +1 -1
  118. data/spec/rubocop/cop/rails/default_scope_spec.rb +6 -0
  119. data/spec/rubocop/cop/rails/output_spec.rb +2 -1
  120. data/spec/rubocop/cop/style/align_hash_spec.rb +9 -9
  121. data/spec/rubocop/cop/style/align_parameters_spec.rb +1 -1
  122. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +5 -0
  123. data/spec/rubocop/cop/style/case_indentation_spec.rb +53 -2
  124. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +3 -3
  125. data/spec/rubocop/cop/style/documentation_spec.rb +0 -1
  126. data/spec/rubocop/cop/style/dot_position_spec.rb +18 -3
  127. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +4 -4
  128. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +13 -0
  129. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
  130. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +1 -1
  131. data/spec/rubocop/cop/style/hash_syntax_spec.rb +5 -0
  132. data/spec/rubocop/cop/style/{favor_modifier_spec.rb → if_unless_modifier_spec.rb} +4 -111
  133. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
  134. data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -91
  135. data/spec/rubocop/cop/style/lambda_call_spec.rb +18 -0
  136. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +2 -2
  137. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +35 -1
  138. data/spec/rubocop/cop/style/method_length_spec.rb +1 -0
  139. data/spec/rubocop/cop/style/method_name_spec.rb +27 -5
  140. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +4 -4
  141. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
  142. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
  143. data/spec/rubocop/cop/style/{ternary_operator_spec.rb → nested_ternary_operator_spec.rb} +0 -15
  144. data/spec/rubocop/cop/style/numeric_literals_spec.rb +18 -1
  145. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -1
  146. data/spec/rubocop/cop/style/parameter_lists_spec.rb +1 -0
  147. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +13 -4
  148. data/spec/rubocop/cop/style/raise_args_spec.rb +22 -0
  149. data/spec/rubocop/cop/style/redundant_self_spec.rb +4 -4
  150. data/spec/rubocop/cop/style/regexp_literal_spec.rb +4 -0
  151. data/spec/rubocop/cop/style/space_after_colon_spec.rb +12 -4
  152. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +2 -2
  153. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +30 -1
  154. data/spec/rubocop/cop/style/{space_around_equals_in_default_parameter_spec.rb → space_around_equals_in_parameter_default_spec.rb} +0 -0
  155. data/spec/rubocop/cop/style/space_around_operators_spec.rb +2 -1
  156. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +20 -3
  157. data/spec/rubocop/cop/style/string_literals_spec.rb +33 -0
  158. data/spec/rubocop/cop/style/trailing_comma_spec.rb +200 -0
  159. data/spec/rubocop/cop/style/variable_name_spec.rb +27 -3
  160. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
  161. data/spec/rubocop/cop/style/word_array_spec.rb +1 -0
  162. data/spec/rubocop/cop/team_spec.rb +1 -1
  163. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +3 -4
  164. data/spec/rubocop/file_inspector_spec.rb +1 -1
  165. data/spec/rubocop/formatter/base_formatter_spec.rb +12 -11
  166. data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
  167. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +2 -0
  168. data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
  169. data/spec/rubocop/formatter/json_formatter_spec.rb +4 -3
  170. data/spec/rubocop/formatter/progress_formatter_spec.rb +2 -2
  171. data/spec/rubocop/options_spec.rb +3 -1
  172. data/spec/rubocop/target_finder_spec.rb +13 -11
  173. data/spec/spec_helper.rb +5 -1
  174. data/spec/support/shared_examples.rb +2 -2
  175. data/spec/support/statement_modifier_helper.rb +41 -0
  176. metadata +88 -30
  177. data/lib/rubocop/cop/check_assignment.rb +0 -43
  178. data/lib/rubocop/cop/style/array_syntax.rb +0 -22
  179. data/lib/rubocop/cop/style/autocorrect_alignment.rb +0 -78
  180. data/lib/rubocop/cop/style/code_length.rb +0 -35
  181. data/lib/rubocop/cop/style/configurable_enforced_style.rb +0 -51
  182. data/lib/rubocop/cop/style/configurable_max.rb +0 -17
  183. data/lib/rubocop/cop/style/configurable_naming.rb +0 -41
  184. data/lib/rubocop/cop/style/favor_modifier.rb +0 -118
  185. data/lib/rubocop/cop/style/if_then_else.rb +0 -27
  186. data/lib/rubocop/cop/style/space_after_comma_etc.rb +0 -73
  187. data/lib/rubocop/cop/style/space_inside.rb +0 -33
  188. data/lib/rubocop/cop/style/string_help.rb +0 -30
  189. data/lib/rubocop/cop/style/surrounding_space.rb +0 -44
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # Common functionality for checking for spaces inside various
6
+ # kinds of parentheses.
7
+ module SpaceInside
8
+ include SurroundingSpace
9
+ MSG = 'Space inside %s detected.'
10
+
11
+ def investigate(processed_source)
12
+ @processed_source = processed_source
13
+ left, right, kind = specifics
14
+ processed_source.tokens.each_cons(2) do |t1, t2|
15
+ if t1.type == left || t2.type == right
16
+ if t2.pos.line == t1.pos.line && space_between?(t1, t2)
17
+ range = Parser::Source::Range.new(processed_source.buffer,
18
+ t1.pos.end_pos,
19
+ t2.pos.begin_pos)
20
+ add_offence(range, range, format(MSG, kind))
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def autocorrect(range)
27
+ @corrections << ->(corrector) { corrector.remove(range) }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # Common functionality for modifier cops.
6
+ module StatementModifier
7
+ include IfNode
8
+
9
+ # TODO: Extremely ugly solution that needs lots of polish.
10
+ def check(sexp, comments)
11
+ case sexp.loc.keyword.source
12
+ when 'if' then cond, body, _else = *sexp
13
+ when 'unless' then cond, _else, body = *sexp
14
+ else cond, body = *sexp
15
+ end
16
+
17
+ return false if length(sexp) > 3
18
+
19
+ body_length = body_length(body)
20
+
21
+ return false if body_length == 0
22
+
23
+ on_node(:lvasgn, cond) do
24
+ return false
25
+ end
26
+
27
+ indentation = sexp.loc.keyword.column
28
+ kw_length = sexp.loc.keyword.size
29
+ cond_length = cond.loc.expression.size
30
+ space = 1
31
+ total = indentation + body_length + space + kw_length + space +
32
+ cond_length
33
+ total <= max_line_length && !body_has_comment?(body, comments)
34
+ end
35
+
36
+ def max_line_length
37
+ config.for_cop('LineLength')['Max']
38
+ end
39
+
40
+ def length(sexp)
41
+ sexp.loc.expression.source.lines.to_a.size
42
+ end
43
+
44
+ def body_length(body)
45
+ if body && body.loc.expression
46
+ body.loc.expression.size
47
+ else
48
+ 0
49
+ end
50
+ end
51
+
52
+ def body_has_comment?(body, comments)
53
+ comment_lines = comments.map(&:location).map(&:line)
54
+ body_line = body.loc.expression.line
55
+ comment_lines.include?(body_line)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # Classes that include this module just implement functions to determine
6
+ # what is an offence and how to do auto-correction. They get help with
7
+ # adding offences for the faulty string nodes, and with filtering out
8
+ # nodes.
9
+ module StringHelp
10
+ def on_str(node)
11
+ # Constants like __FILE__ are handled as strings,
12
+ # but don't respond to begin.
13
+ return unless node.loc.respond_to?(:begin) && node.loc.begin
14
+ return if part_of_ignored_node?(node)
15
+
16
+ if offence?(node)
17
+ add_offence(node, :expression) { opposite_style_detected }
18
+ else
19
+ correct_style_detected
20
+ end
21
+ end
22
+
23
+ def on_dstr(node)
24
+ ignore_node(node)
25
+ end
26
+
27
+ def on_regexp(node)
28
+ ignore_node(node)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # Common functionality for checking surrounding space.
6
+ module SurroundingSpace
7
+ def space_between?(t1, t2)
8
+ char_preceding_2nd_token =
9
+ @processed_source[t2.pos.line - 1][t2.pos.column - 1]
10
+ if char_preceding_2nd_token == '+' && t1.type != :tPLUS
11
+ # Special case. A unary plus is not present in the tokens.
12
+ char_preceding_2nd_token =
13
+ @processed_source[t2.pos.line - 1][t2.pos.column - 2]
14
+ end
15
+ t2.pos.line > t1.pos.line || char_preceding_2nd_token =~ /[ \t]/
16
+ end
17
+
18
+ def index_of_first_token(node)
19
+ b = node.loc.expression.begin
20
+ token_table[[b.line, b.column]]
21
+ end
22
+
23
+ def index_of_last_token(node)
24
+ e = node.loc.expression.end
25
+ (0...e.column).to_a.reverse.find do |c|
26
+ ix = token_table[[e.line, c]]
27
+ return ix if ix
28
+ end
29
+ end
30
+
31
+ def token_table
32
+ @token_table ||= begin
33
+ table = {}
34
+ @processed_source.tokens.each_with_index do |t, ix|
35
+ table[[t.pos.line, t.pos.column]] = ix
36
+ end
37
+ table
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -25,7 +25,9 @@ module Rubocop
25
25
 
26
26
  first_arg = args[0]
27
27
 
28
- add_offence(first_arg, :expression) if lambda_or_proc?(first_arg)
28
+ if first_arg.type != :block || lambda_or_proc?(first_arg)
29
+ add_offence(first_arg, :expression)
30
+ end
29
31
  end
30
32
  end
31
33
  end
@@ -18,23 +18,15 @@ module Rubocop
18
18
  # # good
19
19
  # def attribute ...
20
20
  class AccessorMethodName < Cop
21
- def on_def(node)
22
- method_name, args, _body = *node
23
- check(node, method_name.to_s, args)
24
- end
25
-
26
- def on_defs(node)
27
- _scope, method_name, args, _body = *node
28
- check(node, method_name.to_s, args)
29
- end
21
+ include CheckMethods
30
22
 
31
23
  private
32
24
 
33
- def check(node, method_name, args)
34
- if bad_reader_name?(method_name, args)
25
+ def check(node, method_name, args, _body)
26
+ if bad_reader_name?(method_name.to_s, args)
35
27
  add_offence(node, :name,
36
28
  'Do not prefix reader method names with get_.')
37
- elsif bad_writer_name?(method_name, args)
29
+ elsif bad_writer_name?(method_name.to_s, args)
38
30
  add_offence(node, :name,
39
31
  'Do not prefix writer method names with set_.')
40
32
  end
@@ -13,7 +13,7 @@ module Rubocop
13
13
  # Discard attr writer methods.
14
14
  return if method_name.to_s.end_with?('=')
15
15
  # Discard operator methods.
16
- return if OPERATOR_METHODS.include?(method_name)
16
+ return if operator?(method_name)
17
17
 
18
18
  # We care only for the last argument.
19
19
  arg = args.last
@@ -48,6 +48,7 @@ module Rubocop
48
48
  if style == :no_braces
49
49
  corrector.remove(node.loc.begin)
50
50
  corrector.remove(node.loc.end)
51
+ remove_trailing_comma(node, corrector)
51
52
  elsif style == :braces
52
53
  corrector.insert_before(node.loc.expression, '{')
53
54
  corrector.insert_after(node.loc.expression, '}')
@@ -55,6 +56,20 @@ module Rubocop
55
56
  end
56
57
  end
57
58
 
59
+ def remove_trailing_comma(node, corrector)
60
+ sb = node.loc.end.source_buffer
61
+ pos_after_last_pair = node.children.last.loc.expression.end_pos
62
+ range_after_last_pair =
63
+ Parser::Source::Range.new(sb, pos_after_last_pair,
64
+ node.loc.end.begin_pos)
65
+ trailing_comma_offset = range_after_last_pair.source =~ /,/
66
+ if trailing_comma_offset
67
+ comma_begin = pos_after_last_pair + trailing_comma_offset
68
+ corrector.remove(Parser::Source::Range.new(sb, comma_begin,
69
+ comma_begin + 1))
70
+ end
71
+ end
72
+
58
73
  def non_empty_hash?(arg)
59
74
  arg && arg.type == :hash && arg.children.any?
60
75
  end
@@ -8,35 +8,52 @@ module Rubocop
8
8
  #
9
9
  # It will register a separate offence for each misaligned *when*.
10
10
  class CaseIndentation < Cop
11
+ include ConfigurableEnforcedStyle
12
+
11
13
  def on_case(case_node)
12
14
  _condition, *whens, _else = *case_node
13
15
 
14
- base, indent = cop_config.values_at('IndentWhenRelativeTo',
15
- 'IndentOneStep')
16
+ base = style
17
+ indent = cop_config['IndentOneStep']
16
18
  base_column = base_column(case_node, base)
17
19
 
18
20
  whens.each do |when_node|
19
- pos = when_node.loc.keyword
20
- expected_column = base_column +
21
- (indent ? IndentationWidth::CORRECT_INDENTATION : 0)
22
- if pos.column != expected_column
23
- msg = 'Indent when ' + if indent
24
- "one step more than #{base}."
25
- else
26
- "as deep as #{base}."
27
- end
28
- add_offence(when_node, pos, msg)
29
- end
21
+ check_when(when_node, case_node, base, indent, base_column)
30
22
  end
31
23
  end
32
24
 
33
25
  private
34
26
 
27
+ def check_when(when_node, case_node, base, indent, base_column)
28
+ pos = when_node.loc.keyword
29
+ expected_column = base_column +
30
+ (indent ? IndentationWidth::CORRECT_INDENTATION : 0)
31
+ if pos.column == expected_column
32
+ correct_style_detected
33
+ else
34
+ msg = 'Indent when ' + if indent
35
+ "one step more than #{base}."
36
+ else
37
+ "as deep as #{base}."
38
+ end
39
+ add_offence(when_node, pos, msg) do
40
+ if pos.column == base_column(case_node, alternative_style)
41
+ opposite_style_detected
42
+ else
43
+ unrecognized_style_detected
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ def parameter_name
50
+ 'IndentWhenRelativeTo'
51
+ end
52
+
35
53
  def base_column(case_node, base)
36
54
  case base
37
- when 'case' then case_node.location.keyword.column
38
- when 'end' then case_node.location.end.column
39
- else fail "Unknown IndentWhenRelativeTo: #{base}"
55
+ when :case then case_node.location.keyword.column
56
+ when :end then case_node.location.end.column
40
57
  end
41
58
  end
42
59
  end
@@ -26,6 +26,16 @@ module Rubocop
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ # Dummy implementation of method in ConfigurableEnforcedStyle that is
31
+ # called from StringHelp.
32
+ def opposite_style_detected
33
+ end
34
+
35
+ # Dummy implementation of method in ConfigurableEnforcedStyle that is
36
+ # called from StringHelp.
37
+ def correct_style_detected
38
+ end
29
39
  end
30
40
  end
31
41
  end
@@ -5,16 +5,34 @@ module Rubocop
5
5
  module Style
6
6
  # This cop checks the . position in multi-line method calls.
7
7
  class DotPosition < Cop
8
- MSG = 'Place the . on the next line, together with the method name.'
8
+ include ConfigurableEnforcedStyle
9
9
 
10
10
  def on_send(node)
11
11
  return unless node.loc.dot
12
12
 
13
- add_offence(node, :dot) unless proper_dot_position?(node)
13
+ if proper_dot_position?(node)
14
+ correct_style_detected
15
+ else
16
+ add_offence(node, :dot) { opposite_style_detected }
17
+ end
14
18
  end
15
19
 
16
20
  private
17
21
 
22
+ def message(node)
23
+ 'Place the . on the ' +
24
+ case style
25
+ when :leading
26
+ 'next line, together with the method name.'
27
+ when :trailing
28
+ 'previous line, together with the method call receiver.'
29
+ end
30
+ end
31
+
32
+ def parameter_name
33
+ 'Style'
34
+ end
35
+
18
36
  def proper_dot_position?(node)
19
37
  dot_line = node.loc.dot.line
20
38
 
@@ -25,10 +43,9 @@ module Rubocop
25
43
  selector_line = node.loc.begin.line
26
44
  end
27
45
 
28
- case cop_config['Style'].downcase
29
- when 'leading' then dot_line == selector_line
30
- when 'trailing' then dot_line != selector_line || same_line?(node)
31
- else fail 'Unknown dot position style selected.'
46
+ case style
47
+ when :leading then dot_line == selector_line
48
+ when :trailing then dot_line != selector_line || same_line?(node)
32
49
  end
33
50
  end
34
51
 
@@ -3,7 +3,7 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
- # This cops checks redundant blanks lines around the bodies of classes,
6
+ # This cops checks redundant empty lines around the bodies of classes,
7
7
  # modules & methods.
8
8
  #
9
9
  # @example
@@ -24,8 +24,8 @@ module Rubocop
24
24
  class EmptyLinesAroundBody < Cop
25
25
  include CheckMethods
26
26
 
27
- MSG_BEG = 'Extra blank line detected at body beginning.'
28
- MSG_END = 'Extra blank line detected at body end.'
27
+ MSG_BEG = 'Extra empty line detected at body beginning.'
28
+ MSG_END = 'Extra empty line detected at body end.'
29
29
 
30
30
  def on_class(node)
31
31
  check(node)
@@ -55,7 +55,7 @@ module Rubocop
55
55
  end
56
56
 
57
57
  def check_source(start_line, end_line)
58
- if processed_source.lines[start_line].blank?
58
+ if processed_source.lines[start_line].empty?
59
59
  range = source_range(processed_source.buffer,
60
60
  processed_source[0...start_line],
61
61
  0,
@@ -63,7 +63,7 @@ module Rubocop
63
63
  add_offence(range, range, MSG_BEG)
64
64
  end
65
65
 
66
- if processed_source.lines[end_line - 2].blank?
66
+ if processed_source.lines[end_line - 2].empty?
67
67
  range = source_range(processed_source.buffer,
68
68
  processed_source[0...(end_line - 2)],
69
69
  0,
@@ -3,28 +3,10 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
- # Some common code shared between the two cops.
7
- module FavorOtherKeywordOverNegation
8
- def check(node)
9
- condition, _body, _rest = *node
10
-
11
- # Look at last expression of contents if there's a parenthesis
12
- # around condition.
13
- condition = condition.children.last while condition.type == :begin
14
-
15
- if condition.type == :send
16
- _object, method = *condition
17
- if method == :! && !(node.loc.respond_to?(:else) && node.loc.else)
18
- add_offence(node, :expression, error_message)
19
- end
20
- end
21
- end
22
- end
23
-
24
6
  # Checks for uses of if with a negated condition. Only ifs
25
7
  # without else are considered.
26
8
  class FavorUnlessOverNegatedIf < Cop
27
- include FavorOtherKeywordOverNegation
9
+ include NegativeConditional
28
10
 
29
11
  def on_if(node)
30
12
  return unless node.loc.respond_to?(:keyword)
@@ -37,19 +19,6 @@ module Rubocop
37
19
  'Favor unless (or control flow or) over if for negative conditions.'
38
20
  end
39
21
  end
40
-
41
- # Checks for uses of while with a negated condition.
42
- class FavorUntilOverNegatedWhile < Cop
43
- include FavorOtherKeywordOverNegation
44
-
45
- def on_while(node)
46
- check(node)
47
- end
48
-
49
- def error_message
50
- 'Favor until over while for negative conditions.'
51
- end
52
- end
53
22
  end
54
23
  end
55
24
  end