package com.cloudbees.groovy.cps.impl; import com.cloudbees.groovy.cps.Block; import com.cloudbees.groovy.cps.Continuation; import com.cloudbees.groovy.cps.Env; import com.cloudbees.groovy.cps.Next; import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; /** * Logical operator ({@code &&} and {@code ||}) * * @author Kohsuke Kawaguchi */ public class LogicalOpBlock implements Block { private final Block lhs, rhs; private final boolean and; public LogicalOpBlock(Block lhs, Block rhs, boolean and) { this.lhs = lhs; this.rhs = rhs; this.and = and; } public Next eval(Env e, Continuation k) { return new ContinuationImpl(e,k).then(lhs,e,decide); } class ContinuationImpl extends ContinuationGroup { final Continuation k; final Env e; ContinuationImpl(Env e, Continuation k) { this.e = e; this.k = k; } public Next decide(Object lhs) { boolean v = DefaultTypeTransformation.castToBoolean(lhs); if (and) { if (!v) return k.receive(false); // false && ... else return then(rhs,e,k); } else { if (v) return k.receive(true); // true || ... else return then(rhs,e,k); } } private static final long serialVersionUID = 1L; } static final ContinuationPtr decide = new ContinuationPtr(ContinuationImpl.class,"decide"); private static final long serialVersionUID = 1L; }