rubocop 1.11.0 → 1.12.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +16 -1
  4. data/lib/rubocop.rb +1 -0
  5. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  6. data/lib/rubocop/comment_config.rb +43 -94
  7. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  8. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +11 -8
  9. data/lib/rubocop/cop/layout/argument_alignment.rb +6 -5
  10. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  11. data/lib/rubocop/cop/layout/assignment_indentation.rb +6 -3
  12. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  13. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +14 -15
  14. data/lib/rubocop/cop/layout/comment_indentation.rb +16 -16
  15. data/lib/rubocop/cop/layout/else_alignment.rb +9 -6
  16. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -5
  17. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +9 -6
  18. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -15
  19. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  20. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  21. data/lib/rubocop/cop/layout/indentation_style.rb +27 -30
  22. data/lib/rubocop/cop/layout/indentation_width.rb +19 -9
  23. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +6 -5
  24. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -5
  25. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  26. data/lib/rubocop/cop/lint/number_conversion.rb +7 -0
  27. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -2
  28. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  29. data/lib/rubocop/cop/lint/symbol_conversion.rb +89 -2
  30. data/lib/rubocop/cop/mixin/alignment.rb +10 -3
  31. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  32. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  33. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -6
  34. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  35. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  36. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +1 -1
  37. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +4 -6
  38. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +4 -0
  39. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  40. data/lib/rubocop/cop/registry.rb +9 -0
  41. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
  42. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  43. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +62 -0
  44. data/lib/rubocop/cop/style/case_like_if.rb +15 -4
  45. data/lib/rubocop/cop/style/class_equality_comparison.rb +2 -0
  46. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  47. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  48. data/lib/rubocop/cop/style/documentation.rb +25 -3
  49. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  50. data/lib/rubocop/cop/style/hash_syntax.rb +16 -15
  51. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +40 -0
  52. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +20 -2
  53. data/lib/rubocop/cop/style/negated_if_else_condition.rb +15 -2
  54. data/lib/rubocop/cop/style/redundant_begin.rb +26 -3
  55. data/lib/rubocop/cop/style/redundant_return.rb +4 -0
  56. data/lib/rubocop/cop/style/redundant_self.rb +7 -3
  57. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  58. data/lib/rubocop/cop/style/rescue_modifier.rb +17 -14
  59. data/lib/rubocop/cop/style/sole_nested_conditional.rb +16 -0
  60. data/lib/rubocop/cop/style/string_chars.rb +38 -0
  61. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -0
  62. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +5 -1
  63. data/lib/rubocop/cop/style/unless_logical_operators.rb +8 -2
  64. data/lib/rubocop/directive_comment.rb +64 -9
  65. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  66. data/lib/rubocop/magic_comment.rb +1 -1
  67. data/lib/rubocop/target_finder.rb +1 -0
  68. data/lib/rubocop/version.rb +1 -1
  69. metadata +5 -3
@@ -50,6 +50,8 @@ module RuboCop
50
50
 
51
51
  def class_name(class_node, node)
52
52
  if node.children.first.method?(:name)
53
+ return class_node.receiver.source if class_node.receiver
54
+
53
55
  class_node.source.delete('"').delete("'")
54
56
  else
55
57
  class_node.source
@@ -165,7 +165,7 @@ module RuboCop
165
165
  end
166
166
 
167
167
  def preferred_delimiter
168
- (command_delimiter || default_delimiter).split('')
168
+ (command_delimiter || default_delimiter).chars
169
169
  end
170
170
 
171
171
  def command_delimiter
@@ -70,8 +70,8 @@ module RuboCop
70
70
  end
71
71
 
72
72
  def directive_cops(comment)
73
- match = CommentConfig::COMMENT_DIRECTIVE_REGEXP.match(comment.text)
74
- match && match[2] ? match[2].split(',').map(&:strip) : []
73
+ match_captures = DirectiveComment.new(comment).match_captures
74
+ match_captures && match_captures[1] ? match_captures[1].split(',').map(&:strip) : []
75
75
  end
76
76
 
77
77
  def allowed_cops
@@ -60,6 +60,15 @@ module RuboCop
60
60
  # extend Foo
61
61
  # end
62
62
  #
63
+ # @example AllowedConstants: ['ClassMethods']
64
+ #
65
+ # # good
66
+ # module A
67
+ # module ClassMethods
68
+ # # ...
69
+ # end
70
+ # end
71
+ #
63
72
  class Documentation < Base
