/**
   * Returns the tags in a javadoc comment. Only finds throws, exception, param, return and see
   * tags.
   *
   * @param comment the Javadoc comment
   * @return the tags found
   */
  private static List<JavadocTag> getMethodTags(TextBlock comment) {
    final String[] lines = comment.getText();
    final List<JavadocTag> tags = Lists.newArrayList();
    int currentLine = comment.getStartLineNo() - 1;
    final int startColumnNumber = comment.getStartColNo();

    for (int i = 0; i < lines.length; i++) {
      currentLine++;
      final Matcher javadocArgMatcher = MATCH_JAVADOC_ARG.matcher(lines[i]);
      final Matcher javadocNoargMatcher = MATCH_JAVADOC_NOARG.matcher(lines[i]);
      final Matcher noargCurlyMatcher = MATCH_JAVADOC_NOARG_CURLY.matcher(lines[i]);
      final Matcher argMultilineStart = MATCH_JAVADOC_ARG_MULTILINE_START.matcher(lines[i]);
      final Matcher noargMultilineStart = MATCH_JAVADOC_NOARG_MULTILINE_START.matcher(lines[i]);

      if (javadocArgMatcher.find()) {
        final int col = calculateTagColumn(javadocArgMatcher, i, startColumnNumber);
        tags.add(
            new JavadocTag(
                currentLine, col, javadocArgMatcher.group(1), javadocArgMatcher.group(2)));
      } else if (javadocNoargMatcher.find()) {
        final int col = calculateTagColumn(javadocNoargMatcher, i, startColumnNumber);
        tags.add(new JavadocTag(currentLine, col, javadocNoargMatcher.group(1)));
      } else if (noargCurlyMatcher.find()) {
        final int col = calculateTagColumn(noargCurlyMatcher, i, startColumnNumber);
        tags.add(new JavadocTag(currentLine, col, noargCurlyMatcher.group(1)));
      } else if (argMultilineStart.find()) {
        final int col = calculateTagColumn(argMultilineStart, i, startColumnNumber);
        tags.addAll(getMultilineArgTags(argMultilineStart, col, lines, i, currentLine));
      } else if (noargMultilineStart.find()) {
        tags.addAll(getMultilineNoArgTags(noargMultilineStart, lines, i, currentLine));
      }
    }
    return tags;
  }
  @Override
  public void beginTree(DetailAST rootAST) {
    final Map<Integer, TextBlock> cppComments = getFileContents().getCppComments();
    final Map<Integer, List<TextBlock>> cComments = getFileContents().getCComments();
    final Set<Integer> lines = Sets.newHashSet();
    lines.addAll(cppComments.keySet());
    lines.addAll(cComments.keySet());

    for (Integer lineNo : lines) {
      final String line = getLines()[lineNo - 1];
      final String lineBefore;
      final TextBlock comment;
      if (cppComments.containsKey(lineNo)) {
        comment = cppComments.get(lineNo);
        lineBefore = line.substring(0, comment.getStartColNo());
      } else {
        final List<TextBlock> commentList = cComments.get(lineNo);
        comment = commentList.get(commentList.size() - 1);
        lineBefore = line.substring(0, comment.getStartColNo());

        // do not check comment which doesn't end line
        if (comment.getText().length == 1
            && !line.substring(comment.getEndColNo() + 1).trim().isEmpty()) {
          continue;
        }
      }
      if (!regexp.matcher(lineBefore).find() && !isLegalComment(comment)) {
        log(lineNo, MSG_KEY);
      }
    }
  }
 /**
  * Appends the suppressions in a collection of comments to the full set of suppression tags.
  *
  * @param comments the set of comments.
  */
 private void tagSuppressions(Collection<TextBlock> comments) {
   for (final TextBlock comment : comments) {
     final int startLineNo = comment.getStartLineNo();
     final String[] text = comment.getText();
     tagCommentLine(text[0], startLineNo);
     for (int i = 1; i < text.length; i++) {
       tagCommentLine(text[i], startLineNo + i);
     }
   }
 }
  @Override
  public void visitToken(DetailAST ast) {
    if (this.currentVersion == null) {
      // If not current version is set, just ignore this check

      return;
    }

    switch (ast.getType()) {
      case TokenTypes.PACKAGE_DEF:
        // Save the package
        FullIdent ident = FullIdent.createFullIdent(ast.getLastChild().getPreviousSibling());
        this.packageName = ident.getText();
        return;
      case TokenTypes.CLASS_DEF:
      case TokenTypes.INTERFACE_DEF:
        this.classOrInterfaceName = ast.findFirstToken(TokenTypes.IDENT).getText();
        break;
    }

    if (AnnotationUtility.containsAnnotation(ast)) {
      DetailAST holder = AnnotationUtility.getAnnotationHolder(ast);
      for (DetailAST annotation : findAllTokens(holder, TokenTypes.ANNOTATION)) {
        String annotationName = annotation.findFirstToken(TokenTypes.IDENT).getText();
        if (annotationName.equals("Unstable")) {
          FileContents contents = getFileContents();
          String annotatedElementName = ast.findFirstToken(TokenTypes.IDENT).getText();
          // Get the Javadoc before the annotation in order to locate a @Since annotation and to
          // extract
          // the XWiki version mentioned there.
          List<String> sinceVersions = Collections.emptyList();
          TextBlock cmt = contents.getJavadocBefore(ast.getLineNo());
          if (cmt != null) {
            sinceVersions =
                extractSinceVersionsFromJavadoc(cmt.getText(), annotation, annotatedElementName);
          }
          if (sinceVersions.isEmpty()) {
            log(
                annotation.getLineNo(),
                annotation.getColumnNo(),
                String.format(
                    "There is an @Unstable "
                        + "annotation for [%s] but the @since javadoc tag is missing, you must add it!",
                    computeElementName(annotatedElementName)));
            return;
          }
          checkSinceVersions(sinceVersions, annotation, annotatedElementName);
        }
      }
    }
  }
  /**
   * Checks if given comment is legal (single-line and matches to the pattern).
   *
   * @param comment comment to check.
   * @return true if the comment if legal.
   */
  private boolean isLegalComment(final TextBlock comment) {
    final boolean legal;

    // multi-line comment can not be legal
    if (legalComment == null || comment.getStartLineNo() != comment.getEndLineNo()) {
      legal = false;
    } else {
      String commentText = comment.getText()[0];
      // remove chars which start comment
      commentText = commentText.substring(2);
      // if this is a C-style comment we need to remove its end
      if (commentText.endsWith("*/")) {
        commentText = commentText.substring(0, commentText.length() - 2);
      }
      commentText = commentText.trim();
      legal = legalComment.matcher(commentText).find();
    }
    return legal;
  }
  /**
   * Checks to see if the text block contains a inheritDoc tag.
   *
   * @param javadoc the javadoc of the AST
   * @return true if contains the tag
   */
  private static boolean containsJavadocTag(final TextBlock javadoc) {
    if (javadoc == null) {
      return false;
    }

    final String[] lines = javadoc.getText();

    for (final String line : lines) {
      final Matcher matchInheritDoc = MATCH_INHERITDOC.matcher(line);

      if (matchInheritDoc.find()) {
        return true;
      }
    }
    return false;
  }
