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
@@ -1,43 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Common functionality for checking assignment nodes.
6
- module CheckAssignment
7
- def on_lvasgn(node)
8
- _lhs, rhs = *node
9
- check_assignment(node, rhs)
10
- end
11
-
12
- def on_ivasgn(node)
13
- _lhs, rhs = *node
14
- check_assignment(node, rhs)
15
- end
16
-
17
- def on_gvasgn(node)
18
- _lhs, rhs = *node
19
- check_assignment(node, rhs)
20
- end
21
-
22
- def on_or_asgn(node)
23
- _lhs, rhs = *node
24
- check_assignment(node, rhs)
25
- end
26
-
27
- def on_and_asgn(node)
28
- _lhs, rhs = *node
29
- check_assignment(node, rhs)
30
- end
31
-
32
- def on_casgn(node)
33
- _scope, _lhs, rhs = *node
34
- check_assignment(node, rhs)
35
- end
36
-
37
- def on_op_asgn(node)
38
- _lhs, _op, rhs = *node
39
- check_assignment(node, rhs)
40
- end
41
- end
42
- end
43
- end
@@ -1,22 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Common code for ordinary arrays with [] that can be written with %
7
- # syntax.
8
- module ArraySyntax
9
- def array_of?(element_type, node)
10
- return false unless node.loc.begin && node.loc.begin.is?('[')
11
-
12
- array_elems = node.children
13
-
14
- # no need to check empty arrays
15
- return false unless array_elems && array_elems.size > 1
16
-
17
- array_elems.all? { |e| e.type == element_type }
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,78 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # This module does auto-correction of nodes that should just be moved to
7
- # the left or to the right, amount being determined by the instance
8
- # variable @column_delta.
9
- module AutocorrectAlignment
10
- def check_alignment(items)
11
- items.each_cons(2) do |prev, current|
12
- if current.loc.line > prev.loc.line && start_of_line?(current.loc)
13
- @column_delta = items.first.loc.column - current.loc.column
14
- add_offence(current, :expression) if @column_delta != 0
15
- end
16
- end
17
- end
18
-
19
- def start_of_line?(loc)
20
- loc.expression.source_line[0...loc.column] =~ /^\s*$/
21
- end
22
-
23
- def autocorrect(node)
24
- # We can't use the instance variable inside the lambda. That would
25
- # just give each lambda the same reference and they would all get
26
- # the last value of @column_delta. A local variable fixes the
27
- # problem.
28
- column_delta = @column_delta
29
-
30
- @corrections << lambda do |corrector|
31
- expr = node.loc.expression
32
- each_line(expr) do |line_begin_pos, line|
33
- range = calculate_range(expr, line_begin_pos, column_delta)
34
- if column_delta > 0
35
- corrector.insert_before(range, ' ' * column_delta)
36
- else
37
- remove(range, corrector)
38
- end
39
- end
40
- end
41
- end
42
-
43
- def calculate_range(expr, line_begin_pos, column_delta)
44
- starts_with_space = expr.source_buffer.source[line_begin_pos] =~ / /
45
- pos_to_remove = if column_delta > 0 || starts_with_space
46
- line_begin_pos
47
- else
48
- line_begin_pos - column_delta.abs
49
- end
50
- Parser::Source::Range.new(expr.source_buffer, pos_to_remove,
51
- pos_to_remove + column_delta.abs)
52
- end
53
-
54
- def remove(range, corrector)
55
- original_stderr = $stderr
56
- $stderr = StringIO.new # Avoid error messages on console
57
- corrector.remove(range)
58
- rescue RuntimeError
59
- range = Parser::Source::Range.new(range.source_buffer,
60
- range.begin_pos + 1,
61
- range.end_pos + 1)
62
- retry if range.source =~ /^ +$/
63
- ensure
64
- $stderr = original_stderr
65
- end
66
-
67
- def each_line(expr)
68
- offset = 0
69
- expr.source.each_line do |line|
70
- line_begin_pos = expr.begin_pos + offset
71
- yield line_begin_pos, line
72
- offset += line.length
73
- end
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,35 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Common functionality for checking length of code segments.
7
- module CodeLength
8
- include ConfigurableMax
9
-
10
- def max_length
11
- cop_config['Max']
12
- end
13
-
14
- def count_comments?
15
- cop_config['CountComments']
16
- end
17
-
18
- def check(node, *_)
19
- length = code_length(node)
20
- if length > max_length
21
- add_offence(node, :keyword, sprintf(message, length,
22
- max_length)) do
23
- self.max = length
24
- end
25
- end
26
- end
27
-
28
- # Returns true for lines that shall not be included in the count.
29
- def irrelevant_line(source_line)
30
- source_line.blank? || !count_comments? && comment_line?(source_line)
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,51 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Handles `EnforcedStyle` configuration parameters.
7
- module ConfigurableEnforcedStyle
8
- def opposite_style_detected
9
- self.config_to_allow_offences ||=
10
- { 'EnforcedStyle' => alternative_style.to_s }
11
- both_styles_detected if config_to_allow_offences['Enabled']
12
- end
13
-
14
- def correct_style_detected
15
- # Enabled:true indicates, later when the opposite style is detected,
16
- # that the correct style is used somewhere.
17
- self.config_to_allow_offences ||= { 'Enabled' => true }
18
- both_styles_detected if config_to_allow_offences['EnforcedStyle']
19
- end
20
-
21
- def both_styles_detected
22
- # Both correct and opposite styles exist.
23
- self.config_to_allow_offences = { 'Enabled' => false }
24
- end
25
-
26
- def unrecognized_style_detected
27
- # All we can do is to disable.
28
- self.config_to_allow_offences = { 'Enabled' => false }
29
- end
30
-
31
- def style
32
- s = cop_config['EnforcedStyle']
33
- if cop_config['SupportedStyles'].include?(s)
34
- s.to_sym
35
- else
36
- fail "Unknown style #{s} selected!"
37
- end
38
- end
39
-
40
- def alternative_style
41
- a = cop_config['SupportedStyles'].map(&:to_sym)
42
- if a.size != 2
43
- fail 'alternative_style can only be used when there are exactly ' +
44
- '2 SupportedStyles'
45
- end
46
- style == a.first ? a.last : a.first
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,17 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Handles `Max` configuration parameters, especially setting them to an
7
- # appropriate value with --auto-gen-config.
8
- module ConfigurableMax
9
- def max=(value)
10
- cfg = self.config_to_allow_offences ||= {}
11
- value = [cfg['Max'], value].max if cfg['Max']
12
- cfg['Max'] = value
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,41 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # This module provides functionality for checking if names match the
7
- # configured EnforcedStyle.
8
- module ConfigurableNaming
9
- include ConfigurableEnforcedStyle
10
-
11
- SNAKE_CASE = /^@?[\da-z_]+[!?=]?$/
12
- CAMEL_CASE = /^@?[a-z][\da-zA-Z]+[!?=]?$/
13
-
14
- def check(node, range)
15
- return unless range
16
-
17
- name = range.source.to_sym
18
- unless matches_config?(name) || Cop::OPERATOR_METHODS.include?(name)
19
- add_offence(node, range, message(style))
20
- end
21
- end
22
-
23
- def matches_config?(name)
24
- name =~ (style == :snake_case ? SNAKE_CASE : CAMEL_CASE)
25
- end
26
-
27
- # Returns a range containing the method name after the given regexp and
28
- # a dot.
29
- def after_dot(node, method_name_length, regexp)
30
- expr = node.loc.expression
31
- match = /\A#{regexp}\s*\.\s*/.match(expr.source)
32
- return unless match
33
- offset = match[0].length
34
- begin_pos = expr.begin_pos + offset
35
- Parser::Source::Range.new(expr.source_buffer, begin_pos,
36
- begin_pos + method_name_length)
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,118 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Common functionality for modifier cops.
7
- module FavorModifier
8
- include IfNode
9
-
10
- # TODO: Extremely ugly solution that needs lots of polish.
11
- def check(sexp, comments)
12
- case sexp.loc.keyword.source
13
- when 'if' then cond, body, _else = *sexp
14
- when 'unless' then cond, _else, body = *sexp
15
- else cond, body = *sexp
16
- end
17
-
18
- return false if length(sexp) > 3
19
-
20
- body_length = body_length(body)
21
-
22
- return false if body_length == 0
23
-
24
- on_node(:lvasgn, cond) do
25
- return false
26
- end
27
-
28
- indentation = sexp.loc.keyword.column
29
- kw_length = sexp.loc.keyword.size
30
- cond_length = conditional_length(cond)
31
- space = 1
32
- total = indentation + body_length + space + kw_length + space +
33
- cond_length
34
- total <= max_line_length && !body_has_comment?(body, comments)
35
- end
36
-
37
- def max_line_length
38
- config.for_cop('LineLength')['Max']
39
- end
40
-
41
- def length(sexp)
42
- sexp.loc.expression.source.lines.to_a.size
43
- end
44
-
45
- def conditional_length(conditional_node)
46
- node = if conditional_node.type == :match_current_line
47
- conditional_node.children.first
48
- else
49
- conditional_node
50
- end
51
-
52
- node.loc.expression.size
53
- end
54
-
55
- def body_length(body)
56
- if body && body.loc.expression
57
- body.loc.expression.size
58
- else
59
- 0
60
- end
61
- end
62
-
63
- def body_has_comment?(body, comments)
64
- comment_lines = comments.map(&:location).map(&:line)
65
- body_line = body.loc.expression.line
66
- comment_lines.include?(body_line)
67
- end
68
- end
69
-
70
- # Checks for if and unless statements that would fit on one line
71
- # if written as a modifier if/unless.
72
- class IfUnlessModifier < Cop
73
- include FavorModifier
74
-
75
- def error_message
76
- 'Favor modifier if/unless usage when you have a single-line body. ' +
77
- 'Another good alternative is the usage of control flow &&/||.'
78
- end
79
-
80
- def investigate(processed_source)
81
- return unless processed_source.ast
82
- on_node(:if, processed_source.ast) do |node|
83
- # discard ternary ops, if/else and modifier if/unless nodes
84
- next if ternary_op?(node)
85
- next if modifier_if?(node)
86
- next if elsif?(node)
87
- next if if_else?(node)
88
-
89
- if check(node, processed_source.comments)
90
- add_offence(node, :keyword, error_message)
91
- end
92
- end
93
- end
94
- end
95
-
96
- # Checks for while and until statements that would fit on one line
97
- # if written as a modifier while/until.
98
- class WhileUntilModifier < Cop
99
- include FavorModifier
100
-
101
- MSG =
102
- 'Favor modifier while/until usage when you have a single-line body.'
103
-
104
- def investigate(processed_source)
105
- return unless processed_source.ast
106
- on_node([:while, :until], processed_source.ast) do |node|
107
- # discard modifier while/until
108
- next unless node.loc.end
109
-
110
- if check(node, processed_source.comments)
111
- add_offence(node, :keyword)
112
- end
113
- end
114
- end
115
- end
116
- end
117
- end
118
- end
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Common functionality for cops checking if and unless statements.
7
- module IfThenElse
8
- def on_if(node)
9
- check(node)
10
- end
11
-
12
- def on_unless(node)
13
- check(node)
14
- end
15
-
16
- def check(node)
17
- # We won't check modifier or ternary conditionals.
18
- if node.loc.expression.source =~ /\A(if|unless)\b/
19
- if offending_line(node)
20
- add_offence(node, :expression, error_message)
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,73 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- module Style
6
- # Common functionality for cops checking for missing space after
7
- # punctuation.
8
- module SpaceAfterCommaEtc
9
- MSG = 'Space missing after %s.'
10
-
11
- def investigate(processed_source)
12
- processed_source.tokens.each_cons(2) do |t1, t2|
13
- if kind(t1) && t1.pos.line == t2.pos.line &&
14
- t2.pos.column == t1.pos.column + offset(t1)
15
- add_offence(t1, t1.pos, sprintf(MSG, kind(t1)))
16
- end
17
- end
18
- end
19
-
20
- # The normal offset, i.e., the distance from the punctuation
21
- # token where a space should be, is 1.
22
- def offset(token)
23
- 1
24
- end
25
-
26
- def autocorrect(token)
27
- @corrections << lambda do |corrector|
28
- corrector.insert_after(token.pos, ' ')
29
- end
30
- end
31
- end
32
-
33
- # Checks for comma (,) not follwed by some kind of space.
34
- class SpaceAfterComma < Cop
35
- include SpaceAfterCommaEtc
36
-
37
- def kind(token)
38
- 'comma' if token.type == :tCOMMA
39
- end
40
- end
41
-
42
- # Checks for semicolon (;) not follwed by some kind of space.
43
- class SpaceAfterSemicolon < Cop
44
- include SpaceAfterCommaEtc
45
-
46
- def kind(token)
47
- 'semicolon' if token.type == :tSEMI
48
- end
49
- end
50
-
51
- # Checks for colon (:) not follwed by some kind of space.
52
- class SpaceAfterColon < Cop
53
- include SpaceAfterCommaEtc
54
-
55
- # The colon following a label will not appear in the token
56
- # array. Instad we get a tLABEL token, whose length we use to
57
- # calculate where we expect a space.
58
- def offset(token)
59
- case token.type
60
- when :tLABEL then token.text.length + 1
61
- when :tCOLON then 1
62
- end
63
- end
64
-
65
- def kind(token)
66
- case token.type
67
- when :tLABEL, :tCOLON then 'colon'
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end