1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* tool/make_hgraph.rb: added.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50674 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2015-05-29 08:39:50 +00:00
parent 451fe269e5
commit 7fd053a018
2 changed files with 99 additions and 0 deletions

View file

@ -1,3 +1,7 @@
Fri May 29 17:39:14 2015 Koichi Sasada <ko1@atdot.net>
* tool/make_hgraph.rb: added.
Fri May 29 14:39:00 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* compile.c (iseq_compile_each): out of range NTH_REF is always

95
tool/make_hgraph.rb Normal file
View file

@ -0,0 +1,95 @@
#
# 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