public static Expression invokeGenerated(
      CodegenContext ctx,
      SerializableSupplier<Expression> groupExpressionsGenerator,
      String methodPrefix) {
    List<Expression> cutPoint =
        ExpressionUtils.extractCapturedExpressions(groupExpressionsGenerator);
    return invokeGenerated(
        ctx, new HashSet<>(cutPoint), groupExpressionsGenerator.get(), methodPrefix, false);
  }
@Test
  public void testInvokeGenerated() throws Exception {
    CodegenContext ctx = new CodegenContext();
    String clsName = "TestInvokeGenerated";
    ctx.setClassName(clsName);
    ctx.setPackage("test");
    Expression expression =
        ExpressionOptimizer.invokeGenerated(
            ctx, () -> new Return(new Add(Literal.ofInt(1), Literal.ofInt(2))), "test");
    Code.ExprCode methodCode = new Return(expression).genCode(ctx);
    ctx.addMethod("add", methodCode.code(), int.class);
    String classCode = ctx.genCode();
    ClassLoader classLoader =
        new CodeGenerator(getClass().getClassLoader())
            .compile(new CompileUnit("test", clsName, classCode));
    Class<?> generatedClass = classLoader.loadClass("test." + clsName);
    {
      Method test = generatedClass.getMethod("add");
      test.setAccessible(true);
      assertEquals(test.invoke(generatedClass.newInstance()), 3);
    }
    {
      // janino generated an static method which take instance of class instead.
      assertTrue(
          Arrays.stream(generatedClass.getDeclaredMethods())
              .anyMatch(m -> m.getName().startsWith("test")));
    }
  }