Jenkins-Pipelines führen Groovy-Code im Continuation-Passing-Stil mit dem Groovy-CPS- Interpreter aus. Dies ist kein Vanilla Groovy, den Sie direkt in der IDE oder in der Groovy Shell ausführen können.
Groovy CPS transformiert Ihren Code, um den Continuation-Passing-Stil und den korrekten Groovy-Ausdruck wie folgt zu unterstützen:
a = b = c = 0
verwandelt sich in etwas, das eher so aussieht:
eval(
var("a"),
assign(
eval(
var("b"),
assign(
eval(
var("c"),
assign(0)
)
)
)
)
)
Das Problem mit diesem Ausdruck im CPS-Interpreter besteht darin, dass die Zuweisung keinen nullWert zurückgibt und der Wert daher der Variablen zugewiesen wird b, und dasselbe passiert mit der Variablen a.
Wenn Sie tiefer in den CPS-Aufrufblock eintauchen möchten, können Sie das groovy-cps-Projekt klonen und einen einfachen Testfall in die com.cloudbees.groovy.cps.CpsTransformerTestKlasse schreiben .
@Test
void testMultiVariablesInlineCPS() {
def cps = parseCps('''
int a, b, c
a = b = c = 0
''')
println cps
}
Dann können Sie einen Haltepunkt am setzen println cpsund den Debugger ausführen. Wenn Sie das Inspektionsfenster öffnen, sehen Sie ein Bild ähnlich dem folgenden:

Beachten Sie als Randnotiz, dass der Groovy-Compiler auch Ihre einzeiligen Zuweisungen transformiert, wenn Sie den Code in den Bytecode kompilieren. Wenn Sie ein einfaches Groovy-Skript wie folgt kompilieren:
int a, b, c
a = b = c = 0
println "$a $b $c"
Wenn Sie dann die Klassendatei in der IDE öffnen, um den Bytecode in das Java-Äquivalent zu dekompilieren, wird Folgendes angezeigt:
//
// 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[]{"", " ", " ", ""}));
}
}