AllowedValues (@NotNull PsiModifierListOwner owner, @NotNull PsiManager manager) { PsiUtilCore.ensureValid(owner); PsiFile containingFile = owner.getContainingFile(); if (containingFile != null) { PsiUtilCore.ensureValid(containingFile); if (!containsBeanInfoText((PsiFile)containingFile.getNavigationElement())) { return null; } } PsiMethod method = null; if (owner instanceof PsiParameter parameter) { PsiElement scope = parameter.getDeclarationScope(); if (!(scope instanceof PsiMethod)) return null; PsiElement nav = scope.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod)nav; if (method.isConstructor()) { // not a property, try the @ConstructorProperties({"prop"}) PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties"); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof PsiArrayInitializerMemberValue)) return null; PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers(); PsiElement parent = parameter.getParent(); if (!(parent instanceof PsiParameterList)) return null; int index = ((PsiParameterList)parent).getParameterIndex(parameter); if (index >= initializers.length) return null; PsiAnnotationMemberValue initializer = initializers[index]; if (!(initializer instanceof PsiLiteralExpression)) return null; Object val = ((PsiLiteralExpression)initializer).getValue(); if (!(val instanceof String)) return null; PsiMethod setter = PropertyUtilBase.findPropertySetter(method.getContainingClass(), (String)val, false, false); if (setter == null) return null; // try the @beaninfo of the corresponding setter PsiElement navigationElement = setter.getNavigationElement(); if (!(navigationElement instanceof PsiMethod)) return null; method = (PsiMethod)navigationElement; } } else if (owner instanceof PsiMethod) { PsiElement nav = owner.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod)nav; } if (method == null) return null; PsiClass aClass = method.getContainingClass(); if (aClass == null) return null; if (PropertyUtilBase.isSimplePropertyGetter(method)) { List<PsiMethod> setters = PropertyUtilBase.getSetters(aClass, PropertyUtilBase.getPropertyNameByGetter(method)); if (setters.size() != 1) return null; method = setters.get(0); } if (!PropertyUtilBase.isSimplePropertySetter(method)) return null; PsiDocComment doc = method.getDocComment(); if (doc == null) return null; PsiDocTag beaninfo = doc.findTagByName("beaninfo"); if (beaninfo == null) return null; String data = StringUtil.join(beaninfo.getDataElements(), PsiElement::getText, "\n"); int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:"); if (enumIndex == -1) return null; data = data.substring(enumIndex); int colon = data.indexOf(':'); int last = colon == -1 ? data.length() : data.substring(0,colon).lastIndexOf('\n'); data = data.substring(0, last); List<PsiAnnotationMemberValue> values = new ArrayList<>(); for (String line : StringUtil.splitByLines(data)) { List<String> words = StringUtil.split(line, " ", true, true); if (words.size() != 2) continue; String ref = words.get(1); PsiExpression constRef = JavaPsiFacade.getElementFactory(manager.getProject()).createExpressionFromText(ref, aClass); if (!(constRef instanceof PsiReferenceExpression expr)) continue; values.add(expr); } if (values.isEmpty()) return null; PsiAnnotationMemberValue[] array = values.toArray(PsiAnnotationMemberValue.EMPTY_ARRAY); return new AllowedValues(array, false); }