64
73
  include DocumentationComment
65
74
 
@@ -90,14 +99,19 @@ module RuboCop
90
99
 
91
100
  def check(node, body, type)
92
101
  return if namespace?(body)
93
- return if documentation_comment?(node) || nodoc_comment?(node)
94
- return if compact_namespace?(node) &&
95
- nodoc_comment?(outer_module(node).first)
102
+ return if documentation_comment?(node)
103
+ return if constant_allowed?(node)
104
+ return if nodoc_self_or_outer_module?(node)
96
105
  return if macro_only?(body)
97
106
 
98
107
  add_offense(node.loc.keyword, message: format(MSG, type: type))
99
108
  end
100
109
 
110
+ def nodoc_self_or_outer_module?(node)
111
+ nodoc_comment?(node) ||
112
+ compact_namespace?(node) && nodoc_comment?(outer_module(node).first)
113
+ end
114
+
101
115
  def macro_only?(body)
102
116
  body.respond_to?(:macro?) && body.macro? ||
103
117
  body.respond_to?(:children) && body.children&.all? { |child| macro_only?(child) }
@@ -117,6 +131,10 @@ module RuboCop
117
131
  constant_definition?(node) || constant_visibility_declaration?(node)
118
132
  end
119
133
 
134
+ def constant_allowed?(node)
135
+ allowed_constants.include?(node.identifier.short_name)
136
+ end
137
+
120
138
  def compact_namespace?(node)
121
139
  /::/.match?(node.loc.name.source)
122
140
  end
@@ -143,6 +161,10 @@ module RuboCop
143
161
  def nodoc(node)
144
162
  processed_source.ast_with_comments[node.children.first].first
145
163
  end
164
+
165
+ def allowed_constants
166
+ @allowed_constants ||= cop_config.fetch('AllowedConstants', []).map(&:intern)
167
+ end
146
168
  end
147
169
  end
148
170
  end
@@ -224,7 +224,7 @@ module RuboCop
224
224
 
225
225
  register_offense(node) do |corrector|
226
226
  line_str = missing_line(node, code)
227
- corrector.insert_after(node.loc.expression.end, ", __FILE__, #{line_str}")
227
+ corrector.insert_after(node.last_argument.source_range.end, ", __FILE__, #{line_str}")
228
228
  end
229
229
  end
230
230
 
@@ -54,9 +54,10 @@ module RuboCop
54
54
  # # good
55
55
  # {a: 1, b: 2}
56
56
  # {:c => 3, 'd' => 4}
57
- class HashSyntax < Cop
57
+ class HashSyntax < Base
58
58
  include ConfigurableEnforcedStyle
59
59
  include RangeHelp
60
+ extend AutoCorrector
60
61
 
61
62
  MSG_19 = 'Use the new Ruby 1.9 hash syntax.'
62
63
  MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash."
@@ -104,18 +105,6 @@ module RuboCop
104
105
  end
105
106
  end
106
107
 
107
- def autocorrect(node)
108
- lambda do |corrector|
109
- if style == :hash_rockets || force_hash_rockets?(node.parent.pairs)
110
- autocorrect_hash_rockets(corrector, node)
111
- elsif style == :ruby19_no_mixed_keys || style == :no_mixed_keys
112
- autocorrect_no_mixed_keys(corrector, node)
113
- else
114
- autocorrect_ruby19(corrector, node)
115
- end
116
- end
117
- end
118
-
119
108
  def alternative_style
120
109
  case style
121
110
  when :hash_rockets
@@ -127,6 +116,16 @@ module RuboCop
127
116
 
128
117
  private
129
118
 
119
+ def autocorrect(corrector, node)
120
+ if style == :hash_rockets || force_hash_rockets?(node.parent.pairs)
121
+ autocorrect_hash_rockets(corrector, node)
122
+ elsif style == :ruby19_no_mixed_keys || style == :no_mixed_keys
123
+ autocorrect_no_mixed_keys(corrector, node)
124
+ else
125
+ autocorrect_ruby19(corrector, node)
126
+ end
127
+ end
128
+
130
129
  def sym_indices?(pairs)
131
130
  pairs.all? { |p| word_symbol_pair?(p) }
132
131
  end
@@ -152,14 +151,16 @@ module RuboCop
152
151
  return true if /\A[_a-z]\w*[?!]?\z/i.match?(sym_name)
153
152
 
154
153
  # For more complicated hash keys, let the parser validate the syntax.
