/** * Utility method to obtain annotations of a specific type from the supplied PsiModifierListOwner. * For optimization reasons, this method only looks at elements of type java.lang.String. * * <p>The parameter <code>allowIndirect</code> determines if the method should look for indirect * annotations, i.e. annotations which have themselves been annotated by the supplied annotation * name. Currently, this only allows one level of indirection and returns an array of * [base-annotation, indirect annotation] * * <p>The <code>annotationName</code> parameter is a pair of the target annotation class' fully * qualified name as a String and as a Set. This is done for performance reasons because the Set * is required by the {@link com.intellij.codeInsight.AnnotationUtil} utility class and allows to * avoid unnecessary object constructions. */ @NotNull public static PsiAnnotation[] getAnnotationFrom( PsiModifierListOwner owner, Pair<String, ? extends Set<String>> annotationName, boolean allowIndirect, boolean inHierarchy) { if (!PsiUtilEx.isLanguageAnnotationTarget(owner)) return PsiAnnotation.EMPTY_ARRAY; return getAnnotationsFromImpl(owner, annotationName, allowIndirect, inHierarchy); }
/** * Determines the PsiModifierListOwner for the passed element depending of the specified * LookupType. The LookupType decides whether to prefer the element a reference expressions * resolves to, or the element that is implied by the usage context ("expected type"). */ @Nullable public static PsiModifierListOwner getAnnotatedElementFor( @Nullable PsiElement element, LookupType type) { while (element != null) { if (type == LookupType.PREFER_DECLARATION || type == LookupType.DECLARATION_ONLY) { if (element instanceof PsiReferenceExpression) { final PsiElement e = ((PsiReferenceExpression) element).resolve(); if (e instanceof PsiModifierListOwner) { return (PsiModifierListOwner) e; } if (type == LookupType.DECLARATION_ONLY) { return null; } } } element = ContextComputationProcessor.getTopLevelInjectionTarget(element); final PsiElement parent = element.getParent(); if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression) element).getOperationTokenType() == JavaTokenType.PLUSEQ) { element = ((PsiAssignmentExpression) element).getLExpression(); continue; } else if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression p = (PsiAssignmentExpression) parent; if (p.getRExpression() == element) { element = p.getLExpression(); continue; } } else if (parent instanceof PsiReturnStatement) { final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); if (m != null) { return m; } } else if (parent instanceof PsiModifierListOwner) { return (PsiModifierListOwner) parent; } else if (parent instanceof PsiArrayInitializerMemberValue) { final PsiArrayInitializerMemberValue value = (PsiArrayInitializerMemberValue) parent; final PsiElement pair = value.getParent(); if (pair instanceof PsiNameValuePair) { return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) pair); } } else if (parent instanceof PsiNameValuePair) { return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) parent); } else { return PsiUtilEx.getParameterForArgument(element); } // If no annotation has been found through the usage context, check if the element // (i.e. the element the reference refers to) is annotated itself if (type != LookupType.DECLARATION_ONLY) { if (element instanceof PsiReferenceExpression) { final PsiElement e = ((PsiReferenceExpression) element).resolve(); if (e instanceof PsiModifierListOwner) { return (PsiModifierListOwner) e; } } } return null; } return null; }