Guest User

Untitled

a guest
Oct 18th, 2013
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. require 'pp'
  2.  
  3. def parse_class_info(instruction_sequence)
  4.   classes = []
  5.  
  6.   find_classes = proc do |instructions, parent, index, parent_class|
  7.     next unless instructions.is_a? Array
  8.     if instructions[0] == :defineclass
  9.       _, class_name, class_info = instructions
  10.       class_name = :"#{parent_class}::#{class_name}" if parent_class
  11.       info = { type: class_info[5][/\<([^:]+)/, 1].to_sym, name: class_name }
  12.       class_body = class_info[13]
  13.       if index
  14.         instruction, argument = parent[index - 3]
  15.         info[:super_class] = argument if instruction == :getconstant
  16.       end
  17.       classes << info
  18.       class_body.each {|instruction| find_classes.(instruction, class_body, nil, class_name) }
  19.     else
  20.       instructions.each_with_index {|instruction, i| find_classes.(instruction, instructions, i, parent_class) }
  21.     end
  22.   end
  23.  
  24.   find_classes.(instruction_sequence.to_a, nil)
  25.  
  26.   classes
  27. end
  28.  
  29. file_contents = <<-RUBY
  30. class TestModule < SuperClass
  31.   foo
  32. end
  33.  
  34. module TestMod
  35.   class TestClass < Super
  36.     class AnotherNestedClass
  37.     end
  38.   end
  39. end
  40.  
  41. class TestClass2
  42.   foo_bar
  43. end
  44. RUBY
  45.  
  46. pp parse_class_info RubyVM::InstructionSequence.compile(file_contents)
  47.  
  48. #[{:type=>:class, :name=>:TestModule, :super_class=>:SuperClass},
  49. # {:type=>:module, :name=>:TestMod},
  50. # {:type=>:class, :name=>:"TestMod::TestClass"},
  51. # {:type=>:class, :name=>:"TestMod::TestClass::AnotherNestedClass"},
  52. # {:type=>:class, :name=>:TestClass2}]
Advertisement
Add Comment
Please, Sign In to add comment