rubocop 0.34.2 → 0.35.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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +103 -31
  4. data/config/default.yml +32 -2
  5. data/config/disabled.yml +24 -0
  6. data/config/enabled.yml +20 -2
  7. data/lib/rubocop.rb +13 -0
  8. data/lib/rubocop/ast_node.rb +48 -0
  9. data/lib/rubocop/cli.rb +9 -0
  10. data/lib/rubocop/config.rb +8 -6
  11. data/lib/rubocop/config_loader.rb +30 -8
  12. data/lib/rubocop/cop/commissioner.rb +1 -1
  13. data/lib/rubocop/cop/cop.rb +19 -6
  14. data/lib/rubocop/cop/lint/circular_argument_reference.rb +33 -2
  15. data/lib/rubocop/cop/lint/debugger.rb +9 -56
  16. data/lib/rubocop/cop/lint/end_alignment.rb +29 -9
  17. data/lib/rubocop/cop/lint/eval.rb +6 -2
  18. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +24 -6
  19. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
  20. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +10 -1
  21. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  22. data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
  23. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
  24. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
  25. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  26. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  27. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
  28. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
  29. data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
  30. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
  31. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
  32. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  33. data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
  34. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  35. data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
  36. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  37. data/lib/rubocop/cop/performance/detect.rb +5 -1
  38. data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
  39. data/lib/rubocop/cop/performance/size.rb +1 -1
  40. data/lib/rubocop/cop/performance/string_replacement.rb +14 -8
  41. data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
  42. data/lib/rubocop/cop/style/align_hash.rb +1 -12
  43. data/lib/rubocop/cop/style/align_parameters.rb +19 -7
  44. data/lib/rubocop/cop/style/and_or.rb +42 -13
  45. data/lib/rubocop/cop/style/block_comments.rb +4 -2
  46. data/lib/rubocop/cop/style/block_delimiters.rb +57 -18
  47. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  48. data/lib/rubocop/cop/style/command_literal.rb +2 -10
  49. data/lib/rubocop/cop/style/copyright.rb +5 -3
  50. data/lib/rubocop/cop/style/documentation.rb +9 -6
  51. data/lib/rubocop/cop/style/dot_position.rb +6 -0
  52. data/lib/rubocop/cop/style/double_negation.rb +4 -15
  53. data/lib/rubocop/cop/style/each_with_object.rb +17 -4
  54. data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -5
  55. data/lib/rubocop/cop/style/encoding.rb +10 -4
  56. data/lib/rubocop/cop/style/extra_spacing.rb +23 -13
  57. data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
  58. data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
  59. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
  60. data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
  61. data/lib/rubocop/cop/style/for.rb +2 -1
  62. data/lib/rubocop/cop/style/if_unless_modifier.rb +31 -0
  63. data/lib/rubocop/cop/style/indent_hash.rb +67 -37
  64. data/lib/rubocop/cop/style/indentation_width.rb +1 -1
  65. data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
  66. data/lib/rubocop/cop/style/method_call_parentheses.rb +8 -0
  67. data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
  68. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +8 -13
  69. data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
  70. data/lib/rubocop/cop/style/next.rb +18 -0
  71. data/lib/rubocop/cop/style/parallel_assignment.rb +57 -15
  72. data/lib/rubocop/cop/style/predicate_name.rb +7 -2
  73. data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
  74. data/lib/rubocop/cop/style/single_line_methods.rb +7 -5
  75. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
  76. data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
  77. data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
  78. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
  79. data/lib/rubocop/cop/style/trailing_comma.rb +9 -6
  80. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
  81. data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
  82. data/lib/rubocop/cop/style/variable_name.rb +5 -0
  83. data/lib/rubocop/cop/style/word_array.rb +2 -1
  84. data/lib/rubocop/cop/team.rb +17 -4
  85. data/lib/rubocop/cop/util.rb +5 -0
  86. data/lib/rubocop/cop/variable_force/locatable.rb +1 -1
  87. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +22 -10
  89. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  90. data/lib/rubocop/node_pattern.rb +390 -0
  91. data/lib/rubocop/options.rb +48 -36
  92. data/lib/rubocop/processed_source.rb +3 -1
  93. data/lib/rubocop/rake_task.rb +1 -1
  94. data/lib/rubocop/remote_config.rb +60 -0
  95. data/lib/rubocop/result_cache.rb +4 -2
  96. data/lib/rubocop/runner.rb +33 -10
  97. data/lib/rubocop/token.rb +2 -1
  98. data/lib/rubocop/version.rb +1 -1
  99. data/lib/rubocop/warning.rb +11 -0
  100. data/relnotes/v0.35.0.md +210 -0
  101. data/rubocop.gemspec +2 -2
  102. metadata +20 -6
