@Nullable @Override public Object invoke(@Nullable Object proxy, @NotNull Method method, Object[] args) throws Throwable { if (stack.get().size() > MAX_STACK_DEPTH) { in.error("Stack consists of the following Lambda types: "); for (DollarLambda stackEntry : stack.get()) { in.error(stackEntry.lambda.getClass() + ":" + stackEntry.meta); } throw new LambdaRecursionException(stack.get().size()); } try { if (proxy == null) { return null; } else if (Object.class == method.getDeclaringClass()) { String name = method.getName(); if ("equals".equals(name)) { return execute().equals(args[0]); } else if ("hashCode".equals(name)) { return execute().hashCode(); } else if ("toString".equals(name)) { return execute().toString(); } else { throw new IllegalStateException(String.valueOf(method)); } } else if (method.getName().equals("dynamic")) { return true; } else if (method.getName().equals("_unwrap")) { return proxy; // return lambda.pipe(in)._unwrap(); } else if (method.getName().equals("_fix")) { if (fixable) { if (args.length == 1) { return lambda.pipe(DollarFactory.fromValue(args[0]))._fix((Boolean) args[0]); } else { return lambda .pipe(DollarFactory.fromValue(args[1])) ._fix((int) args[0], (Boolean) args[1]); } } else { return proxy; } } else if (method.getName().equals("_fixDeep")) { if (fixable) { if (args == null || args.length == 0) { return lambda.pipe(DollarFactory.fromValue(false))._fixDeep(); } else { return lambda.pipe(DollarFactory.fromValue(args[0]))._fixDeep((Boolean) args[0]); } } else { return proxy; } } else if (method.getName().equals("getMetaAttribute")) { return meta.get(args[0].toString()); } else if (method.getName().equals("setMetaAttribute")) { meta.put(String.valueOf(args[0]), String.valueOf(args[1])); return null; } else if (method.getName().equals("$listen")) { String listenerId = UUID.randomUUID().toString(); if (args.length == 2) { listenerId = String.valueOf(args[1]); } listeners.put(listenerId, (Pipeable) args[0]); return DollarStatic.$(listenerId); } else if (method.getName().equals("$notify")) { if (notifyStack.get().contains(this)) { // throw new IllegalStateException("Recursive notify loop detected"); return proxy; } notifyStack.get().add(this); final var value = execute(); for (Pipeable listener : listeners.values()) { listener.pipe(value); } notifyStack.get().remove(this); return proxy; } else if (method.getName().equals("$remove")) { //noinspection SuspiciousMethodCalls listeners.remove(args[0]); return args[0]; } else if (method.getName().equals("hasErrors")) { return false; } else if (method.getName().equals("$copy") || method.getName().equals("copy")) { return proxy; } else { // System.err.println(method); var out = execute(); if (out == null) { return null; } try { stack.get().add(this); return method.invoke(out, args); } finally { stack.get().remove(stack.get().size() - 1); } } } catch (InvocationTargetException e) { throw e.getCause(); } }
public var execute() throws Exception { return executor.executeNow(() -> lambda.pipe(in)).get(); }