krótka odpowiedź brzmi: nie możesz. długie odpowiedź brzmi:
w zależności od tego, co trzeba kod, można być może uciec z
// file: example1.groovy
def a = { it.twice() }
println a.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return it.twice() }
BUT
trzeba będzie kod źródłowy skryptu dostępnego w ścieżce klasy w czasie wykonywania, jak wyjaśniono w
groovy.lang.MetaClass # getClassNode()
„Pobiera odwołanie do oryginalnego AST dla metaklasą jeśli jest dostępny w czasie wykonywania
@return The oryginalnym AST lub null, jeśli nie może być powrócił”
I
się tekstu trik naprawdę nie zwracają ten sam kod, tylko jak kod reprezentacji AST, jak może być widział w tym skrypcie
// file: example2.groovy
def b = {p-> p.twice() * "p"}
println b.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return (p.twice() * p) }
nadal, może to być przydatne, jak to jest, jeśli chcesz po prostu wziąć szybki rzut oka
, a jeśli mają zbyt wiele czasu na swoje ręce i nie wiedzą, co zrobić można napisać własną org.codehaus.groovy.ast.GroovyCodeVisitor
do całkiem wydrukować to
OR, tylko ukraść istniejący jak 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")
// })
// })
teraz.
jeśli chcesz oryginalny, dokładny, runnable Kodeksu ... jesteś pecha
To znaczy, można użyć wiersza źródło informacji, ale ostatni raz sprawdzałem, to nie było naprawdę zachęcając prawo
// 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.
numery linii shuld być przynajmniej blisko oryginalnego kodu chociaż
To prawdopodobnie nie będzie pasował do Twojego okoliczności, ale może być w stanie iść w drugą stronę. Od GroovyShell.evaluate() wykonuje String (z odpowiednimi powiązaniami var), co jeśli zamknięcie było po prostu ciągiem znaków? –