简短的回答是你不能。长答案是:
根据您需要代码的目的,您也许可以逃脱
// file: example1.groovy
def a = { it.twice() }
println a.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return it.twice() }
但是
您将需要在类路径 AT RUNTIME 中可用的脚本源代码,如
中所述
groovy.lang.MetaClass#getClassNode()
"获取对原始的引用
MetaClass 的 AST(如果是)
在运行时可用
@return
原始 AST 或 null 如果不能
归还”
与
text 技巧并没有真正返回相同的代码,只是一个类似于 AST 表示的代码,正如可以在这个脚本中看到的那样
// file: example2.groovy
def b = {p-> p.twice() * "p"}
println b.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return (p.twice() * p) }
不过,如果您只是想快速浏览一下,它可能会很有用
而且,如果您手头有太多时间并且不知道该做什么,您可以编写自己的org.codehaus.groovy.ast.GroovyCodeVisitor 来漂亮地打印它
或者,偷一个现有的,比如groovy.inspect.swingui.AstNodeToScriptVisitor
// file: example3.groovy
def c = {w->
[1,2,3].each {
println "$it"
(1..it).each {x->
println 'this seems' << ' somewhat closer' << ''' to the
original''' << " $x"
}
}
}
def node = c.metaClass.classNode.getDeclaredMethods("doCall")[0].code
def writer = new StringWriter()
node.visit new groovy.inspect.swingui.AstNodeToScriptVisitor(writer)
println writer
// prints: return [1, 2, 3].each({
// this.println("$it")
// return (1.. it ).each({ java.lang.Object x ->
// return this.println('this seems' << ' somewhat closer' << ' to the \n original' << " $x")
// })
// })
现在。
如果您想要原始、准确、可运行的代码......那你就走运了
我的意思是,您可以使用源代码行信息,但上次我检查时,并没有真正让它们正确
// file: example1.groovy
....
def code = a.metaClass.classNode.getDeclaredMethods("doCall")[0].code
println "$code.lineNumber $code.columnNumber $code.lastLineNumber $code.lastColumnNumber"
new File('example1.groovy').readLines()
... etc etc you get the idea.
行号应该至少接近原始代码