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();
 }
예제 #2
0
  @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;
  }
예제 #6
0
 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;
 }
예제 #7
0
 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;
 }
예제 #8
0
 @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;
 }
예제 #9
0
 @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();
   }
 }
예제 #10
0
 @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;
 }
예제 #14
0
 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());
     }
   }
 }
예제 #15
0
  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);
       }
     }
   }
 }