@@ -20,11 +20,12 @@ def initialize(line, column)
2020
2121 # This entry represents a class definition using the class keyword.
2222 class ClassDefinition
23- attr_reader :nesting , :name , :location , :comments
23+ attr_reader :nesting , :name , :superclass , : location, :comments
2424
25- def initialize ( nesting , name , location , comments )
25+ def initialize ( nesting , name , superclass , location , comments )
2626 @nesting = nesting
2727 @name = name
28+ @superclass = superclass
2829 @location = location
2930 @comments = comments
3031 end
@@ -182,7 +183,7 @@ def find_constant_path(insns, index)
182183 if insn . is_a? ( Array ) && insn [ 0 ] == :opt_getconstant_path
183184 # In this case we're on Ruby 3.2+ and we have an opt_getconstant_path
184185 # instruction, so we already know all of the symbols in the nesting.
185- insn [ 1 ]
186+ [ index - 1 , insn [ 1 ] ]
186187 elsif insn . is_a? ( Symbol ) && insn . match? ( /\A label_\d +/ )
187188 # Otherwise, if we have a label then this is very likely the
188189 # destination of an opt_getinlinecache instruction, in which case
@@ -195,7 +196,9 @@ def find_constant_path(insns, index)
195196 index -= 1
196197 end
197198
198- names
199+ [ index - 1 , names ]
200+ else
201+ [ index , [ ] ]
199202 end
200203 end
201204
@@ -213,7 +216,24 @@ def index_iseq(iseq, file_comments)
213216 _ , name , class_iseq , flags = insn
214217 next_nesting = current_nesting . dup
215218
216- if ( nesting = find_constant_path ( insns , index - 2 ) )
219+ # This is the index we're going to search for the nested constant
220+ # path within the declaration name.
221+ constant_index = index - 2
222+
223+ # This is the superclass of the class being defined.
224+ superclass = [ ]
225+
226+ # If there is a superclass, then we're going to find it here and
227+ # then update the constant_index as necessary.
228+ if flags & VM_DEFINECLASS_FLAG_HAS_SUPERCLASS > 0
229+ constant_index , superclass = find_constant_path ( insns , index - 1 )
230+
231+ if superclass . empty?
232+ raise NotImplementedError , "superclass with non constant path"
233+ end
234+ end
235+
236+ if ( _ , nesting = find_constant_path ( insns , constant_index ) )
217237 # If there is a constant path in the class name, then we need to
218238 # handle that by updating the nesting.
219239 next_nesting << ( nesting << name )
@@ -243,6 +263,7 @@ def index_iseq(iseq, file_comments)
243263 results << ClassDefinition . new (
244264 next_nesting ,
245265 name ,
266+ superclass ,
246267 location ,
247268 EntryComments . new ( file_comments , location )
248269 )
@@ -299,9 +320,23 @@ def visit_class(node)
299320 location =
300321 Location . new ( node . location . start_line , node . location . start_column )
301322
323+ superclass =
324+ if node . superclass
325+ visited = visit ( node . superclass )
326+
327+ if visited == [ [ ] ]
328+ raise NotImplementedError , "superclass with non constant path"
329+ end
330+
331+ visited
332+ else
333+ [ ]
334+ end
335+
302336 results << ClassDefinition . new (
303337 nesting . dup ,
304338 names . last ,
339+ superclass ,
305340 location ,
306341 comments_for ( node )
307342 )
@@ -315,14 +350,7 @@ def visit_const_ref(node)
315350 end
316351
317352 def visit_const_path_ref ( node )
318- names =
319- if node . parent . is_a? ( ConstPathRef )
320- visit ( node . parent )
321- else
322- [ visit ( node . parent ) ]
323- end
324-
325- names << node . constant . value . to_sym
353+ visit ( node . parent ) << node . constant . value . to_sym
326354 end
327355
328356 def visit_def ( node )
@@ -376,7 +404,7 @@ def visit_statements(node)
376404 end
377405
378406 def visit_var_ref ( node )
379- node . value . value . to_sym
407+ [ node . value . value . to_sym ]
380408 end
381409 end
382410
0 commit comments