rubocop 0.84.0 → 0.85.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -14
  3. data/config/default.yml +33 -15
  4. data/lib/rubocop.rb +6 -0
  5. data/lib/rubocop/cli.rb +2 -2
  6. data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
  7. data/lib/rubocop/comment_config.rb +1 -1
  8. data/lib/rubocop/config.rb +3 -1
  9. data/lib/rubocop/config_loader.rb +1 -1
  10. data/lib/rubocop/config_loader_resolver.rb +18 -2
  11. data/lib/rubocop/config_store.rb +12 -2
  12. data/lib/rubocop/cop/bundler/gem_comment.rb +70 -1
  13. data/lib/rubocop/cop/commissioner.rb +0 -21
  14. data/lib/rubocop/cop/cop.rb +36 -21
  15. data/lib/rubocop/cop/corrector.rb +3 -1
  16. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +1 -1
  17. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +3 -1
  18. data/lib/rubocop/cop/layout/case_indentation.rb +3 -3
  19. data/lib/rubocop/cop/layout/class_structure.rb +19 -16
  20. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
  21. data/lib/rubocop/cop/layout/end_of_line.rb +2 -2
  22. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
  23. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  24. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  25. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -6
  26. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
  27. data/lib/rubocop/cop/layout/heredoc_indentation.rb +20 -103
  28. data/lib/rubocop/cop/layout/line_length.rb +17 -17
  29. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -1
  30. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  31. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +3 -1
  32. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -1
  33. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -1
  34. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +8 -4
  35. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  36. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -1
  37. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +33 -2
  38. data/lib/rubocop/cop/lint/loop.rb +1 -1
  39. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +69 -0
  40. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  41. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +7 -7
  42. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -1
  43. data/lib/rubocop/cop/lint/redundant_require_statement.rb +3 -3
  44. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  45. data/lib/rubocop/cop/lint/suppressed_exception.rb +4 -2
  46. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  47. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +1 -1
  48. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  49. data/lib/rubocop/cop/migration/department_name.rb +9 -5
  50. data/lib/rubocop/cop/mixin/array_min_size.rb +3 -1
  51. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -1
  52. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
  53. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  54. data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
  55. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  56. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +16 -0
  57. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -1
  58. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +1 -1
  59. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +11 -1
  60. data/lib/rubocop/cop/naming/file_name.rb +26 -11
  61. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  62. data/lib/rubocop/cop/registry.rb +65 -8
  63. data/lib/rubocop/cop/style/array_join.rb +1 -1
  64. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -1
  65. data/lib/rubocop/cop/style/copyright.rb +2 -2
  66. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  67. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  68. data/lib/rubocop/cop/style/format_string_token.rb +2 -3
  69. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -2
  70. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
  71. data/lib/rubocop/cop/style/hash_syntax.rb +5 -3
  72. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  73. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  74. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  75. data/lib/rubocop/cop/style/negated_unless.rb +3 -3
  76. data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
  77. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  78. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  79. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +89 -0
  80. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +130 -0
  81. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  82. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +3 -3
  83. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +3 -3
  84. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +13 -13
  85. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +3 -3
  86. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
  87. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  88. data/lib/rubocop/cop/style/when_then.rb +1 -1
  89. data/lib/rubocop/cop/team.rb +69 -25
  90. data/lib/rubocop/cop/util.rb +1 -1
  91. data/lib/rubocop/cop/utils/format_string.rb +18 -0
  92. data/lib/rubocop/cop/variable_force/branch.rb +3 -1
  93. data/lib/rubocop/formatter/junit_formatter.rb +14 -4
  94. data/lib/rubocop/magic_comment.rb +1 -1
  95. data/lib/rubocop/options.rb +17 -3
  96. data/lib/rubocop/result_cache.rb +4 -4
  97. data/lib/rubocop/rspec/cop_helper.rb +2 -23
  98. data/lib/rubocop/rspec/expect_offense.rb +45 -6
  99. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  100. data/lib/rubocop/runner.rb +14 -10
  101. data/lib/rubocop/target_finder.rb +3 -1
  102. data/lib/rubocop/target_ruby.rb +4 -1
  103. data/lib/rubocop/version.rb +1 -1
  104. metadata +23 -5
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for uses of `each_key` and `each_value` Hash methods.
7
7
  #
