【问题标题】:Using ErrorProne to enforce a type annotation?使用 ErrorProne 强制类型注释?
【发布时间】:2019-06-05 19:32:48
【问题描述】:

是否有使用 ErrorProne 对类型和参数强制注解的示例?

例如,

@EventKey private static final String VALID_KEY = "asdf";

Map<@EventKey String, Object> map = new HashMap<>();

public void addSomeValues() {
    map.put("invalid_key", new Object()); // should error
    map.put(VALID_KEY, new Object()); // should pass
}

public void put(@EventKey String key, Object value) {
    map.put(key, value);
}

public void usingCustomPut(){

    put("invalid_key", new Object()); // should error
    put(VALID_KEY, new Object()); // should pass
}

【问题讨论】:

    标签: java checker-framework errorprone


    【解决方案1】:

    Error Prone 有一组硬编码的检查。您可以扩展 Error Prone,但这需要对其进行分叉、编辑源代码、重建它并使用您自己的自定义版本。

    Checker Framework 是一个可插入的类型检查器,专为检查类型注释而设计。 它符合您的目的。

    假设您定义了@EventKey 注释,如下所示。 (这是遵循creating a new checker 的说明。)

    然后就可以运行命令了

    java -jar "${CHECKERFRAMEWORK}/checker/dist/checker.jar" -cp . \
    -processor org.checkerframework.common.subtyping.SubtypingChecker \
    -Aquals=UnknownEventKey,EventKey TestCase.java
    

    它的行为完全符合您的意愿,允许正确的行,禁止不正确的行(通过编译器错误消息)。

    (一个警告:Checker Framework 也会对赋值 VALID_KEY = "asdf" 发出警告,因为它无法知道该赋值是合法的。如果你确定它是合法的,你可以 suppress 发出警告.)

    为了完整起见,这里是注释定义:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    import org.checkerframework.framework.qual.DefaultQualifierInHierarchy;
    import org.checkerframework.framework.qual.SubtypeOf;
    
    /** The value might or might not be an Event Key. */
    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
    @SubtypeOf({})
    @DefaultQualifierInHierarchy
    public @interface UnknownEventKey {}
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    import org.checkerframework.framework.qual.ImplicitFor;
    import org.checkerframework.framework.qual.LiteralKind;
    import org.checkerframework.framework.qual.SubtypeOf;
    
    /** The value is an Event Key. */
    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
    @SubtypeOf({UnknownEventKey.class})
    @ImplicitFor(literals = LiteralKind.NULL)
    public @interface EventKey {}
    

    【讨论】:

    • 该死,已经写了一个容易出错的检查器。最终需要比这里需要的更多的工作。很好记住,而不是重新写另一个。谢谢!
    猜你喜欢
    • 2011-01-16
    • 2011-07-16
    • 1970-01-01
    • 2013-10-24
    • 2019-07-11
    • 2019-05-21
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多