155
- parse("{ #{sym_name}: :foo }").valid_syntax?
154
+ ProcessedSource.new("{ #{sym_name}: :foo }", target_ruby_version).valid_syntax?
156
155
  end
157
156
 
158
157
  def check(pairs, delim, msg)
159
158
  pairs.each do |pair|
160
159
  if pair.delimiter == delim
161
160
  location = pair.source_range.begin.join(pair.loc.operator)
162
- add_offense(pair, location: location, message: msg) do
161
+ add_offense(location, message: msg) do |corrector|
162
+ autocorrect(corrector, pair)
163
+
163
164
  opposite_style_detected
164
165
  end
165
166
  else
@@ -79,6 +79,30 @@ module RuboCop
79
79
  # # good
80
80
  # foo.enforce strict: true
81
81
  #
82
+ # # good
83
+ # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
84
+ # model.validate strict(true)
85
+ #
86
+ # # good
87
+ # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
88
+ # yield path, File.basename(path)
89
+ #
90
+ # # good
91
+ # # Operators methods calls with parens
92
+ # array&.[](index)
93
+ #
94
+ # # good
95
+ # # Operators methods without parens, if you prefer
96
+ # array.[] index
97
+ #
98
+ # # good
99
+ # # Operators methods calls with parens
100
+ # array&.[](index)
101
+ #
102
+ # # good
103
+ # # Operators methods without parens, if you prefer
104
+ # array.[] index
105
+ #
82
106
  # @example IgnoreMacros: true (default)
83
107
  #
84
108
  # # good
@@ -146,6 +170,22 @@ module RuboCop
146
170
  #
147
171
  # # good
148
172
  # Array 1
173
+ #
174
+ # @example AllowParenthesesInStringInterpolation: false (default)
175
+ #
176
+ # # bad
177
+ # "#{t('this.is.bad')}"
178
+ #
179
+ # # good
180
+ # "#{t 'this.is.better'}"
181
+ #
182
+ # @example AllowParenthesesInStringInterpolation: true
183
+ #
184
+ # # good
185
+ # "#{t('this.is.good')}"
186
+ #
187
+ # # good
188
+ # "#{t 'this.is.also.good'}"
149
189
  class MethodCallWithArgsParentheses < Base
150
190
  require_relative 'method_call_with_args_parentheses/omit_parentheses'
151
191
  require_relative 'method_call_with_args_parentheses/require_parentheses'
@@ -5,6 +5,7 @@ module RuboCop
5
5
  module Style
6
6
  class MethodCallWithArgsParentheses
7
7
  # Style omit_parentheses
8
+ # rubocop:disable Metrics/ModuleLength
8
9
  module OmitParentheses
9
10
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
10
11
  OMIT_MSG = 'Omit parentheses for method calls with arguments.'
@@ -12,18 +13,21 @@ module RuboCop
12
13
 
13
14
  private
14
15
 
16
+ # rubocop:disable Metrics/CyclomaticComplexity
15
17
  def omit_parentheses(node)
16
18
  return unless node.parenthesized?
17
19
  return if inside_endless_method_def?(node)
18
- return if node.implicit_call?
20
+ return if syntax_like_method_call?(node)
19
21
  return if super_call_without_arguments?(node)
20
22
  return if allowed_camel_case_method_call?(node)
21
23
  return if legitimate_call_with_parentheses?(node)
24
+ return if allowed_string_interpolation_method_call?(node)
22
25
 
23
26
  add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
24
27
  auto_correct(corrector, node)
25
28
  end
26
29
  end
30
+ # rubocop:enable Metrics/CyclomaticComplexity
27
31
 
28
32
  def auto_correct(corrector, node)
29
33
  if parentheses_at_the_end_of_multiline_call?(node)
@@ -43,6 +47,10 @@ module RuboCop
43
47
  node.each_ancestor(:def).any?(&:endless?) && node.arguments.any?
44
48
  end
45
49
 
50
+ def syntax_like_method_call?(node)
51
+ node.implicit_call? || node.operator_method?
52
+ end
53
+
46
54
  def super_call_without_arguments?(node)
47
55
  node.super_type? && node.arguments.none?
48
56
  end
@@ -53,6 +61,11 @@ module RuboCop
53
61
  cop_config['AllowParenthesesInCamelCaseMethod'])
54
62
  end
55
63
 
