Solon v3.0.9

Liquor 评估器

</> markdown

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

部件描述
CodeSpec代码申明
LiquorEvaluator评估器。用于管理 CodeSpec 的编译、缓存
Execable可执行接口。由 CodeSpec 编译后会产生
::Scripts评估器的脚本工具
::Exprs评估器的表达式工具

1、CodeSpec 类结构及编译效果

字段描述
code申明代码(一般包含,代码头?和代码主体!)
imports申明类头导入
parameters申明参数
returnType申明返回类型
cached申明缓存的(默认为 true)。当代码无限变化时,不能用缓存(否则有 OOM 风险)

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

#imports#

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

其中 #imports#,由三部分组成:

  • LiquorEvaluator:globalImports(一般不用,避免产生相互干扰。特殊定制时可用)
  • CodeSpec:imports
  • code:header-imports (代码头部的 import 语句)

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

  • 缓存键,用于缓存控制

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

方法列表:

方法描述
printable(bool)配置可打印的
compile(codeSpec)预编译
eval(codeSpec, args)评估

eval 过程分解:

3、Exprs 代码展示(Scripts 类似)

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

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) throws InvocationTargetException {
        return eval(new CodeSpec(code));
    }

    /**
     * 评估
     *
     * @param codeSpec 代码申明
     * @param args     执行参数
     */
    static Object eval(CodeSpec codeSpec, Object... args) throws InvocationTargetException {
        //强制有估评结果
        if (codeSpec.getReturnType() == null) {
            codeSpec.returnType(Object.class);
        }

        return LiquorEvaluator.getInstance().eval(codeSpec, args);
    }

    /**
     * 评估
     *
     * @param code 代码
     */
    static Object eval(String code, Map<String, Object> context) throws InvocationTargetException {
        assert context != null;

        CodeSpec codeSpec = new CodeSpec(code);
        Object[] args = codeSpec.bind(context);

        return eval(codeSpec, args);
    }
}