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(); }
@Nullable public static PsiAnnotationMemberValue setDeclaredAttributeValue( @NotNull PsiAnnotation psiAnnotation, @Nullable String attributeName, @Nullable PsiAnnotationMemberValue value, @NotNull PairFunction<Project, String, PsiAnnotation> annotationCreator) { PsiAnnotationMemberValue existing = psiAnnotation.findDeclaredAttributeValue(attributeName); if (value == null) { if (existing == null) { return null; } existing.getParent().delete(); } else { if (existing != null) { ((PsiNameValuePair) existing.getParent()).setValue(value); } else { PsiNameValuePair[] attributes = psiAnnotation.getParameterList().getAttributes(); if (attributes.length == 1) { PsiNameValuePair attribute = attributes[0]; if (attribute.getName() == null) { PsiAnnotationMemberValue defValue = attribute.getValue(); assert defValue != null : attribute; attribute.replace( createNameValuePair( defValue, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME + "=", annotationCreator)); } } boolean allowNoName = attributes.length == 0 && ("value".equals(attributeName) || null == attributeName); final String namePrefix; if (allowNoName) { namePrefix = ""; } else { namePrefix = attributeName + "="; } psiAnnotation .getParameterList() .addBefore(createNameValuePair(value, namePrefix, annotationCreator), null); } } return psiAnnotation.findDeclaredAttributeValue(attributeName); }
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; }
private static PsiAnnotation createNewAnnotation( final Project project, final Editor editor, final PsiElement container, @Nullable final PsiAnnotation annotation, final String id) { if (annotation != null) { final String currentSuppressedId = "\"" + id + "\""; if (!annotation.getText().contains("{")) { final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); if (attributes.length == 1) { final String suppressedWarnings = attributes[0].getText(); if (suppressedWarnings.contains(currentSuppressedId)) return null; return JavaPsiFacade.getInstance(project) .getElementFactory() .createAnnotationFromText( "@" + SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME + "({" + suppressedWarnings + ", " + currentSuppressedId + "})", container); } } else { final int curlyBraceIndex = annotation.getText().lastIndexOf("}"); if (curlyBraceIndex > 0) { final String oldSuppressWarning = annotation.getText().substring(0, curlyBraceIndex); if (oldSuppressWarning.contains(currentSuppressedId)) return null; return JavaPsiFacade.getInstance(project) .getElementFactory() .createAnnotationFromText( oldSuppressWarning + ", " + currentSuppressedId + "})", container); } else if (!ApplicationManager.getApplication().isUnitTestMode() && editor != null) { Messages.showErrorDialog( editor.getComponent(), InspectionsBundle.message( "suppress.inspection.annotation.syntax.error", annotation.getText())); } } } else { return JavaPsiFacade.getInstance(project) .getElementFactory() .createAnnotationFromText( "@" + SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME + "(\"" + id + "\")", container); } return null; }
public static PsiAnnotationMemberValue getAnnotationMemberValue( PsiAnnotation annotation, String attributeName) { final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { if (attributeName.equals(attribute.getName())) { final PsiAnnotationMemberValue value = attribute.getValue(); if (value != null) { return value; } break; } } 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; }
@Nullable public static PsiAnnotationMemberValue findDeclaredAttributeValue( @NotNull PsiAnnotation annotation, @NonNls String attributeName) { if ("value".equals(attributeName)) attributeName = null; PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { @NonNls final String name = attribute.getName(); if (Comparing.equal(name, attributeName) || attributeName == null && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)) { return attribute.getValue(); } } return null; }
@NotNull static String getKotlinSignature(@NotNull PsiAnnotation kotlinSignatureAnnotation) { PsiNameValuePair pair = kotlinSignatureAnnotation.getParameterList().getAttributes()[0]; PsiAnnotationMemberValue value = pair.getValue(); if (value == null) { return "null"; } else if (value instanceof PsiLiteralExpression) { Object valueObject = ((PsiLiteralExpression) value).getValue(); return valueObject == null ? "null" : StringUtil.unescapeStringCharacters(valueObject.toString()); } else { return value.getText(); } }
@Nullable static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) { if (!(element instanceof PsiModifierListOwner)) return null; PsiModifierListOwner annotationOwner = getAnnotationOwner(element); PsiAnnotation ownAnnotation = PsiBasedExternalAnnotationResolver.findOwnAnnotation(annotationOwner, KOTLIN_SIGNATURE); PsiAnnotation annotation = ownAnnotation != null ? ownAnnotation : PsiBasedExternalAnnotationResolver.findExternalAnnotation( annotationOwner, KOTLIN_SIGNATURE.getFqName()); if (annotation == null) return null; if (annotation.getParameterList().getAttributes().length == 0) return null; return annotation; }
@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; }
@Override public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { if (first.getElementType() == NAME_VALUE_PAIR && last.getElementType() == NAME_VALUE_PAIR) { final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); ASTNode lparenth = findChildByRole(ChildRole.LPARENTH); if (lparenth == null) { LeafElement created = Factory.createSingleLeafElement(LPARENTH, "(", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getFirstChildNode(), true); } ASTNode rparenth = findChildByRole(ChildRole.RPARENTH); if (rparenth == null) { LeafElement created = Factory.createSingleLeafElement(RPARENTH, ")", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getLastChildNode(), false); } final ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET); if (nodes.length == 1) { final ASTNode node = nodes[0]; if (node instanceof PsiNameValuePair) { final PsiNameValuePair pair = (PsiNameValuePair) node; if (pair.getName() == null) { final String text = pair.getValue().getText(); try { final PsiAnnotation annotation = JavaPsiFacade.getInstance(getProject()) .getElementFactory() .createAnnotationFromText("@AAA(value = " + text + ")", null); replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode()); } catch (IncorrectOperationException e) { LOG.error(e); } } } } if (anchor == null && before != null) { anchor = findChildByRole(before.booleanValue() ? ChildRole.RPARENTH : ChildRole.LPARENTH); } } return super.addInternal(first, last, anchor, before); }
@Override public List<PsiLiteralExpression> getTargets() { final List<PsiLiteralExpression> result = new ArrayList<PsiLiteralExpression>(); if (mySuppressedExpression != null) { result.add(mySuppressedExpression); return result; } final PsiAnnotationParameterList list = myTarget.getParameterList(); final PsiNameValuePair[] attributes = list.getAttributes(); for (PsiNameValuePair attribute : attributes) { final PsiAnnotationMemberValue value = attribute.getValue(); if (value instanceof PsiArrayInitializerMemberValue) { final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue) value).getInitializers(); for (PsiAnnotationMemberValue initializer : initializers) { if (initializer instanceof PsiLiteralExpression) { result.add((PsiLiteralExpression) initializer); } } } } return result; }
public static void addSuppressAnnotation( final Project project, final Editor editor, final PsiElement container, final PsiModifierListOwner modifierOwner, final String id) throws IncorrectOperationException { PsiAnnotation annotation = AnnotationUtil.findAnnotation( modifierOwner, SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME); final PsiAnnotation newAnnotation = createNewAnnotation(project, editor, container, annotation, id); if (newAnnotation != null) { if (annotation != null && annotation.isPhysical()) { annotation.replace(newAnnotation); } else { final PsiNameValuePair[] attributes = newAnnotation.getParameterList().getAttributes(); new AddAnnotationFix( SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME, modifierOwner, attributes) .invoke(project, editor, container.getContainingFile()); } } }
public static AnnotationValueElement getValueStringFromAnnotationWithDefault( PsiAnnotation annotation) { final PsiAnnotationParameterList parameterList = annotation.getParameterList(); final PsiNameValuePair[] attributes = parameterList.getAttributes(); final PsiElement logicalElement = getImmediateOwnerElement(annotation); if (logicalElement == null) { return null; } final String value; final PsiElement errorElement; if (attributes.length == 0) { value = getNameOfElement(logicalElement); errorElement = annotation; } else { final String text = attributes[0].getText(); value = text.substring(1, text.length() - 1); errorElement = attributes[0]; } return new AnnotationValueElement(value, errorElement); }
@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); } } } }