@@ -6,6 +6,71 @@ module Cop
66 module IndexMethod # rubocop:disable Metrics/ModuleLength
77 RESTRICT_ON_SEND = %i[ each_with_object to_h map collect [] ] . freeze
88
9+ # Internal helper class to hold match data
10+ Captures = ::Struct . new (
11+ :transformed_argname ,
12+ :transforming_body_expr
13+ ) do
14+ def noop_transformation?
15+ transforming_body_expr . lvar_type? && transforming_body_expr . children == [ transformed_argname ]
16+ end
17+ end
18+
19+ # Internal helper class to hold autocorrect data
20+ Autocorrection = ::Struct . new ( :match , :block_node , :leading , :trailing ) do
21+ def self . from_each_with_object ( node , match )
22+ new ( match , node , 0 , 0 )
23+ end
24+
25+ def self . from_to_h ( node , match )
26+ new ( match , node , 0 , 0 )
27+ end
28+
29+ def self . from_map_to_h ( node , match )
30+ if node . block_literal?
31+ strip_trailing_chars = 0
32+ else
33+ map_range = node . children . first . source_range
34+ node_range = node . source_range
35+ strip_trailing_chars = node_range . end_pos - map_range . end_pos
36+ end
37+
38+ new ( match , node . children . first , 0 , strip_trailing_chars )
39+ end
40+
41+ def self . from_hash_brackets_map ( node , match )
42+ new ( match , node . children . last , "#{ node . receiver . source } [" . length , ']' . length )
43+ end
44+
45+ def strip_prefix_and_suffix ( node , corrector )
46+ expression = node . source_range
47+ corrector . remove_leading ( expression , leading )
48+ corrector . remove_trailing ( expression , trailing )
49+ end
50+
51+ def set_new_method_name ( new_method_name , corrector )
52+ range = block_node . send_node . loc . selector
53+ if ( send_end = block_node . send_node . loc . end )
54+ # If there are arguments (only true in the `each_with_object` case)
55+ range = range . begin . join ( send_end )
56+ end
57+ corrector . replace ( range , new_method_name )
58+ end
59+
60+ def set_new_arg_name ( transformed_argname , corrector )
61+ return if block_node . numblock_type?
62+
63+ corrector . replace ( block_node . arguments , "|#{ transformed_argname } |" )
64+ end
65+
66+ def set_new_body_expression ( transforming_body_expr , corrector )
67+ body_source = transforming_body_expr . source
68+ body_source = "{ #{ body_source } }" if transforming_body_expr . hash_type? && !transforming_body_expr . braces?
69+
70+ corrector . replace ( block_node . body , body_source )
71+ end
72+ end
73+
974 def on_block ( node )
1075 on_bad_each_with_object ( node ) do |*match |
1176 handle_possible_offense ( node , match , 'each_with_object' )
@@ -102,71 +167,6 @@ def execute_correction(corrector, node, correction)
102167 correction . set_new_arg_name ( captures . transformed_argname , corrector )
103168 correction . set_new_body_expression ( captures . transforming_body_expr , corrector )
104169 end
105-
106- # Internal helper class to hold match data
107- Captures = ::Struct . new (
108- :transformed_argname ,
109- :transforming_body_expr
110- ) do
111- def noop_transformation?
112- transforming_body_expr . lvar_type? && transforming_body_expr . children == [ transformed_argname ]
113- end
114- end
115-
116- # Internal helper class to hold autocorrect data
117- Autocorrection = ::Struct . new ( :match , :block_node , :leading , :trailing ) do
118- def self . from_each_with_object ( node , match )
119- new ( match , node , 0 , 0 )
120- end
121-
122- def self . from_to_h ( node , match )
123- new ( match , node , 0 , 0 )
124- end
125-
126- def self . from_map_to_h ( node , match )
127- if node . block_literal?
128- strip_trailing_chars = 0
129- else
130- map_range = node . children . first . source_range
131- node_range = node . source_range
132- strip_trailing_chars = node_range . end_pos - map_range . end_pos
133- end
134-
135- new ( match , node . children . first , 0 , strip_trailing_chars )
136- end
137-
138- def self . from_hash_brackets_map ( node , match )
139- new ( match , node . children . last , "#{ node . receiver . source } [" . length , ']' . length )
140- end
141-
142- def strip_prefix_and_suffix ( node , corrector )
143- expression = node . source_range
144- corrector . remove_leading ( expression , leading )
145- corrector . remove_trailing ( expression , trailing )
146- end
147-
148- def set_new_method_name ( new_method_name , corrector )
149- range = block_node . send_node . loc . selector
150- if ( send_end = block_node . send_node . loc . end )
151- # If there are arguments (only true in the `each_with_object` case)
152- range = range . begin . join ( send_end )
153- end
154- corrector . replace ( range , new_method_name )
155- end
156-
157- def set_new_arg_name ( transformed_argname , corrector )
158- return if block_node . numblock_type?
159-
160- corrector . replace ( block_node . arguments , "|#{ transformed_argname } |" )
161- end
162-
163- def set_new_body_expression ( transforming_body_expr , corrector )
164- body_source = transforming_body_expr . source
165- body_source = "{ #{ body_source } }" if transforming_body_expr . hash_type? && !transforming_body_expr . braces?
166-
167- corrector . replace ( block_node . body , body_source )
168- end
169- end
170170 end
171171 end
172172end
0 commit comments