functions = new TreeMap<String,StepDescriptor>();
for (StepDescriptor d : StepDescriptor.all()) {
functions.put(d.getFunctionName(), d);
}
}
final StepDescriptor d = functions.get(name);
if (d == null) {
throw new NoSuchMethodError("No such DSL method " + name + " found among " + functions.keySet());
}
final NamedArgsAndClosure ps = parseArgs(d,args);
CpsThread thread = CpsThread.current();
FlowNode an;
// TODO: generalize the notion of Step taking over the FlowNode creation.
// see https://trello.com/c/v6Pbwqxj/13-allowing-steps-to-build-flownodes
boolean hack = d instanceof ParallelStep.DescriptorImpl;
if (ps.body == null && !hack) {
an = new StepAtomNode(exec, d, thread.head.get());
// TODO: use CPS call stack to obtain the current call site source location. See JENKINS-23013
thread.head.setNewHead(an);
} else {
an = new StepStartNode(exec, d, thread.head.get());
thread.head.setNewHead(an);
}
final CpsStepContext context = new CpsStepContext(d,thread,handle,an,ps.body);
Step s;
boolean sync;
try {
d.checkContextAvailability(context);
s = d.newInstance(ps.namedArgs);
StepExecution e = s.start(context);
thread.setStep(e);
sync = e.start();
} catch (Exception e) {
if (e instanceof MissingContextVariableException)