Checking for the absence of a superclass in the annotation handler

When you get a TypeElement in the annotation handler, you can query its superclass (or, more specifically, its TypeMirror ) using the getSuperClass() method. According to the JavaDoc, a type that does not explicate extends something (in other words, Object is a superclass), or this interface will return NoType with NONE as TypeKind .

Ignoring the fact that the whole model / mirror API thing seems to be out of order to confuse you at every opportunity for a moment, how could I reliably verify this? Here are some snippets of code:

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

Is it correct? This seems rather awkward. Since the equals method of TypeMirror should not be used to check semantic equality, I wonder if it can be used for TypeKind . The feeling of my feeling says yes because it is renamed, but then I doubt it instanceof .

Is there a better way to do this? The entire javax.lang.model package and its children have cross-references throughout the store, and it’s never clear to me what the best method is for something. There are useful useful methods for some things, and then, apparently, simple tasks that require dubious acrobatics, as mentioned above.

+6
source share
1 answer

I just did a test and realized that I misinterpreted the documentation. It returns a NoType with a NONE view for java.lang.Object and interfaces, and not for something implicitly extending Object. I was a fool. I don’t need to check, as it previously checks to see if the annotated element is a class in the strict sense (not an enumeration or an interface) and will return if that is the case. In other words, checking if the canonical name is java.lang.Object or maybe using Types.isSameType should do the trick.

Sorry people. I decided not to delete, as others may come up with the same question. Feel free to vote if you think it is appropriate.

EDIT: Here I ended up going ...

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

If some of these error messages seem strange, this is due to the fact that I left some project-specific materials.

+8
source

Source: https://habr.com/ru/post/899117/


All Articles