@@ -7,64 +7,17 @@ module RuboCop
7
7
  class Debugger < Cop
8
8
  MSG = 'Remove debugger entry point `%s`.'
9
9
 
10
- # debugger call node
11
- #
12
- # (send nil :debugger)
13
- DEBUGGER_NODE = s(:send, nil, :debugger)
14
-
15
- # byebug call node
16
- #
17
- # (send nil :byebug)
18
- BYEBUG_NODE = s(:send, nil, :byebug)
19
-
20
- # binding.pry node
21
- #
22
- # (send
23
- # (send nil :binding) :pry)
24
- PRY_NODE = s(:send, s(:send, nil, :binding), :pry)
25
-
26
- # binding.remote_pry node
27
- #
28
- # (send
29
- # (send nil :binding) :remote_pry)
30
- REMOTE_PRY_NODE = s(:send, s(:send, nil, :binding), :remote_pry)
31
-
32
- # binding.pry_remote node
33
- #
34
- # (send
35
- # (send nil :binding) :pry_remote)
36
- PRY_REMOTE_NODE = s(:send, s(:send, nil, :binding), :pry_remote)
37
-
38
- # save_and_open_page
39
- #
40
- # (send nil :save_and_open_page)
41
- CAPYBARA_SAVE_PAGE = s(:send, nil, :save_and_open_page)
42
-
43
- # save_and_open_screenshot
44
- #
45
- # (send nil :save_and_open_screenshot)
46
- CAPYBARA_SAVE_OPEN_SCREENSHOT = s(:send, nil, :save_and_open_screenshot)
47
-
48
- # save_screenshot
49
- #
50
- # (send nil :save_screenshot)
51
- CAPYBARA_SAVE_SCREENSHOT = s(:send, nil, :save_screenshot)
52
-
53
- DEBUGGER_NODES = [
54
- DEBUGGER_NODE,
55
- BYEBUG_NODE,
56
- PRY_NODE,
57
- REMOTE_PRY_NODE,
58
- PRY_REMOTE_NODE,
59
- CAPYBARA_SAVE_PAGE,
60
- CAPYBARA_SAVE_OPEN_SCREENSHOT,
61
- CAPYBARA_SAVE_SCREENSHOT
62
- ]
10
+ def_node_matcher :debugger_call?,
11
+ '{(send nil {:debugger :byebug} ...)
12
+ (send (send nil :binding)
13
+ {:pry :remote_pry :pry_remote} ...)
14
+ (send (const nil :Pry) :rescue ...)
15
+ (send nil {:save_and_open_page
16
+ :save_and_open_screenshot
17
+ :save_screenshot} ...)}'
63
18
 
64
19
  def on_send(node)
65
- receiver, method_name, *_args = *node
66
- node_without_args = self.class.s(:send, receiver, method_name)
67
- return unless DEBUGGER_NODES.include? node_without_args
20
+ return unless debugger_call?(node)
68
21
  add_offense(node,
69
22
  :expression,
70
23
  format(MSG, node.loc.expression.source))
@@ -41,6 +41,10 @@ module RuboCop
41
41
  end