8
- # Note: If you have an array of two-element arrays, you can put
8
+ # NOTE: If you have an array of two-element arrays, you can put
9
9
  # parentheses around the block arguments to indicate that you're not
10
10
  # working with a hash, and suppress RuboCop offenses.
11
11
  #
@@ -13,11 +13,11 @@ module RuboCop
13
13
  # The supported styles are:
14
14
  #
15
15
  # * ruby19 - forces use of the 1.9 syntax (e.g. `{a: 1}`) when hashes have
16
- # all symbols for keys
16
+ # all symbols for keys
17
17
  # * hash_rockets - forces use of hash rockets for all hashes
18
18
  # * no_mixed_keys - simply checks for hashes with mixed syntaxes
19
19
  # * ruby19_no_mixed_keys - forces use of ruby 1.9 syntax and forbids mixed
20
- # syntax hashes
20
+ # syntax hashes
21
21
  #
22
22
  # @example EnforcedStyle: ruby19 (default)
23
23
  # # bad
@@ -178,7 +178,9 @@ module RuboCop
178
178
  )
179
179
 
180
180
  hash_node = pair_node.parent
181
- corrector.wrap(hash_node, '{', '}') if hash_node.parent&.return_type? && !hash_node.braces?
181
+ return unless hash_node.parent&.return_type? && !hash_node.braces?
182
+
183
+ corrector.wrap(hash_node, '{', '}')
182
184
  end
183
185
 
184
186
  def range_for_autocorrect_ruby19(pair_node)
@@ -23,7 +23,7 @@ module RuboCop
23
23
  def investigate(processed_source)
24
24
  processed_source.each_comment do |comment|
25
25
  next if comment_line?(processed_source[comment.loc.line - 1]) ||
26
- comment.text.match(/\A# rubocop:(enable|disable)/)
26
+ comment.text.match?(/\A# rubocop:(enable|disable)/)
27
27
 
28
28
  add_offense(comment)
29
29
  end
@@ -82,7 +82,7 @@ module RuboCop
82
82
  end
83
83
 
84
84
  def keyword_end_str(node, node_buf)
85
- if /[^\s\)]/.match?(node_buf.source_line(node.loc.end.line))
85
+ if /[^\s)]/.match?(node_buf.source_line(node.loc.end.line))
86
86
  "\n" + (' ' * node.loc.column) + 'end'
87
87
  else
88
88
  'end'
@@ -6,9 +6,9 @@ module RuboCop
6
6
  # Checks for uses of if with a negated condition. Only ifs
7
7
  # without else are considered. There are three different styles:
8
8
  #
9
- # - both
10
- # - prefix
11
- # - postfix
9
+ # * both
10
+ # * prefix
11
+ # * postfix
12
12
  #
13
13
  # @example EnforcedStyle: both (default)
14
14
  # # enforces `unless` for `prefix` and `postfix` conditionals
@@ -6,9 +6,9 @@ module RuboCop
6
6
  # Checks for uses of unless with a negated condition. Only unless
7
7
  # without else are considered. There are three different styles:
8
8
  #
9
- # - both
10
- # - prefix
11
- # - postfix
9
+ # * both
10
+ # * prefix
11
+ # * postfix
12
12
  #
13
13
  # @example EnforcedStyle: both (default)
14
14
  # # enforces `if` for `prefix` and `postfix` conditionals
@@ -11,7 +11,7 @@ module RuboCop
11
11
  #
12
12
  # With `IncludeSemanticChanges` set to `true`, this cop reports offenses
13
13
  # for `!x.nil?` and autocorrects that and `x != nil` to solely `x`, which
14
- # is **usually** OK, but might change behavior.
14
+ # is *usually* OK, but might change behavior.
15
15
  #
16
16
  # @example