Beispiel #7
0
 /**
  * Gets validTags from a given piece of Javadoc.
  *
  * @param cmt the Javadoc comment to process.
  * @param tagType the type of validTags we're interested in
  * @return all standalone validTags from the given javadoc.
  */
 public static JavadocTags getJavadocTags(TextBlock cmt, JavadocTagType tagType) {
   final String[] text = cmt.getText();
   final List<JavadocTag> tags = Lists.newArrayList();
   final List<InvalidJavadocTag> invalidTags = Lists.newArrayList();
   Pattern blockTagPattern = Pattern.compile("/\\*{2,}\\s*@(\\p{Alpha}+)\\s");
   for (int i = 0; i < text.length; i++) {
     final String s = text[i];
     final Matcher blockTagMatcher = blockTagPattern.matcher(s);
     if ((tagType == JavadocTagType.ALL || tagType == JavadocTagType.BLOCK)
         && blockTagMatcher.find()) {
       final String tagName = blockTagMatcher.group(1);
       String content = s.substring(blockTagMatcher.end(1));
       if (content.endsWith("*/")) {
         content = content.substring(0, content.length() - 2);
       }
       final int line = cmt.getStartLineNo() + i;
       int col = blockTagMatcher.start(1) - 1;
       if (i == 0) {
         col += cmt.getStartColNo();
       }
       if (JavadocTagInfo.isValidName(tagName)) {
         tags.add(new JavadocTag(line, col, tagName, content.trim()));
       } else {
         invalidTags.add(new InvalidJavadocTag(line, col, tagName));
       }
     }
     // No block tag, so look for inline validTags
     else if (tagType == JavadocTagType.ALL || tagType == JavadocTagType.INLINE) {
       // Match Javadoc text after comment characters
       final Pattern commentPattern = Pattern.compile("^\\s*(?:/\\*{2,}|\\*+)\\s*(.*)");
       final Matcher commentMatcher = commentPattern.matcher(s);
       final String commentContents;
       final int commentOffset; // offset including comment characters
       if (!commentMatcher.find()) {
         commentContents = s; // No leading asterisks, still valid
         commentOffset = 0;
       } else {
         commentContents = commentMatcher.group(1);
         commentOffset = commentMatcher.start(1) - 1;
       }
       final Pattern tagPattern = Pattern.compile(".*?\\{@(\\p{Alpha}+)\\s+(.*?)\\}");
       final Matcher tagMatcher = tagPattern.matcher(commentContents);
       while (tagMatcher.find()) {
         final String tagName = tagMatcher.group(1);
         final String tagValue = tagMatcher.group(2).trim();
         final int line = cmt.getStartLineNo() + i;
         int col = commentOffset + tagMatcher.start(1) - 1;
         if (i == 0) {
           col += cmt.getStartColNo();
         }
         if (JavadocTagInfo.isValidName(tagName)) {
           tags.add(new JavadocTag(line, col, tagName, tagValue));
         } else {
           invalidTags.add(new InvalidJavadocTag(line, col, tagName));
         }
         // else Error: Unexpected match count for inline Javadoc
         // tag!
       }
     }
     blockTagPattern = Pattern.compile("^\\s*\\**\\s*@(\\p{Alpha}+)\\s");
   }
   return new JavadocTags(tags, invalidTags);
 }