/** * Resolve a method annotation, this method scan the specified method, if the annotation is not found * it will also scan the methods this method overrides and return the annotation when it is found. * * @param annotationType the annotation type, * @param elementUtils element utils * @param typeUtils type utils * @param declaring the element declaring the method * @param method the method to start the resolution from * @return the annotation if resolved otherwise null */ public static AnnotationMirror resolveMethodAnnotation( Class<? extends Annotation> annotationType, Elements elementUtils, Types typeUtils, TypeElement declaring, ExecutableElement method) { return resolveMethodAnnotation( (DeclaredType) elementUtils.getTypeElement(annotationType.getName()).asType(), elementUtils, typeUtils, declaring, method); }
private static AnnotationMirror isFluent(DeclaredType annotationType, Elements elementUtils, Types typeUtils, TypeElement declaring, ExecutableElement method, TypeMirror type) { for (TypeMirror directSuperType : typeUtils.directSupertypes(type)) { Element directSuperTypeElt = typeUtils.asElement(directSuperType); if (directSuperTypeElt instanceof TypeElement) { List<ExecutableElement> methods = ((TypeElement) directSuperTypeElt).getEnclosedElements().stream(). filter(member -> member.getKind() == ElementKind.METHOD).map(member -> (ExecutableElement) member). collect(Collectors.toList()); for (ExecutableElement m : methods) { if (elementUtils.overrides(method, m, declaring)) { AnnotationMirror annotation = resolveMethodAnnotation(annotationType, elementUtils, typeUtils, (TypeElement) directSuperTypeElt, m); if (annotation != null) { return annotation; } } } AnnotationMirror annotation = isFluent(annotationType, elementUtils, typeUtils, declaring, method, directSuperType); if (annotation != null) { return annotation; } } } return null; }
@Override protected MethodInfo createMethodInfo(Set<ClassTypeInfo> ownerTypes, String methodName, String comment, Doc doc, TypeInfo returnType, Text returnDescription, boolean isFluent, boolean isCacheReturn, List<ParamInfo> mParams, ExecutableElement methodElt, boolean isStatic, boolean isDefault, ArrayList<TypeParamInfo.Method> typeParams, TypeElement declaringElt, boolean methodDeprecated, Text methodDeprecatedDesc) { AnnotationMirror proxyIgnoreAnnotation = Helper.resolveMethodAnnotation(ProxyIgnore.class, elementUtils, typeUtils, declaringElt, methodElt); boolean isProxyIgnore = proxyIgnoreAnnotation != null; AnnotationMirror proxyCloseAnnotation = Helper.resolveMethodAnnotation(ProxyClose.class, elementUtils, typeUtils, declaringElt, methodElt); boolean isProxyClose = proxyCloseAnnotation != null; ProxyMethodInfo proxyMeth = new ProxyMethodInfo(ownerTypes, methodName, returnType, returnDescription, isFluent, isCacheReturn, mParams, comment, doc, isStatic, isDefault, typeParams, isProxyIgnore, isProxyClose, methodDeprecated, methodDeprecatedDesc); if (isProxyClose && mParams.size() > 0) { if (mParams.size() > 1) { throw new GenException(this.modelElt, "@ProxyClose methods can't have more than one parameter"); } if (proxyMeth.getKind() != MethodKind.FUTURE) { throw new GenException(this.modelElt, "@ProxyClose parameter must be Handler<AsyncResult<Void>>"); } TypeInfo type = mParams.get(0).getType(); TypeInfo arg = ((ParameterizedTypeInfo) ((ParameterizedTypeInfo) type).getArgs().get(0)).getArgs().get(0); if (arg.getKind() != ClassKind.VOID) { throw new GenException(this.modelElt, "@ProxyClose parameter must be " + "Handler<AsyncResult<Void>> instead of " + type); } } return proxyMeth; }
AnnotationMirror fluentAnnotation = Helper.resolveMethodAnnotation(Fluent.class, elementUtils, typeUtils, declaringElt, modelMethod); boolean isFluent = fluentAnnotation != null; if (isFluent) {