42
42
 
43
43
  def on_case(node)
44
+ if argument_case?(node)
45
+ return check_alignment(node.ancestors.first, node)
46
+ end
47
+
44
48
  check_offset_of_node(node)
45
49
  end
46
50
 
@@ -57,24 +61,40 @@ module RuboCop
57
61
  return unless [:if, :while, :until, :case].include?(rhs.type)
58
62
  return if ternary_op?(rhs)
59
63
 
60
- expr = node.loc.expression
61
- if variable_alignment?(expr, rhs, style)
64
+ check_alignment(node, rhs)
65
+ end
66
+
67
+ def check_alignment(outer_node, inner_node)
68
+ expr = outer_node.loc.expression
69
+ if variable_alignment?(expr, inner_node, style)
62
70
  range = Parser::Source::Range.new(expr.source_buffer,
63
71
  expr.begin_pos,
64
- rhs.loc.keyword.end_pos)
65
- offset = rhs.loc.keyword.column - node.loc.expression.column
72
+ inner_node.loc.keyword.end_pos)
73
+ offset =
74
+ inner_node.loc.keyword.column - outer_node.loc.expression.column
66
75
  else
67
- range = rhs.loc.keyword
76
+ range = inner_node.loc.keyword
68
77
  offset = 0
69
78
  end
70
79
 
71
- check_offset(rhs, range.source, offset)
72
- ignore_node(rhs) # Don't check again.
80
+ check_offset(inner_node, range.source, offset)
81
+ ignore_node(inner_node) # Don't check again.
73
82
  end
74
83
 
75
84
  def autocorrect(node)
76
- align(node,
77
- style == :variable ? node.each_ancestor(:lvasgn).first : node)
85
+ align(node, alignment_node(node))
86
+ end
87
+
88
+ def alignment_node(node)
89
+ return node unless style == :variable
90
+ return node.ancestors.first if argument_case?(node)
91
+
92
+ node.each_ancestor(:lvasgn).first
93
+ end
94
+
95
+ def argument_case?(node)
96
+ node.case_type? && !node.ancestors.empty? &&
97
+ node.ancestors.first.send_type?
78
98
  end
79
99
  end
80
100
  end
@@ -8,9 +8,13 @@ module RuboCop
8
8
  MSG = 'The use of `eval` is a serious security risk.'
9
9
 
10
10
  def on_send(node)
11
- receiver, method_name, = *node
11
+ receiver, method_name, *args = *node
12
12
 
13
- add_offense(node, :selector) if receiver.nil? && method_name == :eval
13
+ return unless receiver.nil? &&
14
+ method_name == :eval &&
15
+ !args.empty? &&
16
+ args.first.type != :str
17
+ add_offense(node, :selector)
14
18
  end
15
19
  end
16
20
  end
@@ -37,7 +37,10 @@ module RuboCop
37
37
  false
38
38
  else
39
39
  num_of_format_args, num_of_expected_fields = count_matches(node)
40
- num_of_expected_fields != num_of_format_args
40
+
41
+ num_of_format_args != :unknown &&
42
+ num_of_expected_fields != :unknown &&
43
+ num_of_expected_fields != num_of_format_args
41
44
  end
42
45
  else
43
46
  false
@@ -79,22 +82,36 @@ module RuboCop
79
82
  args.loc.expression.source[0, 2] == SHOVEL
80
83
  end
81
84
 
85
+ def literal?(node)
86
+ node.int_type? ||
87
+ node.str_type? ||
88
+ node.sym_type? ||
89
+ node.float_type? ||
90
+ node.dstr_type? ||
91
+ node.dsym_type?
92
+ end
93
+
82
94
  def count_matches(node)
83
95
  receiver_node, _method_name, *args = *node
84
96
 
85
97
  if (sprintf?(node) || format?(node)) && !heredoc?(node)
86
98
  number_of_args_for_format = (args.size - 1)
87
99
  number_of_expected_fields = expected_fields_count(args.first)
