@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); } } }
/** * 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; }
/** * 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); }