Pipa Jenkins mengeksekusi kode Groovy dalam gaya kelanjutan-lewat menggunakan juru bahasa -cov . Ini bukan vanilla Groovy yang bisa Anda jalankan langsung di IDE atau di Groovy Shell.
CPS Groovy mengubah kode Anda untuk mendukung gaya passing-kelanjutan dan ekspresi Groovy yang benar seperti:
a = b = c = 0
ditransformasikan menjadi sesuatu yang lebih mirip:
eval(
var("a"),
assign(
eval(
var("b"),
assign(
eval(
var("c"),
assign(0)
)
)
)
)
)
Masalah dengan ungkapan ini dalam interpreter CPS adalah bahwa penugasan tidak mengembalikan nilai apa pun, dan dengan demikian null
nilai akan ditugaskan ke variabel b
, dan hal yang sama terjadi pada variabel a
.
Jika Anda ingin menggali lebih dalam di blok doa CPS, Anda dapat mengkloning proyek groovy-cps dan menulis test case sederhana di com.cloudbees.groovy.cps.CpsTransformerTest
kelas.
@Test
void testMultiVariablesInlineCPS() {
def cps = parseCps('''
int a, b, c
a = b = c = 0
''')
println cps
}
Kemudian Anda bisa meletakkan breakpoint di println cps
dan menjalankan debugger. Saat Anda membuka jendela inspeksi, Anda akan melihat gambar yang mirip dengan ini:
Sebagai catatan, perlu diingat bahwa kompiler Groovy juga mengubah tugas baris tunggal Anda ketika mengkompilasi kode menjadi bytecode. Jika Anda menyusun skrip Groovy sederhana seperti:
int a, b, c
a = b = c = 0
println "$a $b $c"
dan kemudian Anda membuka file kelasnya di IDE untuk mendekompilasi bytecode ke Java, Anda akan melihat sesuatu seperti ini:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import groovy.lang.Binding;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.GStringImpl;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class test extends Script {
public test() {
CallSite[] var1 = $getCallSiteArray();
}
public test(Binding context) {
CallSite[] var2 = $getCallSiteArray();
super(context);
}
public static void main(String... args) {
CallSite[] var1 = $getCallSiteArray();
var1[0].call(InvokerHelper.class, test.class, args);
}
public Object run() {
CallSite[] var1 = $getCallSiteArray();
int a = 0;
int b = 0;
int c = 0;
byte var5 = 0;
return var1[1].callCurrent(this, new GStringImpl(new Object[]{Integer.valueOf(var5), Integer.valueOf(var5), Integer.valueOf(var5)}, new String[]{"", " ", " ", ""}));
}
}