88
- elsif percent?(node)
89
- first_child_argument = args.first
100
+ elsif percent?(node) && args.first.array_type?
101
+ number_of_expected_fields = expected_fields_count(receiver_node)
90
102
 
103
+ first_child_argument = args.first
91
104
  if first_child_argument.array_type?
92
105
  number_of_args_for_format = args.first.child_nodes.size
93
- number_of_expected_fields = expected_fields_count(receiver_node)
94
- else
106
+ elsif literal?(first_child_argument)
95
107
  number_of_args_for_format = 1
96
- number_of_expected_fields = expected_fields_count(receiver_node)
108
+ else
109
+ # non-literals might evaluate to an Array, or they might not
110
+ # so we can't tell just how many format args there will be
111
+ number_of_args_for_format = :unknown
97
112
  end
113
+ else
114
+ number_of_args_for_format = number_of_expected_fields = :unknown
98
115
  end
99
116
 
100
117
  [number_of_args_for_format, number_of_expected_fields]
@@ -113,6 +130,7 @@ module RuboCop
113
130
  end
114
131
 
115
132
  def expected_fields_count(node)
133
+ return :unknown unless node.str_type?
116
134
  node
117
135
  .loc
118
136
  .expression
@@ -20,11 +20,6 @@ module RuboCop
20
20
  class LiteralInCondition < Cop
21
21
  MSG = 'Literal `%s` appeared in a condition.'
22
22
 
23
- LITERALS = [:str, :dstr, :int, :float, :array,
24
- :hash, :regexp, :nil, :true, :false]
25
-
26
- BASIC_LITERALS = LITERALS - [:dstr, :array, :hash]
27
-
28
23
  def on_if(node)
29
24
  check_for_literal(node)
30
25
  end
@@ -5,7 +5,8 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for non-local exit from iterator, without return value.
7
7
  # It warns only when satisfies all of these: `return` doesn't have return
8
- # value, block followed by method chain, and block have arguments.
8
+ # value, the block is preceded by a method chain, the block has arguments,
9
+ # and the method which receives the block is not `define_method`.
9
10
  #
10
11
  # @example
11
12
  #
@@ -42,6 +43,9 @@ module RuboCop
42
43
 
43
44
  # `return` does not exit to outside of lambda block, this is safe.
44
45
  break if lambda?(send_node)
46
+ # if a proc is passed to `Module#define_method`, `return` will not
47
+ # cause a non-local exit error
48
+ break if define_method?(send_node)
45
49
 
46
50
  next if args_node.children.empty?
47
51
  if chained_send?(send_node)
@@ -64,6 +68,11 @@ module RuboCop
64
68
  receiver_node, selector_node = *send_node
65
69
  receiver_node.nil? && selector_node == :lambda
66
70
  end
71
+
72
+ def define_method?(send_node)
73
+ _receiver, selector = *send_node
74
+ selector == :define_method
75
+ end
67
76
  end
68
77
  end
69
78
  end
@@ -14,7 +14,7 @@ module RuboCop
14
14
 
15
15
  def on_send(node)
16
16
  _receiver, method_name, args = *node
17
- return if operator?(method_name) || method_name.to_s.end_with?('=')
17
+ return if operator?(method_name) || node.asgn_method_call?
18
18
  return unless args && args.loc.expression.source.start_with?('(')
19
19
 
20
20
  space_length = spaces_before_left_parenthesis(node)
@@ -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
  # Setter calls with parentheses are parsed this way. The parentheses
26
26
  # belong to the argument, not the send node.
@@ -16,6 +16,12 @@ module RuboCop
16
16
 
17
17
  def check_argument(variable)
18
18
  return unless variable.block_argument?
19
+
20
+ if cop_config['IgnoreEmptyBlocks']
21
+ _send, _args, body = *variable.scope.node
22
+ return if body.nil?
23
+ end
24
+
19
25
  super
20
26
  end
21
27
 
