2011-10-12 21 views
6

Podczas uzyskiwania TypeElement w procesorze adnotacji można poprosić o jego superklasę (a dokładniej o TypeMirror) przy użyciu metody getSuperClass(). According to the JavaDoc, typ, który niczego nie rozszerza (innymi słowy, Object jest superklasą) lub jest to interfejs, który zwróci z NONE jako TypeKind.Sprawdzanie nieobecności super klasy w procesorze adnotacji

Pomijając fakt, że cały model/lustrzany interfejs API wydaje się wychodzić z siebie, by dezorientować przy każdej okazji przez chwilę, w jaki sposób mógłbym to sprawdzić? Oto kilka fragmentów kodu:

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

Czy to właściwy sposób? Wydaje się raczej niezgrabne. Ponieważ equals method of TypeMirror nie powinno być używane do semantycznych kontroli równości, zastanawiam się, czy można go bezpiecznie używać do TypeKind. Moje przeczucie mówi "tak", ponieważ jest to wyliczenie, ale wtedy mam wątpliwości co do tego, instanceof.

Czy jest lepszy sposób to zrobić? Cały pakiet javax.lang.model i jego dzieci mają odnośniki w całym sklepie i nigdy nie jest dla mnie jasne, jaka jest najlepsza metoda. Istnieją użyteczne metody użytkowe dla niektórych rzeczy, a następnie są pozornie proste zadania, które wymagają wątpliwych akrobacji, takich jak powyższe.

Odpowiedz

8

Właśnie wykonałem test i zdałem sobie sprawę, że źle zinterpretowałem dokumentację. Zwraca typ NoType z typem NONE dla java.lang.Object i interfejsów, a nie dla czegoś niejawnie rozszerzającego Object. Głupi ja. Nie będę potrzebował czeku, ponieważ wcześniejszy sprawdza, czy element z adnotacjami jest klasą w ścisłym tego słowa znaczeniu (nie wylicza ani interfejsu) i zwróci, jeśli tak. Innymi słowy, sprawdzenie, czy nazwa kanoniczna to java.lang.Object, czy może użycie Types.isSameType powinno załatwić sprawę.

Przepraszam. Zdecydowałem się nie usuwać, ponieważ inni mogą przyjechać z tym samym pytaniem. Jeśli uważasz, że jest to właściwe, możesz je usunąć.

EDIT: Oto, co ostatecznie poszedł z ...

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

Jeśli niektóre z tych komunikatów o błędach wydawać dziwne, to dlatego, że opuścił kilka rzeczy konkretnego projektu na zewnątrz.

Powiązane problemy