2011-10-12 18 views
6

Quando si ottiene un TypeElement in un processore di annotazione, è possibile richiedere la sua super classe (o in particolare, lo TypeMirror di esso) utilizzando il metodo getSuperClass(). According to the JavaDoc, un tipo che non estende in modo esplicito nulla (in altre parole, Object è la super classe) o che è un'interfaccia restituirà un NoType con NONE come TypeKind.Controllo dell'assenza di super classe nel processore di annotazione

Ignorando il fatto che l'intera API modello/mirror sembra andare fuori strada per confondervi in ​​ogni occasione per un momento, come potrei verificarlo in modo affidabile? Ecco alcuni estratti di codice:

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

È questo il modo corretto? Sembra piuttosto goffo. Dal momento che lo equals method of TypeMirror non deve essere utilizzato per i controlli di uguaglianza semantica, mi chiedo se è sicuro utilizzarlo per TypeKind. Il mio istinto dice sì dato che è un enume, ma poi ho dei dubbi su quello instanceof.

C'è un modo migliore per farlo? L'intero pacchetto javax.lang.model ei suoi figli hanno riferimenti incrociati in tutto il negozio e non mi è mai chiaro quale sia il metodo migliore per qualcosa. Esistono utili metodi di utilità per alcune cose, e poi ci sono compiti apparentemente semplici che richiedono acrobazie dubbi come sopra.

risposta

8

Ho appena fatto un test e mi sono reso conto di aver interpretato male la documentazione. Restituisce un NoType con tipo NONE per java.lang.Object e interfacce, non per qualcosa che estende implicitamente Object. Silly me. Non avrò bisogno del controllo poiché uno precedente controlla se l'elemento annotato è una classe in senso stretto (non un enum o un'interfaccia) e ritornerà in tal caso. In altre parole, verificare se il nome canonico è java.lang.Object o forse utilizzare Types.isSameType dovrebbe fare il trucco.

Scusate gente. Ho deciso di non cancellare poiché altri potrebbero arrivare con la stessa domanda. Sentiti libero di votare se ritieni che sia appropriato.

EDIT: Ecco quello che alla fine sono andato con ...

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

Se alcuni di questi messaggi di errore sembra strano, è perché ho lasciato alcune cose specifiche del progetto out.

Problemi correlati