@@ -15,6 +15,14 @@ module RuboCop
15
15
 
16
16
  def check_argument(variable)
17
17
  return unless variable.method_argument?
18
+ return if variable.keyword_argument? &&
19
+ cop_config['AllowUnusedKeywordArguments']
20
+
21
+ if cop_config['IgnoreEmptyMethods']
22
+ _name, _args, body = *variable.scope.node
23
+ return if body.nil?
24
+ end
25
+
18
26
  super
19
27
  end
20
28
 
@@ -21,7 +21,7 @@ module RuboCop
21
21
  condition = 0
22
22
 
23
23
  node.each_node do |child|
24
- if ASGN_NODES.include?(child.type)
24
+ if child.assignment?
25
25
  assignment += 1
26
26
  elsif BRANCH_NODES.include?(child.type)
27
27
  branch += 1
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # Returns true when the block node looks like Class or Module.new do ... .
41
41
  def class_constructor?(block_node)
42
42
  send_node = block_node.children.first
43
- receiver_node, method_name, *_ = *send_node
43
+ receiver_node, method_name, = *send_node
44
44
  return false unless method_name == :new
45
45
  %w(Class Module).include?(Util.const_name(receiver_node))
46
46
  end
@@ -82,7 +82,7 @@ module RuboCop
82
82
  corrector.insert_before(range, ' ' * column_delta)
83
83
  end
84
84
  else
85
- remove(range, corrector) if range.source =~ /^[ \t]+$/
85
+ remove(range, corrector) if range.source =~ /\A[ \t]+\z/
86
86
  end
87
87
  end
88
88
 
@@ -5,6 +5,10 @@ module RuboCop
5
5
  # This module does auto-correction of nodes that could become grammatically
6
6
  # different after the correction. If the code change would alter the
7
7
  # abstract syntax tree, it is not done.
8
+ #
9
+ # However, if the code change merely introduces extraneous "begin" nodes
10
+ # which do not change the meaning of the code, it is still accepted.
11
+ #
8
12
  module AutocorrectUnlessChangingAST
9
13
  def autocorrect(node)
10
14
  current_buffer_src = processed_source.buffer.source
@@ -12,11 +16,12 @@ module RuboCop
12
16
  pre = current_buffer_src[0...replaced_range.begin_pos]
13
17
  post = current_buffer_src[replaced_range.end_pos..-1]
14
18
  new_buffer_src = pre + rewrite_node(node) + post
19
+ new_processed_src = ProcessedSource.new(new_buffer_src)
15
20
 
16
21
  # Make the correction only if it doesn't change the AST for the buffer.
17
- if processed_source.ast != ProcessedSource.new(new_buffer_src).ast
18
- return
19
- end
22
+ return if !new_processed_src.ast ||
23
+ (INLINE_BEGIN.process(processed_source.ast) !=
24
+ INLINE_BEGIN.process(new_processed_src.ast))
20
25
 
21
26
  correction(node)
22
27
  end
@@ -28,6 +33,24 @@ module RuboCop
28
33
  c = correction(ps.ast)
29
34
  Corrector.new(ps.buffer, [c]).rewrite
30
35
  end
36
+
37
+ # 'begin' nodes with a single child can be removed without changing
38
+ # the semantics of an AST. Canonicalizing an AST in this way can help
39
+ # us determine whether it has really changed in a meaningful way, or
40
+ # not. This means we can auto-correct in cases where we would otherwise
41
+ # refrain from doing so.
42
+ #
43
+ # If any other simplifications can be done to an AST without changing
44
+ # its meaning, they should be added here (and the class renamed).
45
+ # This will make autocorrection more powerful across the board.
46
+ #
47
+ class InlineBeginNodes < Parser::AST::Processor
48
+ def on_begin(node)
49
+ node.children.one? ? node.children[0] : node
50
+ end
51
+ end
52
+
53
+ INLINE_BEGIN = InlineBeginNodes.new
31
54
  end