64
+ def allowed_string_interpolation_method_call?(node)
65
+ cop_config['AllowParenthesesInStringInterpolation'] &&
66
+ inside_string_interpolation?(node)
67
+ end
68
+
56
69
  def parentheses_at_the_end_of_multiline_call?(node)
57
70
  node.multiline? &&
58
71
  node.loc.begin.source_line
@@ -114,7 +127,7 @@ module RuboCop
114
127
  def call_as_argument_or_chain?(node)
115
128
  node.parent &&
116
129
  (node.parent.send_type? && !assigned_before?(node.parent, node) ||
117
- node.parent.csend_type? || node.parent.super_type?)
130
+ node.parent.csend_type? || node.parent.super_type? || node.parent.yield_type?)
118
131
  end
119
132
 
120
133
  def hash_literal_in_arguments?(node)
@@ -172,7 +185,12 @@ module RuboCop
172
185
  node.assignment? &&
173
186
  node.loc.operator.begin < target.loc.begin
174
187
  end
188
+
189
+ def inside_string_interpolation?(node)
190
+ node.ancestors.drop_while { |a| !a.begin_type? }.any?(&:dstr_type?)
191
+ end
175
192
  end
193
+ # rubocop:enable Metrics/ModuleLength
176
194
  end
177
195
  end
178
196
  end
@@ -29,6 +29,7 @@ module RuboCop
29
29
  #
30
30
  class NegatedIfElseCondition < Base
31
31
  include RangeHelp
32
+ include CommentsHelp
32
33
  extend AutoCorrector
33
34
 
34
35
  MSG = 'Invert the negated condition and swap the %<type>s branches.'
@@ -97,10 +98,22 @@ module RuboCop
97
98
  if node.if_branch.nil?
98
99
  corrector.remove(range_by_whole_lines(node.loc.else, include_final_newline: true))
99
100
  else
100
- corrector.replace(node.if_branch, node.else_branch.source)
101
- corrector.replace(node.else_branch, node.if_branch.source)
101
+ if_range = node_with_comments(node.if_branch)
102
+ else_range = node_with_comments(node.else_branch)
103
+
104
+ corrector.replace(if_range, else_range.source)
105
+ corrector.replace(else_range, if_range.source)
102
106
  end
103
107
  end
108
+
109
+ def node_with_comments(node)
110
+ first_statement = node.begin_type? ? node.children[0] : node
111
+ return node if processed_source.ast_with_comments[first_statement].empty?
112
+
113
+ begin_pos = source_range_with_comment(first_statement).begin_pos
114
+ end_pos = node.source_range.end_pos
115
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
116
+ end
104
117
  end
105
118
  end
106
119
  end
@@ -63,6 +63,7 @@ module RuboCop
63
63
  # end
64
64
  # end
65
65
  class RedundantBegin < Base
66
+ include RangeHelp
66
67
  extend AutoCorrector
67
68
 
68
69
  MSG = 'Redundant `begin` block detected.'
@@ -95,12 +96,26 @@ module RuboCop
95
96
  private
96
97
 
97
98
  def register_offense(node)
98
- add_offense(node.loc.begin) do |corrector|
99
- corrector.remove(node.loc.begin)
99
+ offense_range = node.loc.begin
100
+
101
+ add_offense(offense_range) do |corrector|
102
+ if any_ancestor_assignment_node?(node)
103
+ replace_begin_with_statement(corrector, offense_range, node)
104
+ else
105
+ corrector.remove(offense_range)
106
+ end
107
+
100
108
  corrector.remove(node.loc.end)
101
109
  end
102
110
  end
103
111
 
112
+ def replace_begin_with_statement(corrector, offense_range, node)
113
+ first_child = node.children.first
114
+
115
+ corrector.replace(offense_range, first_child.source)
116
+ corrector.remove(range_between(offense_range.end_pos, first_child.source_range.end_pos))
117
+ end
118
+
104
119
  def empty_begin?(node)
105
120
  node.children.empty?
106
121
  end
@@ -114,9 +129,17 @@ module RuboCop
114
129
  def valid_context_using_only_begin?(node)
115
130
  parent = node.parent
116
131
 
117
- node.each_ancestor.any?(&:assignment?) || parent&.post_condition_loop? ||
132
+ valid_begin_assignment?(node) || parent&.post_condition_loop? ||
118
133
  parent&.send_type? || parent&.operator_keyword?
119
134
  end
135
+
136
+ def valid_begin_assignment?(node)
137
+ any_ancestor_assignment_node?(node) && !node.children.one?
138
+ end
139
+
140
+ def any_ancestor_assignment_node?(node)
141
+ node.each_ancestor.any?(&:assignment?)
142
+ end
120
143
  end
