private static StringBuilder buildAttributeValueText( PsiAnnotationMemberValue value, StringBuilder out) { if (value instanceof PsiArrayInitializerMemberValue) { final PsiArrayInitializerMemberValue arrayValue = (PsiArrayInitializerMemberValue) value; final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers(); if (initializers.length == 1) { return out.append(initializers[0].getText()); } } else if (value instanceof PsiAnnotation) { return out.append(buildAnnotationText((PsiAnnotation) value)); } return out.append(value.getText()); }
@Nullable private CompileTimeConstant<?> getCompileTimeConstFromArrayExpression( FqName annotationFqName, Name valueName, PsiArrayInitializerMemberValue value, PostponedTasks taskList) { PsiAnnotationMemberValue[] initializers = value.getInitializers(); List<CompileTimeConstant<?>> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers); ClassDescriptor classDescriptor = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList); // TODO: nullability issues ValueParameterDescriptor valueParameterDescriptor = DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter( valueName, classDescriptor); if (valueParameterDescriptor == null) { return null; } JetType expectedArrayType = valueParameterDescriptor.getType(); return new ArrayValue(values, expectedArrayType); }
@Override public void visitAnnotation(PsiAnnotation annotation) { super.visitAnnotation(annotation); final PsiAnnotationParameterList parameterList = annotation.getParameterList(); final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement(); if (nameReferenceElement == null) { return; } final PsiNameValuePair[] attributes = parameterList.getAttributes(); final PsiElement[] annotationChildren = annotation.getChildren(); if (annotationChildren.length >= 2 && annotationChildren[1] instanceof PsiWhiteSpace && !containsError(annotation)) { registerError(annotationChildren[1], Boolean.TRUE); } if (attributes.length == 0) { if (parameterList.getChildren().length > 0 && !containsError(annotation)) { registerError(parameterList, ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); } } else if (attributes.length == 1) { final PsiNameValuePair attribute = attributes[0]; final PsiIdentifier identifier = attribute.getNameIdentifier(); final PsiAnnotationMemberValue attributeValue = attribute.getValue(); if (identifier != null && attributeValue != null) { @NonNls final String name = attribute.getName(); if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name) && !containsError(annotation)) { registerErrorAtOffset( attribute, 0, attributeValue.getStartOffsetInParent(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); } } if (!(attributeValue instanceof PsiArrayInitializerMemberValue)) { return; } final PsiArrayInitializerMemberValue arrayValue = (PsiArrayInitializerMemberValue) attributeValue; final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers(); if (initializers.length != 1) { return; } if (!containsError(annotation)) { registerError( arrayValue.getFirstChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); registerError( arrayValue.getLastChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); } } else if (attributes.length > 1) { for (PsiNameValuePair attribute : attributes) { final PsiAnnotationMemberValue value = attribute.getValue(); if (!(value instanceof PsiArrayInitializerMemberValue)) { continue; } final PsiArrayInitializerMemberValue arrayValue = (PsiArrayInitializerMemberValue) value; final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers(); if (initializers.length != 1) { continue; } if (!containsError(annotation)) { registerError( arrayValue.getFirstChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); registerError( arrayValue.getLastChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE); } } } }
/** * 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; }