Example #1
0
 private void replaceDocComment(
     @Nullable String newCommentText, @NotNull final PsiDocCommentOwner psiDocCommentOwner) {
   final PsiDocComment oldComment = psiDocCommentOwner.getDocComment();
   if (newCommentText != null) newCommentText = stripSpaces(newCommentText);
   if (newCommentText == null
       || oldComment == null
       || newCommentText.equals(oldComment.getText())) {
     return;
   }
   try {
     PsiComment newComment =
         JavaPsiFacade.getInstance(myProject)
             .getElementFactory()
             .createCommentFromText(newCommentText, null);
     final ASTNode oldNode = oldComment.getNode();
     final ASTNode newNode = newComment.getNode();
     assert oldNode != null && newNode != null;
     final ASTNode parent = oldNode.getTreeParent();
     parent.replaceChild(
         oldNode,
         newNode); // important to replace with tree operation to avoid resolve and repository
     // update
   } catch (IncorrectOperationException e) {
     LOG.error(e);
   }
 }
  @Nullable
  private ProblemDescriptor[] checkMember(
      final PsiDocCommentOwner docCommentOwner,
      final InspectionManager manager,
      final boolean isOnTheFly) {
    final ArrayList<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
    final PsiDocComment docComment = docCommentOwner.getDocComment();
    if (docComment == null) return null;

    final Set<PsiJavaCodeReferenceElement> references = new HashSet<PsiJavaCodeReferenceElement>();
    docComment.accept(getVisitor(references, docCommentOwner, problems, manager, isOnTheFly));
    for (PsiJavaCodeReferenceElement reference : references) {
      final List<PsiClass> classesToImport = new ImportClassFix(reference).getClassesToImport();
      final PsiElement referenceNameElement = reference.getReferenceNameElement();
      problems.add(
          manager.createProblemDescriptor(
              referenceNameElement != null ? referenceNameElement : reference,
              cannotResolveSymbolMessage("<code>" + reference.getText() + "</code>"),
              !isOnTheFly || classesToImport.isEmpty() ? null : new AddImportFix(classesToImport),
              ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
              isOnTheFly));
    }

    return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
  }
 private static PsiDocTag getTextJavaDoc(@NotNull final PsiDocCommentOwner element) {
   final PsiDocComment docComment = element.getDocComment();
   if (docComment != null) {
     return docComment.findTagByName("testng.test");
   }
   return null;
 }
  private static boolean isConfigMethod(PsiMethod method, String[] configAnnotationsFqn) {
    for (String fqn : configAnnotationsFqn) {
      if (AnnotationUtil.isAnnotated(method, fqn, false)) return true;
    }

    if (hasDocTagsSupport) {
      final PsiDocComment comment = method.getDocComment();
      if (comment != null) {
        for (String javadocTag : CONFIG_JAVADOC_TAGS) {
          if (comment.findTagByName(javadocTag) != null) return true;
        }
      }
    }
    return false;
  }
  private void fixJavadocForConstructor(PsiClass psiClass) {
    final PsiDocComment docComment = method.getDocComment();
    if (docComment != null) {
      final List<PsiDocTag> mergedTags = new ArrayList<PsiDocTag>();
      final PsiDocTag[] paramTags = docComment.findTagsByName("param");
      for (PsiDocTag paramTag : paramTags) {
        final PsiElement[] dataElements = paramTag.getDataElements();
        if (dataElements.length > 0) {
          if (dataElements[0] instanceof PsiDocParamRef) {
            final PsiReference reference = dataElements[0].getReference();
            if (reference != null) {
              final PsiElement resolve = reference.resolve();
              if (resolve instanceof PsiParameter) {
                final int parameterIndex =
                    method.getParameterList().getParameterIndex((PsiParameter) resolve);
                if (ArrayUtil.find(paramsToMerge, parameterIndex) < 0) continue;
              }
            }
          }
          mergedTags.add((PsiDocTag) paramTag.copy());
        }
      }

      PsiMethod compatibleParamObjectConstructor = null;
      if (myExistingClassCompatibleConstructor != null
          && myExistingClassCompatibleConstructor.getDocComment() == null) {
        compatibleParamObjectConstructor = myExistingClassCompatibleConstructor;
      } else if (!myUseExistingClass) {
        compatibleParamObjectConstructor = psiClass.getConstructors()[0];
      }

      if (compatibleParamObjectConstructor != null) {
        PsiDocComment psiDocComment =
            JavaPsiFacade.getElementFactory(myProject).createDocCommentFromText("/**\n*/");
        psiDocComment =
            (PsiDocComment)
                compatibleParamObjectConstructor.addBefore(
                    psiDocComment, compatibleParamObjectConstructor.getFirstChild());

        for (PsiDocTag tag : mergedTags) {
          psiDocComment.add(tag);
        }
      }
    }
  }
 @Override
 public void invoke(
     @NotNull final Project project, final Editor editor, @NotNull final PsiElement element)
     throws IncorrectOperationException {
   PsiDocCommentOwner container = getContainer(element);
   assert container != null;
   if (!CodeInsightUtilBase.preparePsiElementForWrite(container)) return;
   if (use15Suppressions(container)) {
     final PsiModifierList modifierList = container.getModifierList();
     if (modifierList != null) {
       addSuppressAnnotation(project, editor, container, container, getID(container));
     }
   } else {
     PsiDocComment docComment = container.getDocComment();
     PsiManager manager = PsiManager.getInstance(project);
     if (docComment == null) {
       String commentText =
           "/** @" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container) + "*/";
       docComment =
           JavaPsiFacade.getInstance(manager.getProject())
               .getElementFactory()
               .createDocCommentFromText(commentText);
       PsiElement firstChild = container.getFirstChild();
       container.addBefore(docComment, firstChild);
     } else {
       PsiDocTag noInspectionTag =
           docComment.findTagByName(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME);
       if (noInspectionTag != null) {
         String tagText = noInspectionTag.getText() + ", " + getID(container);
         noInspectionTag.replace(
             JavaPsiFacade.getInstance(manager.getProject())
                 .getElementFactory()
                 .createDocTagFromText(tagText));
       } else {
         String tagText =
             "@" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container);
         docComment.add(
             JavaPsiFacade.getInstance(manager.getProject())
                 .getElementFactory()
                 .createDocTagFromText(tagText));
       }
     }
   }
   DaemonCodeAnalyzer.getInstance(project).restart();
 }
  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);
  }
  @Override
  public PsiReference getReference() {
    final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
    if (comment == null) return null;
    final PsiDocCommentOwner owner = comment.getOwner();
    if (!(owner instanceof PsiMethod) && !(owner instanceof PsiClass)) return null;
    final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
    if (valueToken == null) return null;
    final String name = valueToken.getText();
    PsiElement reference = null;
    final PsiElement firstChild = getFirstChild();
    if (firstChild instanceof PsiDocToken
        && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
      final PsiTypeParameter[] typeParameters =
          ((PsiTypeParameterListOwner) owner).getTypeParameters();
      for (PsiTypeParameter typeParameter : typeParameters) {
        if (typeParameter.getName().equals(name)) {
          reference = typeParameter;
        }
      }
    } else if (owner instanceof PsiMethod) {
      final PsiParameter[] parameters = ((PsiMethod) owner).getParameterList().getParameters();
      for (PsiParameter parameter : parameters) {
        if (parameter.getName().equals(name)) {
          reference = parameter;
        }
      }
    }

    final PsiElement resultReference = reference;
    return new PsiJavaReference() {
      @Override
      public PsiElement resolve() {
        return resultReference;
      }

      @Override
      @NotNull
      public String getCanonicalText() {
        return valueToken.getText();
      }

      @Override
      public PsiElement handleElementRename(String newElementName) {
        final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(getNode());
        LeafElement newElement =
            Factory.createSingleLeafElement(
                JavaDocTokenType.DOC_TAG_VALUE_TOKEN,
                newElementName,
                charTableByTree,
                getManager());
        replaceChild(valueToken, newElement);
        return PsiDocParamRef.this;
      }

      @Override
      public PsiElement bindToElement(@NotNull PsiElement element)
          throws IncorrectOperationException {
        if (isReferenceTo(element)) return PsiDocParamRef.this;
        if (!(element instanceof PsiParameter)) {
          throw new IncorrectOperationException("Unsupported operation");
        }
        return handleElementRename(((PsiParameter) element).getName());
      }

      @Override
      public boolean isReferenceTo(PsiElement element) {
        if (!(element instanceof PsiNamedElement)) return false;
        PsiNamedElement namedElement = (PsiNamedElement) element;
        if (!getCanonicalText().equals(namedElement.getName())) return false;
        return getManager().areElementsEquivalent(resolve(), element);
      }

      @Override
      @NotNull
      public PsiElement[] getVariants() {
        final PsiElement firstChild = getFirstChild();

        Set<String> usedNames = new HashSet<String>();
        for (PsiDocTag tag : comment.getTags()) {
          if (tag.getName().equals("param")) {
            PsiDocTagValue valueElement = tag.getValueElement();
            if (valueElement != null) {
              usedNames.add(valueElement.getText());
            }
          }
        }

        PsiNamedElement[] result = PsiNamedElement.EMPTY_ARRAY;
        if (firstChild instanceof PsiDocToken
            && ((PsiDocToken) firstChild)
                .getTokenType()
                .equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
          result = ((PsiTypeParameterListOwner) owner).getTypeParameters();
        } else if (owner instanceof PsiMethod) {
          result = ((PsiMethod) owner).getParameterList().getParameters();
        }
        List<PsiElement> filtered = new ArrayList<PsiElement>();
        for (PsiNamedElement namedElement : result) {
          if (!usedNames.contains(namedElement.getName())) {
            filtered.add(namedElement);
          }
        }
        return filtered.toArray(new PsiElement[filtered.size()]);
      }

      @Override
      public boolean isSoft() {
        return false;
      }

      @Override
      public TextRange getRangeInElement() {
        final int startOffsetInParent = valueToken.getPsi().getStartOffsetInParent();
        return new TextRange(startOffsetInParent, startOffsetInParent + valueToken.getTextLength());
      }

      @Override
      public PsiElement getElement() {
        return PsiDocParamRef.this;
      }

      @Override
      public void processVariants(PsiScopeProcessor processor) {
        for (final PsiElement element : getVariants()) {
          if (!processor.execute(element, ResolveState.initial())) {
            return;
          }
        }
      }

      @Override
      @NotNull
      public JavaResolveResult advancedResolve(boolean incompleteCode) {
        return resultReference == null
            ? JavaResolveResult.EMPTY
            : new CandidateInfo(resultReference, PsiSubstitutor.EMPTY);
      }

      @Override
      @NotNull
      public JavaResolveResult[] multiResolve(boolean incompleteCode) {
        return resultReference == null
            ? JavaResolveResult.EMPTY_ARRAY
            : new JavaResolveResult[] {new CandidateInfo(resultReference, PsiSubstitutor.EMPTY)};
      }
    };
  }
 public static boolean isDeprecatedByDocTag(@NotNull PsiDocCommentOwner owner) {
   PsiDocComment docComment = owner.getDocComment();
   return docComment != null && docComment.findTagByName("deprecated") != null;
 }
  public String generateDocumentationContentStub(PsiComment contextComment) {
    if (!(contextComment instanceof GrDocComment)) {
      return null;
    }

    final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment);
    if (owner == null) return null;

    Project project = contextComment.getProject();
    final CodeDocumentationAwareCommenter commenter =
        (CodeDocumentationAwareCommenter)
            LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage());

    StringBuilder builder = StringBuilderSpinAllocator.alloc();
    try {
      if (owner instanceof GrMethod) {
        final GrMethod method = (GrMethod) owner;
        final GrParameter[] parameters = method.getParameters();
        final Map<String, String> param2Description = new HashMap<String, String>();
        final PsiMethod[] superMethods = method.findSuperMethods();

        for (PsiMethod superMethod : superMethods) {
          final PsiDocComment comment = superMethod.getDocComment();
          if (comment != null) {
            final PsiDocTag[] params = comment.findTagsByName("param");
            for (PsiDocTag param : params) {
              final PsiElement[] dataElements = param.getDataElements();
              if (dataElements != null) {
                String paramName = null;
                for (PsiElement dataElement : dataElements) {
                  if (dataElement instanceof PsiDocParamRef) {
                    paramName = dataElement.getReference().getCanonicalText();
                    break;
                  }
                }
                if (paramName != null) {
                  param2Description.put(paramName, param.getText());
                }
              }
            }
          }
        }
        for (PsiParameter parameter : parameters) {
          String description = param2Description.get(parameter.getName());
          if (description != null) {
            builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
            if (description.indexOf('\n') > -1)
              description = description.substring(0, description.lastIndexOf('\n'));
            builder.append(description);
          } else {
            builder.append(
                CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
            builder.append(parameter.getName());
          }
          builder.append(LINE_SEPARATOR);
        }

        final PsiType returnType = method.getInferredReturnType();
        if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF))
            && returnType != PsiType.VOID) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter));
          builder.append(LINE_SEPARATOR);
        }

        final PsiClassType[] references = method.getThrowsList().getReferencedTypes();
        for (PsiClassType reference : references) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter));
          builder.append(reference.getClassName());
          builder.append(LINE_SEPARATOR);
        }
      } else if (owner instanceof GrTypeDefinition) {
        final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList();
        if (typeParameterList != null) {
          createTypeParamsListComment(builder, project, commenter, typeParameterList);
        }
      }
      return builder.length() > 0 ? builder.toString() : null;
    } finally {
      StringBuilderSpinAllocator.dispose(builder);
    }
  }