private boolean checkParams(Object... vars) { if (vars == null || vars.length == 0) { if (freeVarsNumber != 0) throw new WrongClosureInvocationException("Closure invoked without vars instead of the expected " + freeVarsNumber); if (curriedVars == null && argsList == null) return true; } if (freeVarsNumber != vars.length) throw new WrongClosureInvocationException("Closure invoked with " + vars.length + " vars instead of the expected " + freeVarsNumber); if (isClosedOnFreeVar()) checkClosedType(vars[0]); return false; }
/** * Binds an object to this closure. * @param closed The object that has to be bound to this closure * @param closedClass The actual class of the proxied object * @return An instance of the closedClass that is actually a proxy used to register all the invocation on the closed object */ public <T> T of(Object closed, Class<T> closedClass) { setClosed(closed); return createProxyClosure(this, closedClass); }
/** * Curry this closure by fixing one of its free variable to a given value. * @param curry The value to which the free variable should be curry * @param position The 1-based position of the variable to which apply the curry operation * @return A Closure having a free variable less than this one since one of them has been fixed to the given value * @throws IllegalArgumentException if this closure doesn't have a free variable in the specified position */ public Closure curry(Object curry, int position) throws IllegalArgumentException { return curry(new Closure(), curry, position); }
private void bindInvocation(Invokable invokable, Object[] args) { invokables.add(invokable); if (args != null) for (Object arg : args) { if (getClosureVarType(arg).isClosureVarPlaceholder()) freeVarsNumber++; } argsList.add(args); }
/** * Creates a closure with three free variables and binds it to the current thread * @param type1 The type of the first free variable of the newly created closure * @param type2 The type of the second free variable of the newly created closure * @param type3 The type of the third free variable of the newly created closure * @return The newly created closure */ public static <A, B, C> Closure3<A, B, C> closure(Class<A> type1, Class<B> type2, Class<C> type3) { return createClosure(type1, type2, type3); }
/** * Invokes this closure once by applying the given triple of variables to it. * @param var1 The first variable used to invoke this closure * @param var2 The second variable used to invoke this closure * @param var3 The third variable used to invoke this closure * @return The result of the closure invocation */ public Object apply(A var1, B var2, C var3) { return closeOne(var1, var2, var3); }
/** * Invoke this closure * @return The result of the closure invocation */ public Object apply() { return closeOne(); }
/** * {@inheritDoc} */ public T exec(Object ... args) { return (T)closure.closeOne(args); } }
/** * Binds a free variable of the given class to the this closure. * @param closedClass The type of the free variable to be bound to this closure * @return A proxy of the same class of the passed class used to register all the invocation on the closed object */ public <T> T of(Class<T> closedClass) { return of(closedClass, closedClass); }
/** * Creates a closure with four free variables and binds it to the current thread * @param type1 The type of the first free variable of the newly created closure * @param type2 The type of the second free variable of the newly created closure * @param type3 The type of the third free variable of the newly created closure * @param type4 The type of the fourth free variable of the newly created closure * @return The newly created closure */ public static <A, B, C, D> Closure4<A, B, C, D> closure(Class<A> type1, Class<B> type2, Class<C> type3, Class<D> type4) { return createClosure(type1, type2, type3, type4); }