Конвейеры Jenkins выполняют код Groovy в стиле продолжения с использованием интерпретатора groovy -cps . Это не ваниль Groovy, которую вы можете выполнить непосредственно в IDE или в Groovy Shell.
Groovy CPS преобразует ваш код для поддержки стиля передачи продолжения и правильного выражения Groovy, например:
a = b = c = 0
преобразуется в нечто, похожее на:
eval(
var("a"),
assign(
eval(
var("b"),
assign(
eval(
var("c"),
assign(0)
)
)
)
)
)
Проблема с этим выражением в интерпретаторе CPS заключается в том, что присвоение не возвращает никакого значения, и, следовательно, null
значение присваивается переменной b
, и то же самое происходит с переменной a
.
Если вы хотите копать глубже в блоке вызовов CPS, вы можете клонировать groovy -cps спроецируйте и напишите простой тестовый пример в классе com.cloudbees.groovy.cps.CpsTransformerTest
.
@Test
void testMultiVariablesInlineCPS() {
def cps = parseCps('''
int a, b, c
a = b = c = 0
''')
println cps
}
Затем вы можете установить точку останова на println cps
и запустить отладчик. Когда вы откроете окно проверки, вы увидите изображение, похожее на это:
В качестве примечания, имейте в виду, что Groovy компилятор также преобразует ваши однострочные назначения при компиляции кода в байт-код. Если вы скомпилируете простой скрипт Groovy, например:
int a, b, c
a = b = c = 0
println "$a $b $c"
, а затем откроете его файл класса в IDE, чтобы декомпилировать байт-код в эквивалент Java, вы увидите что-то вроде этого:
//
// 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[]{"", " ", " ", ""}));
}
}