@@ -220,6 +220,22 @@ def find_constant_path(insns, index)
220220 end
221221 end
222222
223+ def find_attr_arguments ( insns , index )
224+ orig_argc = insns [ index ] [ 1 ] [ :orig_argc ]
225+ names = [ ]
226+
227+ current = index - 1
228+ while current >= 0 && names . length < orig_argc
229+ if insns [ current ] . is_a? ( Array ) && insns [ current ] [ 0 ] == :putobject
230+ names . unshift ( insns [ current ] [ 1 ] )
231+ end
232+
233+ current -= 1
234+ end
235+
236+ names if insns [ current ] == [ :putself ] && names . length == orig_argc
237+ end
238+
223239 def index_iseq ( iseq , file_comments )
224240 results = [ ]
225241 queue = [ [ iseq , [ ] ] ]
@@ -324,31 +340,29 @@ def index_iseq(iseq, file_comments)
324340 )
325341 when :opt_send_without_block , :send
326342 case insn [ 1 ] [ :mid ]
327- when :attr_reader
328- # We're going to scan backward finding symbols until we hit a
329- # different instruction. We'll then use that to determine the
330- # receiver. It needs to be self if we're going to understand it.
331- names = [ ]
332- current = index - 1
333-
334- while current >= 0 && names . length < insn [ 1 ] [ :orig_argc ]
335- if insns [ current ] . is_a? ( Array ) && insns [ current ] [ 0 ] == :putobject
336- names . unshift ( insns [ current ] [ 1 ] )
337- end
338-
339- current -= 1
340- end
341-
342- next if insns [ current ] != [ :putself ]
343+ when :attr_reader , :attr_writer , :attr_accessor
344+ names = find_attr_arguments ( insns , index )
345+ next unless names
343346
344347 location = Location . new ( line , 0 )
345348 names . each do |name |
346- results << MethodDefinition . new (
347- current_nesting ,
348- name ,
349- location ,
350- EntryComments . new ( file_comments , location )
351- )
349+ if insn [ 1 ] [ :mid ] != :attr_writer
350+ results << MethodDefinition . new (
351+ current_nesting ,
352+ name ,
353+ location ,
354+ EntryComments . new ( file_comments , location )
355+ )
356+ end
357+
358+ if insn [ 1 ] [ :mid ] != :attr_reader
359+ results << MethodDefinition . new (
360+ current_nesting ,
361+ :"#{ name } =" ,
362+ location ,
363+ EntryComments . new ( file_comments , location )
364+ )
365+ end
352366 end
353367 when :"core#set_method_alias"
354368 # Now we have to validate that the alias is happening with a
@@ -452,19 +466,23 @@ def visit_class(node)
452466 end
453467
454468 def visit_command ( node )
455- if node . message . value == "attr_reader"
469+ case node . message . value
470+ when "attr_reader" , "attr_writer" , "attr_accessor"
471+ comments = comments_for ( node )
456472 location =
457473 Location . new ( node . location . start_line , node . location . start_column )
458474
459475 node . arguments . parts . each do |argument |
460476 next unless argument . is_a? ( SymbolLiteral )
477+ name = argument . value . value . to_sym
461478
462- results << MethodDefinition . new (
463- nesting . dup ,
464- argument . value . value . to_sym ,
465- location ,
466- comments_for ( node )
467- )
479+ if node . message . value != "attr_writer"
480+ results << MethodDefinition . new ( nesting . dup , name , location , comments )
481+ end
482+
483+ if node . message . value != "attr_reader"
484+ results << MethodDefinition . new ( nesting . dup , :"#{ name } =" , location , comments )
485+ end
468486 end
469487 end
470488
0 commit comments