public static void fillCompletionVariants( CompletionParameters parameters, CompletionResultSet result) { if (parameters.getCompletionType() != CompletionType.BASIC && parameters.getCompletionType() != CompletionType.SMART) { return; } PsiElement position = parameters.getPosition(); if (psiElement(PsiIdentifier.class) .withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClass.class) .andNot(JavaCompletionData.AFTER_DOT) .andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class))) .accepts(position)) { suggestGeneratedMethods(result, position); } else if (psiElement(PsiIdentifier.class) .withParents( PsiJavaCodeReferenceElement.class, PsiAnnotation.class, PsiModifierList.class, PsiClass.class) .accepts(position)) { PsiAnnotation annotation = ObjectUtils.assertNotNull(PsiTreeUtil.getParentOfType(position, PsiAnnotation.class)); int annoStart = annotation.getTextRange().getStartOffset(); suggestGeneratedMethods( result.withPrefixMatcher( annotation.getText().substring(0, parameters.getOffset() - annoStart)), position); } }
/** * 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. */ public static PsiAnnotation[] getAnnotationsFromImpl( PsiModifierListOwner owner, Pair<String, ? extends Set<String>> annotationName, boolean allowIndirect, boolean inHierarchy) { final PsiAnnotation directAnnotation = inHierarchy ? AnnotationUtil.findAnnotationInHierarchy(owner, annotationName.second) : AnnotationUtil.findAnnotation(owner, annotationName.second); if (directAnnotation != null) { return new PsiAnnotation[] {directAnnotation}; } if (allowIndirect) { final PsiAnnotation[] annotations = getAnnotations(owner, inHierarchy); for (PsiAnnotation annotation : annotations) { PsiJavaCodeReferenceElement nameReference = annotation.getNameReferenceElement(); if (nameReference == null) continue; PsiElement resolved = nameReference.resolve(); if (resolved instanceof PsiClass) { final PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotationInHierarchy( (PsiModifierListOwner) resolved, annotationName.second); if (psiAnnotation != null) { return new PsiAnnotation[] {psiAnnotation, annotation}; } } } } return PsiAnnotation.EMPTY_ARRAY; }
public static PsiClass getProviderClass(final PsiElement element, final PsiClass topLevelClass) { final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class); if (annotation != null) { final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass"); if (value instanceof PsiClassObjectAccessExpression) { final PsiTypeElement operand = ((PsiClassObjectAccessExpression) value).getOperand(); final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType()); if (psiClass != null) { return psiClass; } } } return topLevelClass; }
private static AllowedValues getAllowedValuesFromMagic( @NotNull PsiModifierListOwner element, @NotNull PsiType type, PsiAnnotation magic) { if (magic == null) return null; PsiAnnotationMemberValue[] allowedValues; final boolean canBeOred; if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.LONG_RANK) { PsiAnnotationMemberValue intValues = magic.findAttributeValue("intValues"); allowedValues = intValues instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) intValues).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; if (allowedValues.length == 0) { PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags"); allowedValues = orValue instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) orValue).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; canBeOred = true; } else { canBeOred = false; } } else if (type.equals( PsiType.getJavaLangString( element.getManager(), GlobalSearchScope.allScope(element.getProject())))) { PsiAnnotationMemberValue strValuesAttr = magic.findAttributeValue("stringValues"); allowedValues = strValuesAttr instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue) strValuesAttr).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY; canBeOred = false; } else { return null; // other types not supported } if (allowedValues.length != 0) { return new AllowedValues(allowedValues, canBeOred); } // last resort: try valuesFromClass PsiAnnotationMemberValue[] values = readFromClass("valuesFromClass", magic, type); boolean ored = false; if (values == null) { values = readFromClass("flagsFromClass", magic, type); ored = true; } if (values == null) return null; return new AllowedValues(values, ored); }
private static PsiAnnotationMemberValue[] readFromClass( @NonNls String attributeName, @NotNull PsiAnnotation magic, PsiType type) { PsiAnnotationMemberValue fromClassAttr = magic.findAttributeValue(attributeName); PsiType fromClassType = fromClassAttr instanceof PsiClassObjectAccessExpression ? ((PsiClassObjectAccessExpression) fromClassAttr).getOperand().getType() : null; PsiClass fromClass = fromClassType instanceof PsiClassType ? ((PsiClassType) fromClassType).resolve() : null; if (fromClass == null) return null; String fqn = fromClass.getQualifiedName(); if (fqn == null) return null; List<PsiAnnotationMemberValue> constants = new ArrayList<PsiAnnotationMemberValue>(); for (PsiField field : fromClass.getFields()) { if (!field.hasModifierProperty(PsiModifier.PUBLIC) || !field.hasModifierProperty(PsiModifier.STATIC) || !field.hasModifierProperty(PsiModifier.FINAL)) continue; PsiType fieldType = field.getType(); if (!Comparing.equal(fieldType, type)) continue; PsiAssignmentExpression e = (PsiAssignmentExpression) JavaPsiFacade.getElementFactory(field.getProject()) .createExpressionFromText("x=" + fqn + "." + field.getName(), field); PsiReferenceExpression refToField = (PsiReferenceExpression) e.getRExpression(); constants.add(refToField); } if (constants.isEmpty()) return null; return constants.toArray(new PsiAnnotationMemberValue[constants.size()]); }
@Nullable public static String checkFunctionalInterface( @NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel) { if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) { final PsiAnnotationOwner owner = annotation.getOwner(); if (owner instanceof PsiModifierList) { final PsiElement parent = ((PsiModifierList) owner).getParent(); if (parent instanceof PsiClass) { return LambdaHighlightingUtil.checkInterfaceFunctional( (PsiClass) parent, ((PsiClass) parent).getName() + " is not a functional interface"); } } } return null; }
@Nullable public static String calcAnnotationValue(@NotNull PsiAnnotation annotation, @NonNls String attr) { PsiElement value = annotation.findAttributeValue(attr); Object o = CONSTANT_EVALUATION_HELPER.computeConstantExpression(value); if (o instanceof String) { return (String) o; } return null; }
private static boolean processAnnotationAttributes( @Nullable Map<String, Object> annotationAttributeValues, @NotNull PsiAnnotation annotation) { if (annotationAttributeValues != null) { final PsiAnnotationParameterList parameterList = annotation.getParameterList(); final PsiNameValuePair[] attributes = parameterList.getAttributes(); for (PsiNameValuePair attribute : attributes) { final String name = attribute.getName(); if (annotationAttributeValues.containsKey(name)) { annotationAttributeValues.put(name, attribute.getValue()); } } } return true; }
public static boolean isAnnotatedWithParameter( PsiAnnotation annotation, String parameter, Set<String> values) { final PsiAnnotationMemberValue attributeValue = annotation.findDeclaredAttributeValue(parameter); if (attributeValue != null) { Collection<String> matches = extractValuesFromParameter(attributeValue); for (String s : matches) { if (values.contains(s)) { return true; } } } return false; }
public static boolean isTestNGAnnotation(PsiAnnotation annotation) { String qName = annotation.getQualifiedName(); if (qName != null) { if (qName.equals(TEST_ANNOTATION_FQN)) return true; for (String qn : CONFIG_ANNOTATIONS_FQN) { if (qName.equals(qn)) return true; } if (qName.equals(TEST_ANNOTATION_FQN)) return true; for (String qn : CONFIG_ANNOTATIONS_FQN) { if (qName.equals(qn)) return true; } } return false; }
static AllowedValues getAllowedValues( @NotNull PsiModifierListOwner element, PsiType type, Set<PsiClass> visited) { PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(element, true, null); for (PsiAnnotation annotation : annotations) { AllowedValues values; if (type != null && MagicConstant.class.getName().equals(annotation.getQualifiedName())) { // PsiAnnotation magic = AnnotationUtil.findAnnotationInHierarchy(element, // Collections.singleton(MagicConstant.class.getName())); values = getAllowedValuesFromMagic(element, type, annotation); if (values != null) return values; } PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); PsiElement resolved = ref == null ? null : ref.resolve(); if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) continue; PsiClass aClass = (PsiClass) resolved; if (visited == null) visited = new THashSet<PsiClass>(); if (!visited.add(aClass)) continue; values = getAllowedValues(aClass, type, visited); if (values != null) return values; } return parseBeanInfo(element); }
private static void appendAnnotationAttributeValues( final Map<String, Collection<String>> results, final PsiAnnotation annotation, final PsiDocCommentOwner commentOwner) { for (String parameter : results.keySet()) { final Collection<String> values = results.get(parameter); if (annotation != null) { final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue(parameter); if (value != null) { values.addAll(extractValuesFromParameter(value)); } } else { values.addAll(extractAnnotationValuesFromJavaDoc(getTextJavaDoc(commentOwner), parameter)); } } }
private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) { PsiMethod method = null; if (owner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) owner; 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 = PropertyUtil.findPropertySetter( method.getContainingClass(), (String) val, false, false); if (setter == null) return null; // try the @beaninfo of the corresponding setter method = (PsiMethod) setter.getNavigationElement(); } } 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 (PropertyUtil.isSimplePropertyGetter(method)) { List<PsiMethod> setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method)); if (setters.size() != 1) return null; method = setters.get(0); } if (!PropertyUtil.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(), new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return element.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<PsiAnnotationMemberValue>(); 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(aClass.getProject()) .createExpressionFromText(ref, aClass); if (!(constRef instanceof PsiReferenceExpression)) continue; PsiReferenceExpression expr = (PsiReferenceExpression) constRef; values.add(expr); } if (values.isEmpty()) return null; PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]); return new AllowedValues(array, false); }
public static boolean isDisabled(PsiAnnotation annotation) { final PsiAnnotationMemberValue attributeValue = annotation.findDeclaredAttributeValue("enabled"); return attributeValue != null && attributeValue.textMatches("false"); }