Liquor Java 语言执行器。支持完整的 Java 语法及各版本特性（具体看运行时版本）。执行器由“三个”关键类及两个工具组成：



| 部件                        | 描述                                                                  | 
| ---------------- | --------------------------------------- |
| CodeSpec              | 代码声明                                                              | 
| LiquorEvaluator       | 执行器。用于管理 CodeSpec 的编译、缓存               |
| Execable                 | 可执行接口。由 CodeSpec 编译后会产生                 |
| | |
| [::Scripts](/article/852)       | 执行器的脚本工具                            |
| [::Exprs](/article/851)          |  执行器的表达式工具                         |

### 1、CodeSpec 类结构及编译效果


| 字段               | 描述                 | 
| ----------- | ------------ |
| code              | 声明代码（一般包含，代码头？和代码主体！）           | 
| imports          | 声明类头导入     | 
| parameters     | 声明参数           | 
| returnType      | 声明返回类型     | 
| cached           | 声明缓存的（默认为 true）。<mark>当代码无限变化时，不能用缓存（否则有 OOM 风险）</mark>     | 


CodeSpec 会被编译成一个静态函数（并转换为 Execable）。格式效果如下：

```java
#imports#

public class Execable$... {
    public static #returnType# _main$(#parameters#) {
        #code#
    }
}
```

其中 `#imports#`，由三部分组成：

* `LiquorEvaluator:globalImports`（一般不用，避免产生相互干扰。特殊定制时可用）
* `CodeSpec:imports`
* `code:header-imports` （代码头部的 import 语句）

其中 `CodeSpec:code` + `CodeSpec:imports` 会形成：

* 缓存键，<mark>用于缓存控制</mark>


### 2、LiquorEvaluator 接口及 eval 过程分解（使用时以 Scripts 和 Exprs 为主）

方法列表：

| 方法                         | 描述                 | 
| ----------------- | ------------ |
| printable(bool)            | 配置可打印的     | 
| compile(codeSpec)      | 预编译             | 
| eval(codeSpec, args)    | 执行                | 


eval 过程分解：

<img src="/img/ac317f9479cf46a99e5cc3eff481d9e0.png" width="400px" />





### 3、Exprs 代码展示（Scripts 类似）

也可以定制特定业务的体验工具。比如，Exprs 在接收 CodeSpec 时会自动声明 returnType。

```java
public interface Exprs {
    /**
     * 编译
     *
     * @param code 代码
     */
    static Execable compile(String code) {
        return compile(new CodeSpec(code));
    }

    /**
     * 编译
     *
     * @param codeSpec 代码声明
     */
    static Execable compile(CodeSpec codeSpec) {
        //强制有估评结果
        if (codeSpec.getReturnType() == null) {
            codeSpec.returnType(Object.class);
        }

        return LiquorEvaluator.getInstance().compile(codeSpec);
    }

    /**
     * 批量编译
     *
     * @param codeSpecs 代码声明集合
     * @since 1.3.8
     */
    static Map<CodeSpec, Execable> compile(List<CodeSpec> codeSpecs) {
        for (CodeSpec codeSpec : codeSpecs) {
            //强制有估评结果
            if (codeSpec.getReturnType() == null) {
                codeSpec.returnType(Object.class);
            }
        }

        return LiquorEvaluator.getInstance().compile(codeSpecs);
    }


    /**
     * 执行
     *
     * @param code 代码
     */
    static Object eval(String code) {
        return eval(new CodeSpec(code), Collections.emptyMap());
    }

    /**
     * 执行
     *
     * @param code    代码
     * @param context 执行参数
     */
    static Object eval(String code, Map<String, Object> context) {
        assert context != null;

        CodeSpec codeSpec = new CodeSpec(code).parameters(context);

        return eval(codeSpec, context);
    }

    /**
     * 执行
     *
     * @param codeSpec 代码声明
     */
    static Object eval(CodeSpec codeSpec) {
        return eval(codeSpec, Collections.emptyMap());
    }

    /**
     * 执行
     *
     * @param codeSpec 代码声明
     * @param context  执行参数
     */
    static Object eval(CodeSpec codeSpec, Map<String, Object> context) {
        //强制有估评结果
        if (codeSpec.getReturnType() == null) {
            codeSpec.returnType(Object.class);
        }

        return LiquorEvaluator.getInstance().eval(codeSpec, context);
    }
}
```




