[前][次][番号順一覧][スレッド一覧]

ruby-changes:38593

From: ko1 <ko1@a...>
Date: Fri, 29 May 2015 17:40:11 +0900 (JST)
Subject: [ruby-changes:38593] ko1:r50674 (trunk): * tool/make_hgraph.rb: added.

ko1	2015-05-29 17:39:50 +0900 (Fri, 29 May 2015)

  New Revision: 50674

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50674

  Log:
    * tool/make_hgraph.rb: added.

  Added files:
    trunk/tool/make_hgraph.rb
  Modified files:
    trunk/ChangeLog
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50673)
+++ ChangeLog	(revision 50674)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri May 29 17:39:14 2015  Koichi Sasada  <ko1@a...>
+
+	* tool/make_hgraph.rb: added.
+
 Fri May 29 14:39:00 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* compile.c (iseq_compile_each): out of range NTH_REF is always
Index: tool/make_hgraph.rb
===================================================================
--- tool/make_hgraph.rb	(revision 0)
+++ tool/make_hgraph.rb	(revision 50674)
@@ -0,0 +1,95 @@ https://github.com/ruby/ruby/blob/trunk/tool/make_hgraph.rb#L1
+#
+# Make dot file of internal class/module hierarchy graph.
+#
+
+require 'objspace'
+
+module ObjectSpace
+  def self.object_id_of obj
+    if obj.kind_of?(ObjectSpace::InternalObjectWrapper)
+      obj.internal_object_id
+    else
+      obj.object_id
+    end
+  end
+
+  T_ICLASS_NAME = {}
+
+  def self.class_name_of klass
+    case klass
+    when Class, Module
+      # (singleton class).name returns nil
+      klass.name || klass.inspect
+    when InternalObjectWrapper # T_ICLASS
+      if klass.type == :T_ICLASS
+        "#<I:#{class_name_of(ObjectSpace.internal_class_of(klass))}>"
+      else
+        klass.inspect
+      end
+    else
+      klass.inspect
+    end
+  end
+
+  def self.module_refenreces klass
+    h = {} # object_id -> [klass, class_of, super]
+    stack = [klass]
+    while klass = stack.pop
+      obj_id = ObjectSpace.object_id_of(klass)
+      next if h.has_key?(obj_id)
+      cls = ObjectSpace.internal_class_of(klass)
+      sup = ObjectSpace.internal_super_of(klass)
+      stack << cls if cls
+      stack << sup if sup
+      h[obj_id] = [klass, cls, sup].map{|e| ObjectSpace.class_name_of(e)}
+    end
+    h.values
+  end
+
+  def self.module_refenreces_dot klass
+    result = []
+    rank_set = {}
+
+    result << "digraph mod_h {"
+    # result << "  rankdir=LR;"
+    module_refenreces(klass).each{|(m, k, s)|
+      # next if /singleton/ =~ m
+      result << "#{m.dump} -> #{s.dump} [label=\"super\"];"
+      result << "#{m.dump} -> #{k.dump} [label=\"klass\"];"
+
+      unless rank = rank_set[m]
+        rank = rank_set[m] = 0
+      end
+      unless rank_set[s]
+        rank_set[s] = rank + 1
+      end
+      unless rank_set[k]
+        rank_set[k] = rank
+      end
+    }
+
+    rs = [] # [[mods...], ...]
+    rank_set.each{|m, r|
+      rs[r] = [] unless rs[r]
+      rs[r] << m
+    }
+
+    rs.each{|ms|
+      result << "{rank = same; #{ms.map{|m| m.dump}.join(", ")}};"
+    }
+    result << "}"
+    result.join("\n")
+  end
+
+  def self.module_refenreces_image klass, file
+    dot = module_refenreces_dot(klass)
+    img = nil
+    IO.popen("dot -Tpng", 'r+'){|io|
+      #
+      io.puts dot
+      io.close_write
+      img = io.read
+    }
+    open(File.expand_path(file), 'w+'){|f| f.puts img}
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]