Проверка на отсутствие суперкласса в процессоре аннотаций - PullRequest
6 голосов
/ 12 октября 2011

При получении TypeElement в процессоре аннотаций вы можете запросить его суперкласс (или, более конкретно, TypeMirror его), используя метод getSuperClass(). Согласно JavaDoc , тип, который не расширяет ничего, не расширяет ничего (другими словами, Object является суперклассом) или это интерфейс, который вернет NoType с NONE как TypeKind.

Несмотря на то, что вся модель API / модель зеркала, кажется, делает все возможное, чтобы сбить вас с толку при каждой возможности на мгновение, как я могу надежно проверить это? Вот некоторые выдержки из кода:

//Cast is safe since TypeKind is checked before this
final TypeElement el = (TypeElement)annotatedElement;
...
final TypeMirror parent = el.getSuperclass();
//Checking whether "nothing" is extended
if(parent.getKind().equals(TypeKind.NONE) && parent instanceof NoType) {
    ...         
}

Это правильная манера? Это кажется довольно неуклюжим. Так как метод equals TypeMirror не должен использоваться для проверки семантического равенства, мне интересно, безопасно ли его использовать для TypeKind. Мое инстинктивное чувство говорит да, так как это перечисление, но тогда у меня есть сомнения по этому поводу instanceof.

Есть ли лучший способ сделать это? Весь пакет javax.lang.model и его дочерние элементы имеют перекрестные ссылки по всему магазину, и мне никогда не ясно, какой метод лучше всего подходит для чего-либо. Для некоторых вещей есть полезные служебные методы, а затем есть, казалось бы, простые задачи, которые требуют сомнительной акробатики, как указано выше.

1 Ответ

8 голосов
/ 12 октября 2011

Я только что сделал тест и понял, что неправильно истолковал документацию. Он возвращает NoType с добрым NONE для java.lang.Object и интерфейсов, а не для чего-то неявно расширяющего Object. Дурак я. Я не буду нуждаться в проверке, поскольку предыдущий проверяет, является ли аннотированный элемент классом в строгом смысле (не перечисление или интерфейс), и будет возвращать, если это так. Другими словами, проверка того, является ли каноническое имя java.lang.Object или, возможно, использование Types.isSameType, должна помочь.

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

РЕДАКТИРОВАТЬ: Вот что я в конце концов пошел с ...

boolean superTypeValid = true;
final TypeMirror parent = el.getSuperClass();
if(!parent.getKind().equals(TypeKind.DECLARED)) {
    messager.printMessage(Kind.ERROR, "May only inherit from a class; not enums, annotations or other declared kinds.", annotatedElement, mirror);
    superTypeValid = false;
} else {
    final DeclaredType parentType = (DeclaredType)parent;
    final Element parentEl = parentType.asElement();
    if(!parentEl.getKind().equals(ElementKind.CLASS)) {
        messager.printMessage(Kind.ERROR, "May only inherit from a class; not enums, annotations or other declared kinds.", annotatedElement, mirror);
        superTypeValid = false;
    }
}
...
if(superTypeValid) {
    if(typeUtils.isSameType(parent, elUtils.getTypeElement("java.lang.Object").asType())) {
        messager.printMessage(Kind.ERROR, "Inherit must not be set to true if the class doesn't extend.", annotatedElement, mirror);
        valid = false;
    } else {
        ...
    }
}

Если некоторые из этих сообщений об ошибках кажутся странными, это потому, что я пропустил некоторые специфичные для проекта вещи.

...