/** * 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; }
private static String buildAnnotationText(PsiAnnotation annotation) { final StringBuilder out = new StringBuilder("@"); final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement(); assert nameReferenceElement != null; out.append(nameReferenceElement.getText()); final PsiAnnotationParameterList parameterList = annotation.getParameterList(); final PsiNameValuePair[] attributes = parameterList.getAttributes(); if (attributes.length == 0) { return out.toString(); } out.append('('); if (attributes.length == 1) { final PsiNameValuePair attribute = attributes[0]; @NonNls final String name = attribute.getName(); if (name != null && !PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)) { out.append(name).append('='); } buildAttributeValueText(attribute.getValue(), out); } else { for (int i = 0; i < attributes.length; i++) { final PsiNameValuePair attribute = attributes[i]; if (i > 0) { out.append(','); } out.append(attribute.getName()).append('='); buildAttributeValueText(attribute.getValue(), out); } } out.append(')'); return out.toString(); }
public void setMirror(@NotNull TreeElement element) { setMirrorCheckingType(element, null); PsiAnnotation mirror = (PsiAnnotation) SourceTreeToPsiMap.treeElementToPsi(element); ((ClsElementImpl) getParameterList()) .setMirror((TreeElement) SourceTreeToPsiMap.psiElementToTree(mirror.getParameterList())); ((ClsElementImpl) getNameReferenceElement()) .setMirror( (TreeElement) SourceTreeToPsiMap.psiElementToTree(mirror.getNameReferenceElement())); }
private static boolean containsError(PsiAnnotation annotation) { final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) { return true; } final PsiClass aClass = (PsiClass) nameRef.resolve(); if (aClass == null || !aClass.isAnnotationType()) { return true; } final Set<String> names = new HashSet<String>(); final PsiAnnotationParameterList annotationParameterList = annotation.getParameterList(); if (PsiUtilCore.hasErrorElementChild(annotationParameterList)) { return true; } final PsiNameValuePair[] attributes = annotationParameterList.getAttributes(); for (PsiNameValuePair attribute : attributes) { final PsiReference reference = attribute.getReference(); if (reference == null) { return true; } final PsiMethod method = (PsiMethod) reference.resolve(); if (method == null) { return true; } final PsiAnnotationMemberValue value = attribute.getValue(); if (value == null || PsiUtilCore.hasErrorElementChild(value)) { return true; } if (value instanceof PsiAnnotation && containsError((PsiAnnotation) value)) { return true; } if (!hasCorrectType(value, method.getReturnType())) { return true; } final String name = attribute.getName(); if (!names.add(name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME)) { return true; } } for (PsiMethod method : aClass.getMethods()) { if (!(method instanceof PsiAnnotationMethod)) { continue; } final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; if (annotationMethod.getDefaultValue() == null && !names.contains(annotationMethod.getName())) { return true; // missing a required argument } } return false; }
public static PsiAnnotation findAnnotation( @NotNull PsiAnnotationOwner modifierList, @NotNull String qualifiedName) { final String shortName = StringUtil.getShortName(qualifiedName); PsiAnnotation[] annotations = modifierList.getAnnotations(); for (PsiAnnotation annotation : annotations) { final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); if (referenceElement != null && shortName.equals(referenceElement.getReferenceName())) { if (qualifiedName.equals(annotation.getQualifiedName())) return annotation; } } return null; }
private static boolean isAnnotationRepeatedTwice( @NotNull PsiAnnotationOwner owner, @NotNull String qualifiedName) { int count = 0; for (PsiAnnotation annotation : owner.getAnnotations()) { PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) continue; PsiElement resolved = nameRef.resolve(); if (!(resolved instanceof PsiClass) || !qualifiedName.equals(((PsiClass) resolved).getQualifiedName())) continue; count++; if (count == 2) return true; } return false; }
/** * From given targets, returns first where the annotation may be applied. Returns {@code null} * when the annotation is not applicable at any of the targets, or {@linkplain TargetType#UNKNOWN} * if the annotation does not resolve to a valid annotation type. */ @Nullable public static TargetType findAnnotationTarget( @NotNull PsiAnnotation annotation, @NotNull TargetType... types) { if (types.length != 0) { PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); if (ref != null) { PsiElement annotationType = ref.resolve(); if (annotationType instanceof PsiClass) { return findAnnotationTarget((PsiClass) annotationType, types); } } } return TargetType.UNKNOWN; }
@Nullable public static HighlightInfo checkAnnotationType(PsiAnnotation annotation) { PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement(); if (nameReferenceElement != null) { PsiElement resolved = nameReferenceElement.resolve(); if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) { String description = JavaErrorMessages.message("annotation.annotation.type.expected"); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameReferenceElement) .descriptionAndTooltip(description) .create(); } } return null; }
@Nullable public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) { PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) return null; PsiClass aClass = (PsiClass) nameRef.resolve(); if (aClass != null && aClass.isAnnotationType()) { Set<String> names = new HashSet<String>(); PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { final String name = attribute.getName(); if (name != null) { names.add(name); } else { names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); } } PsiMethod[] annotationMethods = aClass.getMethods(); List<String> missed = new ArrayList<String>(); for (PsiMethod method : annotationMethods) { if (PsiUtil.isAnnotationMethod(method)) { PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; if (annotationMethod.getDefaultValue() == null) { if (!names.contains(annotationMethod.getName())) { missed.add(annotationMethod.getName()); } } } } if (!missed.isEmpty()) { StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'"); for (int i = 1; i < missed.size(); i++) { buff.append(", "); buff.append("'").append(missed.get(i)).append("'"); } String description = JavaErrorMessages.message("annotation.missing.attribute", buff); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameRef) .descriptionAndTooltip(description) .create(); } } return null; }
@NotNull public static PsiAnnotationMemberValue getMemberValue( final PsiElement element, final ClsElementImpl parent) { if (element instanceof PsiExpression) { return psiToClsExpression((PsiExpression) element, parent); } else if (element instanceof PsiArrayInitializerMemberValue) { PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue) element).getInitializers(); PsiAnnotationMemberValue[] clsInitializers = new PsiAnnotationMemberValue[initializers.length]; ClsArrayInitializerMemberValueImpl arrayValue = new ClsArrayInitializerMemberValueImpl(parent, clsInitializers); for (int i = 0; i < initializers.length; i++) { clsInitializers[i] = getMemberValue(initializers[i], arrayValue); } return arrayValue; } else if (element instanceof PsiAnnotation) { final PsiAnnotation psiAnnotation = (PsiAnnotation) element; final PsiJavaCodeReferenceElement referenceElement = psiAnnotation.getNameReferenceElement(); assert referenceElement != null : psiAnnotation; final String canonicalText = referenceElement.getText(); // class file has FQNs return new ClsAnnotationValueImpl(parent) { @Override protected ClsJavaCodeReferenceElementImpl createReference() { return new ClsJavaCodeReferenceElementImpl(this, canonicalText); } @Override protected ClsAnnotationParameterListImpl createParameterList() { PsiNameValuePair[] psiAttributes = psiAnnotation.getParameterList().getAttributes(); return new ClsAnnotationParameterListImpl(this, psiAttributes); } @Override public PsiAnnotationOwner getOwner() { return (PsiAnnotationOwner) getParent(); } }; } else { LOG.error("Unexpected source element for annotation member value: " + element); return null; } }
@Nullable public static PsiAnnotation findAnnotation( @Nullable PsiAnnotationOwner annotationOwner, @NotNull String qualifiedName) { if (annotationOwner == null) return null; PsiAnnotation[] annotations = annotationOwner.getAnnotations(); if (annotations.length == 0) return null; String shortName = StringUtil.getShortName(qualifiedName); for (PsiAnnotation annotation : annotations) { PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); if (referenceElement != null && shortName.equals(referenceElement.getReferenceName())) { if (qualifiedName.equals(annotation.getQualifiedName())) { return annotation; } } } return null; }
@Nullable public static PsiAnnotationMemberValue findAttributeValue( @NotNull PsiAnnotation annotation, @Nullable @NonNls String attributeName) { final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName); if (value != null) return value; if (attributeName == null) attributeName = "value"; final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); if (referenceElement != null) { PsiElement resolved = referenceElement.resolve(); if (resolved != null) { PsiMethod[] methods = ((PsiClass) resolved).findMethodsByName(attributeName, false); for (PsiMethod method : methods) { if (PsiUtil.isAnnotationMethod(method)) { return ((PsiAnnotationMethod) method).getDefaultValue(); } } } } return null; }
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); }
@Nullable public static HighlightInfo checkTargetAnnotationDuplicates(PsiAnnotation annotation) { PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) return null; PsiElement resolved = nameRef.resolve(); if (!(resolved instanceof PsiClass) || !CommonClassNames.JAVA_LANG_ANNOTATION_TARGET.equals( ((PsiClass) resolved).getQualifiedName())) { return null; } PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); if (attributes.length < 1) return null; PsiAnnotationMemberValue value = attributes[0].getValue(); if (!(value instanceof PsiArrayInitializerMemberValue)) return null; PsiAnnotationMemberValue[] arrayInitializers = ((PsiArrayInitializerMemberValue) value).getInitializers(); Set<PsiElement> targets = new HashSet<PsiElement>(); for (PsiAnnotationMemberValue initializer : arrayInitializers) { if (initializer instanceof PsiReferenceExpression) { PsiElement target = ((PsiReferenceExpression) initializer).resolve(); if (target != null) { if (targets.contains(target)) { String description = JavaErrorMessages.message("repeated.annotation.target"); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(initializer) .descriptionAndTooltip(description) .create(); } targets.add(target); } } } return null; }
@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); } } } }
@Nullable public static HighlightInfo checkApplicability( @NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel, @NotNull PsiFile containingFile) { if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) { return null; } PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) return null; PsiAnnotationOwner owner = annotation.getOwner(); PsiAnnotation.TargetType[] targets = PsiImplUtil.getTargetsForLocation(owner); if (owner == null || targets.length == 0) { String message = JavaErrorMessages.message("annotation.not.allowed.here"); return annotationError(annotation, message); } if (!(owner instanceof PsiModifierList)) { HighlightInfo info = HighlightUtil.checkTypeAnnotationFeature(annotation, languageLevel, containingFile); if (info != null) return info; } PsiAnnotation.TargetType applicable = PsiImplUtil.findApplicableTarget(annotation, targets); if (applicable == PsiAnnotation.TargetType.UNKNOWN) return null; if (applicable == null) { String target = JavaErrorMessages.message("annotation.target." + targets[0]); String message = JavaErrorMessages.message("annotation.not.applicable", nameRef.getText(), target); return annotationError(annotation, message); } if (applicable == PsiAnnotation.TargetType.TYPE_USE) { if (owner instanceof PsiClassReferenceType) { PsiJavaCodeReferenceElement ref = ((PsiClassReferenceType) owner).getReference(); HighlightInfo info = checkReferenceTarget(annotation, ref); if (info != null) return info; } else if (owner instanceof PsiModifierList) { PsiElement nextElement = PsiTreeUtil.skipSiblingsForward( (PsiModifierList) owner, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); if (nextElement instanceof PsiTypeElement) { PsiTypeElement typeElement = (PsiTypeElement) nextElement; PsiType type = typeElement.getType(); if (PsiType.VOID.equals(type)) { String message = JavaErrorMessages.message("annotation.not.allowed.void"); return annotationError(annotation, message); } if (!(type instanceof PsiPrimitiveType)) { PsiJavaCodeReferenceElement ref = getOutermostReferenceElement(typeElement.getInnermostComponentReferenceElement()); HighlightInfo info = checkReferenceTarget(annotation, ref); if (info != null) return info; } } } else if (owner instanceof PsiTypeElement) { PsiElement context = PsiTreeUtil.skipParentsOfType((PsiTypeElement) owner, PsiTypeElement.class); if (context instanceof PsiClassObjectAccessExpression) { String message = JavaErrorMessages.message("annotation.not.allowed.class"); return annotationError(annotation, message); } } } return null; }
static HighlightInfo checkDuplicateAnnotations(@NotNull PsiAnnotation annotationToCheck) { PsiAnnotationOwner owner = annotationToCheck.getOwner(); if (owner == null) return null; PsiJavaCodeReferenceElement element = annotationToCheck.getNameReferenceElement(); if (element == null) return null; PsiElement resolved = element.resolve(); if (!(resolved instanceof PsiClass)) return null; PsiClass annotationType = (PsiClass) resolved; PsiClass contained = contained(annotationType); String containedElementFQN = contained == null ? null : contained.getQualifiedName(); if (containedElementFQN != null) { PsiClass container = annotationType; String containerName = container.getQualifiedName(); if (isAnnotationRepeatedTwice(owner, containedElementFQN)) { String description = JavaErrorMessages.message("annotation.container.wrong.place", containerName); return annotationError(annotationToCheck, description); } } else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) { if (!PsiUtil.isLanguageLevel8OrHigher(annotationToCheck)) { String description = JavaErrorMessages.message("annotation.duplicate.annotation"); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(description) .create(); } PsiAnnotation metaAnno = PsiImplUtil.findAnnotation( annotationType.getModifierList(), CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE); if (metaAnno == null) { String explanation = JavaErrorMessages.message( "annotation.non.repeatable", annotationType.getQualifiedName()); String description = JavaErrorMessages.message("annotation.duplicate.explained", explanation); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(description) .create(); } String explanation = doCheckRepeatableAnnotation(metaAnno); if (explanation != null) { String description = JavaErrorMessages.message("annotation.duplicate.explained", explanation); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(description) .create(); } PsiClass container = getRepeatableContainer(metaAnno); if (container != null) { PsiAnnotation.TargetType[] targets = PsiImplUtil.getTargetsForLocation(owner); PsiAnnotation.TargetType applicable = PsiImplUtil.findApplicableTarget(container, targets); if (applicable == null) { String target = JavaErrorMessages.message("annotation.target." + targets[0]); String message = JavaErrorMessages.message( "annotation.container.not.applicable", container.getName(), target); return annotationError(annotationToCheck, message); } } } for (PsiAnnotation annotation : owner.getAnnotations()) { if (annotation == annotationToCheck) continue; PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) continue; PsiElement aClass = nameRef.resolve(); if (!resolved.equals(aClass)) continue; } return null; }
private static void completeAnnotationAttributeName( CompletionResultSet result, PsiElement insertedElement, CompletionParameters parameters) { PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class); PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList) pair.getParent(); PsiAnnotation anno = (PsiAnnotation) parameterList.getParent(); boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement); PsiClass annoClass = null; final PsiJavaCodeReferenceElement referenceElement = anno.getNameReferenceElement(); if (referenceElement != null) { final PsiElement element = referenceElement.resolve(); if (element instanceof PsiClass) { annoClass = (PsiClass) element; if (annoClass.findMethodsByName("value", false).length == 0) { showClasses = false; } } } if (showClasses && insertedElement.getParent() instanceof PsiReferenceExpression) { final Set<LookupElement> set = JavaCompletionUtil.processJavaReference( insertedElement, (PsiJavaReference) insertedElement.getParent(), new ElementExtractorFilter(createAnnotationFilter(insertedElement)), JavaCompletionProcessor.Options.DEFAULT_OPTIONS, result.getPrefixMatcher(), parameters); for (final LookupElement element : set) { result.addElement(element); } addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result)); } if (annoClass != null) { final PsiNameValuePair[] existingPairs = parameterList.getAttributes(); methods: for (PsiMethod method : annoClass.getMethods()) { if (!(method instanceof PsiAnnotationMethod)) continue; final String attrName = method.getName(); for (PsiNameValuePair existingAttr : existingPairs) { if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break; if (Comparing.equal(existingAttr.getName(), attrName) || PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName) && existingAttr.getName() == null) continue methods; } LookupElementBuilder element = LookupElementBuilder.createWithIcon(method) .withInsertHandler( new InsertHandler<LookupElement>() { @Override public void handleInsert(InsertionContext context, LookupElement item) { final Editor editor = context.getEditor(); TailType.EQ.processTail(editor, editor.getCaretModel().getOffset()); context.setAddCompletionChar(false); context.commitDocument(); PsiAnnotationParameterList paramList = PsiTreeUtil.findElementOfClassAtOffset( context.getFile(), context.getStartOffset(), PsiAnnotationParameterList.class, false); if (paramList != null && paramList.getAttributes().length > 0 && paramList.getAttributes()[0].getName() == null) { int valueOffset = paramList.getAttributes()[0].getTextRange().getStartOffset(); context .getDocument() .insertString( valueOffset, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); TailType.EQ.processTail( editor, valueOffset + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.length()); } } }); PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) method).getDefaultValue(); if (defaultValue != null) { Object constant = JavaPsiFacade.getInstance(method.getProject()) .getConstantEvaluationHelper() .computeConstantExpression(defaultValue); if (constant != null) { element = element.withTailText( " default " + (constant instanceof String ? "\"" + constant + "\"" : constant), true); } } result.addElement(element); } } }