自分で書かなければならないようですが、ソースを解析してくれるRuby のS-expressionsにアクセスできるので、これは大きな問題ではありません。したがって、次のようにすることができます。
require 'ripper'
def parse_sexp( sexp, stack=[] )
case sexp[0]
when :module
name = sexp[1][1][1]
line_number = sexp[1][1][2][0]
parse_sexp(sexp[2], stack+[sexp[0], sexp[1][1][1]])
puts "#{line_number}: Module: #{name}\n"
when :class
name = sexp[1][1][1]
line_number = sexp[1][1][2][0]
parse_sexp(sexp[3], stack+[sexp[0], sexp[1][1][1]])
puts "#{line_number}: Class: #{stack.last}::#{name}\n"
when :def
name = sexp[1][1]
line_number = sexp[1][2][0]
parse_sexp(sexp[3], stack+[sexp[0], sexp[1][1]])
puts "#{line_number}: Method: #{stack.last}##{name}\n"
else
if sexp.kind_of?(Array)
sexp.each { |s| parse_sexp(s,stack) if s.kind_of?(Array) }
end
end
end
sexp = Ripper.sexp(open 'prog.rb')
parse_sexp(sexp)
Prog.rb は次のとおりです。
$ cat -n prog.rb
1 module M1
2 class C1
3 def m1c1
4 a="test"
5 puts "hello"
6 return a if a.empty?
7 puts "hello2"
8 a
9 end
10 end
11 class C2 < C3
12 def m1c2
13 puts "hello"
14 end
15 end
16 class C3
17 end
18 end
あなたが得るものは次のとおりです。
#line_number #entity
3: Method: C1#m1c1
2: Class: M1::C1
12: Method: C2#m1c2
11: Class: M1::C2
16: Class: M1::C3
1: Module: M1
したがって、テンプレートをカスタマイズし、同じ配列で使用可能なパラメーターを抽出するだけで済みます。
#irb > pp Ripper.sexp("def method(param1);nil; end")
...[:def,
[:@ident, "method", [1, 4]],
[:paren,
[:params, [[:@ident, "param1", [1, 11]]]...
少し難しい作業は、返されたものを見つけることですが、それでも実行可能です。最後にある間に s を探し、それ:return
をメソッドの最後のステートメントに追加します。:def
stack
最後に、これらのコメントをソース ファイルの適切な行の上に置きます。