32
55
  end
33
56
  end
@@ -23,13 +23,12 @@ module RuboCop
23
23
  end
24
24
 
25
25
  def on_send(node)
26
- _receiver, method_name, *_, rhs = *node
27
-
28
26
  # we only want to indent relative to the receiver
29
27
  # when the method called looks like a setter
30
- return unless method_name.to_s.end_with?('=')
28
+ return unless node.asgn_method_call?
31
29
 
32
30
  # This will match if, case, begin, blocks, etc.
31
+ rhs = node.children.last
33
32
  check_assignment(node, rhs) if rhs.is_a?(AST::Node)
34
33
  end
35
34
  end
@@ -5,28 +5,75 @@ module RuboCop
5
5
  # Handles `EnforcedStyle` configuration parameters.
6
6
  module ConfigurableEnforcedStyle
7
7
  def opposite_style_detected
8
- self.config_to_allow_offenses ||=
9
- { parameter_name => alternative_style.to_s }
10
- both_styles_detected if config_to_allow_offenses['Enabled']
8
+ style_detected(alternative_style)
11
9
  end
12
10
 
13
11
  def correct_style_detected
14
- # Enabled:true indicates, later when the opposite style is detected,
15
- # that the correct style is used somewhere.
16
- self.config_to_allow_offenses ||= { 'Enabled' => true }
17
- both_styles_detected if config_to_allow_offenses[parameter_name]
12
+ style_detected(style)
18
13
  end
19
14
 
20
- def both_styles_detected
21
- # Both correct and opposite styles exist.
22
- self.config_to_allow_offenses = { 'Enabled' => false }
15
+ def unexpected_style_detected(unexpected)
16
+ style_detected(unexpected)
17
+ end
18
+
19
+ def ambiguous_style_detected(*possibilities)
20
+ style_detected(possibilities)
23
21
  end
24
22
 
25
- def unrecognized_style_detected
26
- # All we can do is to disable.
23
+ def style_detected(detected)
24
+ # `detected` can be a single style, or an Array of possible styles
25
+ # (if there is more than one which matches the observed code)
26
+
27
+ return if no_acceptable_style?
28
+
29
+ if detected.is_a?(Array)
30
+ detected.map!(&:to_s)
31
+ else
32
+ detected = detected.to_s
33
+ end
34
+
35
+ if !detected_style # we haven't observed any specific style yet
36
+ self.detected_style = detected
37
+ elsif detected_style.is_a?(Array)
38
+ self.detected_style &= [*detected]
39
+ elsif detected.is_a?(Array)
40
+ no_acceptable_style! unless detected.include?(detected_style)
41
+ else
42
+ no_acceptable_style! unless detected_style == detected
43
+ end
44
+ end
45
+
46
+ def no_acceptable_style?
47
+ config_to_allow_offenses['Enabled'] == false
48
+ end
49
+
50
+ def no_acceptable_style!
27
51
  self.config_to_allow_offenses = { 'Enabled' => false }
28
52
  end
29
53
 
54
+ def detected_style
55
+ config_to_allow_offenses[parameter_name]
56
+ end
57
+
58
+ def detected_style=(style)
59
+ if style.nil?
60
+ no_acceptable_style!
61
+ elsif style.is_a?(Array)
62
+ if style.empty?
63
+ no_acceptable_style!
64
+ elsif style.one?
65
+ config_to_allow_offenses[parameter_name] = style[0]
66
+ else
67
+ config_to_allow_offenses[parameter_name] = style
68
+ end
69
+ else
70
+ config_to_allow_offenses[parameter_name] = style
71
+ end
72
+ end
73
+
74
+ alias_method :conflicting_styles_detected, :no_acceptable_style!
75
+ alias_method :unrecognized_style_detected, :no_acceptable_style!
76
+
30
77
  def style
31
78
  s = cop_config[parameter_name]
32
79
  if cop_config['SupportedStyles'].include?(s)