Groovy:如何从AST

时间:2018-05-14 19:24:08

标签: java groovy type-systems static-compilation

我正在使用Groovy来允许用户编写脚本并自定义Java应用程序的某些部分。我正在使用所有用户提供的脚本的静态编译。

我的问题是:如果我的代码希望收到例如一个boolean类型的值作为用户脚本的结果,有没有办法让我检查提供的用户脚本是否总是返回一个布尔值而不实际执行脚本?换句话说,如何访问静态groovy编译器执行的类型推断的结果?我希望能够在编辑脚本内容时告诉用户“嘿,你的脚本并不总是返回一个布尔值”。

2 个答案:

答案 0 :(得分:2)

没有直截了当的方式,但这是可能的。布尔值特别难,因为编译器会很乐意应用各种类型的coersions(例如,将int转换为boolean而不会抱怨)。我遇到了完全相同的问题并执行了以下步骤:

  1. ASTTransformation将返回类型设置为boolean (不是必需的,是半工作早期迭代的工件)
  2. ASTTransformation to meterialize all return statements
  3. TypeCheckingExtension访问ReturnStatements并验证它们的类型为boolean
  4. 使用TypeCheckingExtension
  5. 执行静态类型转换的ASTTransformation

    1:

    ClassCodeVisitorSupport中扩展visitMethod,识别要返回布尔值的所有方法(例如,检查匹配的命名约定)

    returnType的{​​{1}}设置为MethodNode

    2:

    对于与上述相同的方法,请致电ClassHelper.boolean_TYPE

    3:

    扩展org.codehaus.groovy.classgen.ReturnAdder.visitMethod,覆盖AbstractTypeCheckingExtension。此时afterVisitMethod将推断出方法内所有表达式的下限。使用AbstractTypeCheckingExtension子类并覆盖ClassCodeVisitorSupport。使用visitReturnStatement获取推断类型。请注意,这可能与getType(statement.expression)(根据AST的类型)不同。在非布尔类型上调用statement.expression.type

    4:

    延长addStaticTypeError 覆盖StaticTypesTransformation并创建新的newVisitor并在其上调用StaticTypeCheckingVisitor以添加addTypeCheckingExtension

    GitHub项目

    https://github.com/MeneDev/groovy-dsl-building-blocks-enforce-return-type

    它甚至可以作为依赖项重复使用;)

答案 1 :(得分:0)

不是“典型”的常规 - 这是groovy的运行时输入和java的编译时静态输入之间的区别。

例如,以下方法是返回布尔值吗?

def value(v) {
    return v;
}

然而,在2.0版本中,有一个@CompileStatic注释,我认为这会强制在编译时知道所有类型。不知道如何强制你的客户端脚本代码“On”。