Использование ErrorProne для принудительного применения аннотации типа? - PullRequest
1 голос
/ 05 июня 2019

Есть ли пример использования 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
}

1 Ответ

2 голосов
/ 13 июня 2019

Error Prone имеет жестко запрограммированный набор проверок.Вы могли бы расширить Error Prone, но для этого потребовалось бы его разветвить, отредактировать исходный код, пересобрать его и использовать собственную версию.

Checker Framework - это подключаемая программа проверки типов, разработаннаядля проверки типов аннотаций.Это соответствует вашим целям.

Предположим, что вы определили аннотацию @EventKey, как показано ниже.(Это следует инструкциям для создания нового контролера .)

Затем вы можете выполнить команду

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

, и она будет вести себя точно так, как вы хотите, сразрешены правильные строки и запрещены неправильные строки (сообщениями об ошибках компилятора).

(Одно предостережение: Checker Framework также выдает предупреждение для назначения VALID_KEY = "asdf", поскольку у него нет возможности узнать, что этоназначение допустимо. Вы можете отменить это предупреждение, если уверены, что оно допустимо.)

Вот полные определения аннотации:

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 {}
...