17
17
  # # bad
@@ -27,7 +27,8 @@ module RuboCop
27
27
  class RedundantConditional < Cop
28
28
  include Alignment
29
29
 
30
- COMPARISON_OPERATORS = RuboCop::AST::Node::COMPARISON_OPERATORS
30
+ operators = RuboCop::AST::Node::COMPARISON_OPERATORS.to_a
31
+ COMPARISON_OPERATOR_MATCHER = "{:#{operators.join(' :')}}"
31
32
 
32
33
  MSG = 'This conditional expression can just be replaced ' \
33
34
  'by `%<msg>s`.'
@@ -54,11 +55,11 @@ module RuboCop
54
55
  end
55
56
 
56
57
  def_node_matcher :redundant_condition?, <<~RUBY
57
- (if (send _ {:#{COMPARISON_OPERATORS.join(' :')}} _) true false)
58
+ (if (send _ #{COMPARISON_OPERATOR_MATCHER} _) true false)
58
59
  RUBY
59
60
 
60
61
  def_node_matcher :redundant_condition_inverted?, <<~RUBY
61
- (if (send _ {:#{COMPARISON_OPERATORS.join(' :')}} _) false true)
62
+ (if (send _ #{COMPARISON_OPERATOR_MATCHER} _) false true)
62
63
  RUBY
63
64
 
64
65
  def offense?(node)
@@ -27,7 +27,7 @@ module RuboCop
27
27
  EMPTY = ''
28
28
  PERCENT_Q = '%q'
29
29
  PERCENT_CAPITAL_Q = '%Q'
30
- STRING_INTERPOLATION_REGEXP = /#\{.+}/.freeze
30
+ STRING_INTERPOLATION_REGEXP = /#\{.+\}/.freeze
31
31
  ESCAPED_NON_BACKSLASH = /\\[^\\]/.freeze
32
32
 
33
33
  def on_dstr(node)
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for unnecessary single-element Regexp character classes.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # r = /[x]/
12
+ #
13
+ # # good
14
+ # r = /x/
15
+ #
16
+ # # bad
17
+ # r = /[\s]/
18
+ #
19
+ # # good
20
+ # r = /\s/
21
+ #
22
+ # # good
23
+ # r = /[ab]/
24
+ class RedundantRegexpCharacterClass < Cop
25
+ include MatchRange
26
+ include RegexpLiteralHelp
27
+
28
+ MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \
29
+ '`%<char_class>s` can be replaced with `%<element>s`.'
30
+
31
+ PATTERN = /
32
+ (
33
+ (?<!\\) # No \-prefix (i.e. not escaped)
34
+ \[ # Literal [
35
+ (?!\#\{) # Not (the start of) an interpolation
36
+ (?: # Either...
37
+ \\. | # Any escaped character
38
+ [^.*+?{}()|$] | # or one that doesn't require escaping outside the character class
39
+ \\[upP]\{[^}]+\} # or a unicode code-point or property
40
+ )
41
+ \] # Literal ]
42
+ )
43
+ /x.freeze
44
+
45
+ def on_regexp(node)
46
+ each_redundant_character_class(node) do |loc|
47
+ next if whitespace_in_free_space_mode?(node, loc)
48
+
49
+ add_offense(
50
+ node,
51
+ location: loc,
52
+ message: format(
53
+ MSG_REDUNDANT_CHARACTER_CLASS,
54
+ char_class: loc.source,
55
+ element: without_character_class(loc)
56
+ )
57
+ )
58
+ end
59
+ end
60
+
61
+ def autocorrect(node)
62
+ lambda do |corrector|
63
+ each_redundant_character_class(node) do |loc|
64
+ corrector.replace(loc, without_character_class(loc))
65
+ end
66
+ end
67
+ end
68
+
69
+ def each_redundant_character_class(node)
70
+ each_match_range(node.loc.expression, PATTERN) do |loc|
71
+ yield loc
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def without_character_class(loc)
78
+ loc.source[1..-2]
79
+ end
80
+
81
+ def whitespace_in_free_space_mode?(node, loc)
82
+ return false unless freespace_mode_regexp?(node)
83
+
84
+ /\[\s\]/.match?(loc.source)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for redundant escapes inside Regexp literals.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # %r{foo\/bar}
11
+ #
12
+ # # good
13
+ # %r{foo/bar}
14
+ #
15
+ # # good
16
+ # /foo\/bar/
17
+ #
18
+ # # good
19
+ # %r/foo\/bar/
20
+ #
21
+ # # bad
22
+ # /a\-b/
23
+ #
24
+ # # good
25
+ # /a-b/
26
+ #
27
+ # # bad
28
+ # /[\+\-]\d/
29
+ #
30
+ # # good
31
+ # /[+\-]\d/
32
+ class RedundantRegexpEscape < Cop
33
+ include RangeHelp
34
+ include RegexpLiteralHelp
35
+
36
+ MSG_REDUNDANT_ESCAPE = 'Redundant escape inside regexp literal'
37
+
38
+ ALLOWED_ALWAYS_ESCAPES = ' []^\\#'.chars.freeze
39
+ ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES = '-'.chars.freeze
40
+ ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES = '.*+?{}()|$'.chars.freeze
41
+
42
+ def on_regexp(node)
43
+ each_escape(node) do |char, index, within_character_class|
44
+ next if allowed_escape?(node, char, within_character_class)
45
+
46
+ add_offense(
47
+ node,
48
+ location: escape_range_at_index(node, index),
49
+ message: MSG_REDUNDANT_ESCAPE
50
+ )
51
+ end
52
+ end
53
+
54
+ def autocorrect(node)
55
+ lambda do |corrector|
56
+ each_escape(node) do |char, index, within_character_class|
57
+ next if allowed_escape?(node, char, within_character_class)
58
+
59
+ corrector.remove_leading(escape_range_at_index(node, index), 1)
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def slash_literal?(node)
67
+ ['/', '%r/'].include?(node.loc.begin.source)
68
+ end
69
+
70
+ def allowed_escape?(node, char, within_character_class)
71
+ # Strictly speaking a few single-letter metachars are currently
72
+ # unnecessary to "escape", e.g. g, i, E, F, but enumerating them is
73
+ # rather difficult, and their behaviour could change over time with
74
+ # different versions of Ruby so that e.g. /\g/ != /g/
75
+ return true if /[[:alnum:]]/.match?(char)
76
+ return true if ALLOWED_ALWAYS_ESCAPES.include?(char)
77
+
78
+ if char == '/'
79
+ slash_literal?(node)
80
+ elsif within_character_class
81
+ ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES.include?(char)
82
+ else
83
+ ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES.include?(char)
84
+ end
85
+ end
86
+
87
+ def each_escape(node)
88
+ pattern_source(node).each_char.with_index.reduce(
89
+ [nil, false]
90
+ ) do |(previous, within_character_class), (current, index)|
91
+ if previous == '\\'
92
+ yield [current, index - 1, within_character_class]
93
+
94
+ [nil, within_character_class]
95
+ elsif previous == '[' && current != ':'
96
+ [current, true]
97
+ elsif previous != ':' && current == ']'
98
+ [current, false]
99
+ else
100
+ [current, within_character_class]
101
+ end
102
+ end
103
+ end
104
+
105
+ def escape_range_at_index(node, index)
106
+ regexp_begin = node.loc.begin.end_pos
107
+
108
+ start = regexp_begin + index
109
+
110
+ range_between(start, start + 2)
111
+ end
112
+
113
+ def pattern_source(node)
114
+ freespace_mode = freespace_mode_regexp?(node)
115
+
116
+ node.children.reject(&:regopt_type?).map do |child|
117
+ source = child.source
118
+
119
+ if freespace_mode
120
+ # Remove comments to avoid misleading results
121
+ source.sub(/(?<!\\)#.*/, '')
122
+ else
123
+ source
124
+ end
125
+ end.join
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -106,7 +106,7 @@ module RuboCop
106
106
  # method name
107
107
  string =~ /\A[a-zA-Z_]\w*[!?]?\z/ ||
108
108
  # instance / class variable
109
- string =~ /\A\@\@?[a-zA-Z_]\w*\z/ ||
109
+ string =~ /\A@@?[a-zA-Z_]\w*\z/ ||
110
110
  # global variable
111
111
  string =~ /\A\$[1-9]\d*\z/ ||
112
112
  string =~ /\A\$[a-zA-Z_]\w*\z/ ||
@@ -6,11 +6,11 @@ module RuboCop
6
6
  # This cop checks for trailing comma in argument lists.
7
7
  # The supported styles are:
8
8
  #
9
- # - `consistent_comma`: Requires a comma after the last argument,
9
+ # * `consistent_comma`: Requires a comma after the last argument,
10
10
  # for all parenthesized method calls with arguments.
11
- # - `comma`: Requires a comma after the last argument, but only for
11
+ # * `comma`: Requires a comma after the last argument, but only for
12
12
  # parenthesized method calls where each argument is on its own line.
13
- # - `no_comma`: Requires that there is no comma after the last
13
+ # * `no_comma`: Requires that there is no comma after the last
14
14
  # argument.
15
15
  #
16
16
  # @example EnforcedStyleForMultiline: consistent_comma
@@ -6,11 +6,11 @@ module RuboCop
6
6
  # This cop checks for trailing comma in array literals.
7
7
  # The configuration options are:
8
8
  #
9
- # - `consistent_comma`: Requires a comma after the
9
+ # * `consistent_comma`: Requires a comma after the
10
10
  # last item of all non-empty, multiline array literals.
11
- # - `comma`: Requires a comma after last item in an array,
11
+ # * `comma`: Requires a comma after last item in an array,
12
12
  # but only when each item is on its own line.
13
- # - `no_comma`: Does not requires a comma after the
13
+ # * `no_comma`: Does not requires a comma after the
14
14
  # last item in an array
15
15
  #
16
16
  # @example EnforcedStyleForMultiline: consistent_comma
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # # bad
13
13
  # add { |foo, bar,| foo + bar }
14
14
  #
15
- # # good
15
+ # # good
16
16
  # add { |foo, bar| foo + bar }
17
17
  #
18
18
  # # good
@@ -22,24 +22,24 @@ module RuboCop
22
22
  # add { foo }
23
23
  #
24
24
  # # bad
25
- # add do |foo, bar,|
26
- # foo + bar
25
+ # add do |foo, bar,|
26
+ # foo + bar
27
27
  # end
28
28
  #
29
- # # good
30
- # add do |foo, bar|
31
- # foo + bar
32
- # end
29
+ # # good
30
+ # add do |foo, bar|
31
+ # foo + bar
32
+ # end
33
33
  #
34
- # # good
34
+ # # good
35
35
  # add do |foo,|
36
- # foo
37
- # end
36
+ # foo
37
+ # end
38
38
  #
39
- # # good
40
- # add do
39
+ # # good
40
+ # add do
41
41
  # foo + bar
42
- # end
42
+ # end
43
43
  class TrailingCommaInBlockArgs < Cop
44
44
  MSG = 'Useless trailing comma present in block arguments.'
45
45
 
@@ -6,11 +6,11 @@ module RuboCop
6
6
  # This cop checks for trailing comma in hash literals.
7
7
  # The configuration options are:
8
8
  #
9
- # - `consistent_comma`: Requires a comma after the
9
+ # * `consistent_comma`: Requires a comma after the
10
10
  # last item of all non-empty, multiline hash literals.
11
- # - `comma`: Requires a comma after the last item in a hash,
11
+ # * `comma`: Requires a comma after the last item in a hash,
12
12
  # but only when each item is on its own line.
13
- # - `no_comma`: Does not requires a comma after the
13
+ # * `no_comma`: Does not requires a comma after the
14
14
  # last item in a hash
15
15
  #
16
16
  # @example EnforcedStyleForMultiline: consistent_comma