121
144
  end
122
145
  end
@@ -71,6 +71,10 @@ module RuboCop
71
71
  elsif hash_without_braces?(return_node.first_argument)
72
72
  add_braces(corrector, return_node.first_argument)
73
73
  end
74
+ if return_node.splat_argument?
75
+ first_argument = return_node.first_argument
76
+ corrector.replace(first_argument, first_argument.source.gsub(/\A\*/, ''))
77
+ end
74
78
 
75
79
  keyword = range_with_surrounding_space(range: return_node.loc.keyword,
76
80
  side: :right)
@@ -11,7 +11,7 @@ module RuboCop
11
11
  # presence of a method name clash with an argument or a local
12
12
  # variable.
13
13
  #
14
- # * Calling an attribute writer to prevent an local variable assignment.
14
+ # * Calling an attribute writer to prevent a local variable assignment.
15
15
  #
16
16
  # Note, with using explicit self you can only send messages with public or
17
17
  # protected scope, you cannot send private messages this way.
@@ -144,8 +144,12 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def on_argument(node)
147
- name, = *node
148
- @local_variables_scopes[node] << name
147
+ if node.mlhs_type?
148
+ on_args(node)
149
+ else
150
+ name, = *node
151
+ @local_variables_scopes[node] << name
152
+ end
149
153
  end
150
154
 
151
155
  def allow_self(node)
@@ -150,7 +150,7 @@ module RuboCop
150
150
 
151
151
  def preferred_delimiters
152
152
  config.for_cop('Style/PercentLiteralDelimiters') \
153
- ['PreferredDelimiters']['%r'].split('')
153
+ ['PreferredDelimiters']['%r'].chars
154
154
  end
155
155
 
156
156
  def correct_delimiters(node, corrector)
@@ -39,23 +39,23 @@ module RuboCop
39
39
  # rescue SomeException
40
40
  # handle_error
41
41
  # end
42
- class RescueModifier < Cop
42
+ class RescueModifier < Base
43
43
  include Alignment
44
+ include RangeHelp
44
45
  include RescueNode
46
+ extend AutoCorrector
45
47
 
46
48
  MSG = 'Avoid using `rescue` in its modifier form.'
47
49
 
48
50
  def on_resbody(node)
49
51
  return unless rescue_modifier?(node)
50
52
 
51
- add_offense(node.parent)
52
- end
53
+ rescue_node = node.parent
54
+ add_offense(rescue_node) do |corrector|
55
+ parenthesized = parenthesized?(rescue_node)
53
56
 
54
- def autocorrect(node)
55
- parenthesized = parenthesized?(node)
56
- lambda do |corrector|
57
- corrector.replace(node, corrected_block(node, parenthesized))
58
- ParenthesesCorrector.correct(corrector, node.parent) if parenthesized
57
+ correct_rescue_block(corrector, rescue_node, parenthesized)
58
+ ParenthesesCorrector.correct(corrector, rescue_node.parent) if parenthesized
59
59
  end
60
60
  end
61
61
 
@@ -65,17 +65,20 @@ module RuboCop
65
65
  node.parent && parentheses?(node.parent)
66
66
  end
67
67
 
68
- def corrected_block(node, parenthesized)
68
+ def correct_rescue_block(corrector, node, parenthesized)
69
69
  operation, rescue_modifier, = *node
70
70
  *_, rescue_args = *rescue_modifier
71
71
 
72
72
  node_indentation, node_offset = indentation_and_offset(node, parenthesized)
73
73
 
74
- "begin\n" \
75
- "#{operation.source.gsub(/^/, node_indentation)}" \
76
- "\n#{node_offset}rescue\n" \
77
- "#{rescue_args.source.gsub(/^/, node_indentation)}" \
78
- "\n#{node_offset}end"
74
+ corrector.remove(range_between(operation.source_range.end_pos, node.source_range.end_pos))
75
+ corrector.insert_before(operation, "begin\n#{node_indentation}")
76
+ corrector.insert_after(operation, <<~RESCUE_CLAUSE.chop)
77
+
78
+ #{node_offset}rescue
79
+ #{node_indentation}#{rescue_args.source}
80
+ #{node_offset}end
81
+ RESCUE_CLAUSE
79
82
  end
80
83
 
81
84
  def indentation_and_offset(node, parenthesized)