Does groovy @CompileStatic imply @TypeChecked?

时间:2019-04-16 23:28:55

标签: groovy

I have been adding both @TypeChecked and @CompileStatic to groovy code.

The compiler accepts this, but is it redundant? Does TypeChecked add anything that CompileStatic does not? The docs seems to imply that CompileStatic is a superset, but stop short of saying so outright. I would like to compile statically while occasionally disabling strict type checking, to let groovy auto-typecast while still catching misspelled references or missing methods.

An example:

@TypeChecked
@CompileStatic
class MyClass {
    void simple() {
        // compiles fine statically
    }

    @TypeChecked(SKIP)
    void complicated() {
        // would require too many ugly typecasts
    }

    @CompileDynamic
    void evenworse() {
        // need time to untangle this
    }
}

I read Difference between @TypeChecked and @CompileStatic and it did not answer this specific question. It suggested that TypeCast allows some additional checks, but I don't know if it does additional checks by default.

1 个答案:

答案 0 :(得分:1)

我会说是的,CompileStatic意味着TypeChecked。查看注释接口TypeCheckedCompileStatic的常规来源,我们看到:

// TypeChecked.java
@GroovyASTTransformationClass("org.codehaus.groovy.transform.StaticTypesTransformation")
public @interface TypeChecked {

// CompileStatic.java
@GroovyASTTransformationClass("org.codehaus.groovy.transform.sc.StaticCompileTransformation")
public @interface CompileStatic {
...

告诉我们进行实际AST转换(注释的工作)的类是StaticCompileTransformationStaticTypesTransformation

查看我们得到的代码:

// Transformation for TypeChecked
public class StaticTypesTransformation implements ASTTransformation, CompilationUnitAware {

// Transformation for CompileStatic
public class StaticCompileTransformation extends StaticTypesTransformation {

CompileStatic的转换扩展了TypeChecked的转换,因此似乎CompileStatic的行为确实是TypeChecked行为的超集。

<<编辑>>

深入研究,我们看到转换类使用访问者模式,并且它们分别具有以下方法:

    // StaticTypesTransformation, transformation for TypeChecked
    protected StaticTypeCheckingVisitor newVisitor(SourceUnit unit, ClassNode node) {
        return new StaticTypeCheckingVisitor(unit, node);
    }

    // StaticCompileTransformation, transformation for CompileStatic 
    protected StaticTypeCheckingVisitor newVisitor(final SourceUnit unit, final ClassNode node) {
        return new StaticCompilationVisitor(unit, node);
    }

,将为每种情况返回一个自定义的访客类。

StaticCompilationVisitor,我们看到:

public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
    ...
    public void visitClass(final ClassNode node) {
        ...
        super.visitClass(node);
        ...
    }
    ...
}

换句话说,CompileStatic的访问者类扩展了TypeChecked的访问者类,此外,{{1}中的visitClass方法(完成实际工作) }访问者调用CompileStatic,其中super.visitClass(node)super的访问者类。

我认为这或多或少证明了这一点。 TypeChecked的行为实际上是CompileStatic的行为的超集。