Các đường ống Jenkins thực thi mã Groovy theo kiểu truyền tiếp tục bằng trình thông dịch Groovy -cps . Đây không phải là vanilla Groovy, bạn có thể thực thi trực tiếp trong IDE hoặc trong Groovy Shell.
Groovy CPS chuyển đổi mã của bạn để hỗ trợ kiểu chuyển tiếp và biểu thức Groovy chính xác như:
a = b = c = 0
được chuyển đổi thành một cái gì đó trông giống như:
eval(
var("a"),
assign(
eval(
var("b"),
assign(
eval(
var("c"),
assign(0)
)
)
)
)
)
Vấn đề với biểu thức này trong trình thông dịch CPS là phép gán không trả về bất kỳ giá trị nào và do đó null
giá trị được gán cho biến b
và điều tương tự xảy ra với biến a
.
Nếu bạn muốn đào sâu hơn trong khối yêu cầu CPS, bạn có thể sao chép dự án Groovy-cps và viết một trường hợp thử nghiệm đơn giản trong com.cloudbees.groovy.cps.CpsTransformerTest
lớp.
@Test
void testMultiVariablesInlineCPS() {
def cps = parseCps('''
int a, b, c
a = b = c = 0
''')
println cps
}
Sau đó, bạn có thể đặt một điểm dừng tại println cps
và chạy trình gỡ lỗi. Khi bạn mở cửa sổ kiểm tra, bạn sẽ thấy hình ảnh tương tự như thế này:
Lưu ý phụ, hãy nhớ rằng trình biên dịch Groovy cũng chuyển đổi các phép gán dòng đơn của bạn khi biên dịch mã thành mã byte. Nếu bạn biên dịch một tập lệnh Groovy đơn giản như:
int a, b, c
a = b = c = 0
println "$a $b $c"
và sau đó bạn mở tệp lớp của nó trong IDE để dịch ngược mã byte thành tương đương Java, bạn sẽ thấy một cái gì đó như thế này:
//
// 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[]{"", " ", " ", ""}));
}
}