Groovy - 脚本中的类型检查无法按预期工作 [英] Groovy - Type checking in script not working as expected

查看:157
本文介绍了Groovy - 脚本中的类型检查无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Groovy 应用程序,允许用户通过 Groovy 脚本添加自定义行为。我通过 GroovyShell 包含这些脚本,并通过键入Checking Extensions 来检查它们。如何将脚本包含在我的应用程序中的完整代码是:
$ b $ pre $ def $ config $ new CompilerConfiguration
config .addCompilationCustomizers(
新建ASTTransformationCustomizer(TypeChecked)

def shell = new GroovyShell(config)
shell.evaluate(new File(path / to / some / file.groovy ))

这很好。 但是,脚本中的类型检查似乎被严重破坏。例如,我可以包含以下脚本,而不需要来自编译器的任何投诉:

  String test = getTestValue()//自动从Integer转换为String。但为什么? 
println值为$ test//在控制台上显示为值为0
$ b $ private Private Integer getTestValue(){
return 0
}

我甚至可以走得更远。在脚本中创建 class 时,我可以将它分配给 String ,而不会出现任何错误:

  String y = new Test()
println y //在控制台上显示Test @ somenr

class测试{}

其他类型检查执行工作。我还没有发现任何背后的逻辑,所以任何指向正确方向的指针都非常感谢。

解决方案

如果有疑问, DISASM。这是一个类似于你的调用: String x = new T()

  0:invokestatic#17 //方法$ getCallSiteArray:()[Lorg / codehaus / groovy / runtime / callsite / CallSite; 
3:astore_1
4:aload_1
5:ldc#40 // int 1
7:aaload
8:ldc#42 // class T
10:invokeinterface#46,2 // InterfaceMethod org / codehaus / groovy / runtime / callsite / CallSite.callConstructor:(Ljava / lang / Object;)Ljava / lang / Object;
15:invokestatic#52 //方法org / codehaus / groovy / runtime / typehandling / ShortTypeHandling.castToString:(Ljava / lang / Object;)Ljava / lang / String;
18:checkcast#54 // class java / lang / String

所以 是演员的罪魁祸首。这似乎也适用于 @TypeChecked / @CompileStatic


I have a Groovy application in which I allow the user to add custom behavior via Groovy scripts. I include those scripts via GroovyShell and type check them via Type Checking Extensions. The full code of how I include the script in my application is:

def config = new CompilerConfiguration()
config.addCompilationCustomizers(
    new ASTTransformationCustomizer(TypeChecked)
)
def shell = new GroovyShell(config)
shell.evaluate(new File("path/to/some/file.groovy"))

This works fine. However, type checking in the script seems to be seriously broken. For example, I can include the following scripts without any complaint from the compiler:

String test = getTestValue() // automatic conversion from Integer to String. But WHY?
println "The value is $test" // shows as "The value is 0" on the console

private Integer getTestValue(){
    return 0
}

I can even go further than that. When creating a class inside the script, I can assign it to a String without any error:

String y = new Test()
println y // shows Test@somenr on the console

class Test { }

Other type checks do work. I have not discovered any logic behind it yet, so any pointers in the right direction are greatly appreciated.

解决方案

If in doubt, disasm. This is the bit around a call similar to yours: String x = new T():

   0: invokestatic  #17                 // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
   3: astore_1
   4: aload_1
   5: ldc           #40                 // int 1
   7: aaload
   8: ldc           #42                 // class T
  10: invokeinterface #46,  2           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callConstructor:(Ljava/lang/Object;)Ljava/lang/Object;
  15: invokestatic  #52                 // Method org/codehaus/groovy/runtime/typehandling/ShortTypeHandling.castToString:(Ljava/lang/Object;)Ljava/lang/String;
  18: checkcast     #54                 // class java/lang/String

So this is the culprit for that cast. This seems also to hold true for @TypeChecked/@CompileStatic.

这篇关于Groovy - 脚本中的类型检查无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