/** * Checks if the given parameter is final. * * @param param parameter to check. */ private void checkParam(final DetailAST param) { if (!param.branchContains(TokenTypes.FINAL) && !isIgnoredParam(param) && !CheckUtils.isReceiverParameter(param)) { final DetailAST paramName = param.findFirstToken(TokenTypes.IDENT); final DetailAST firstNode = CheckUtils.getFirstNode(param); log(firstNode.getLineNo(), firstNode.getColumnNo(), MSG_KEY, paramName.getText()); } }
@Override public void visitToken(DetailAST ast) { equalsMethods.clear(); // examine method definitions for equals methods final DetailAST objBlock = ast.findFirstToken(TokenTypes.OBJBLOCK); if (objBlock != null) { DetailAST child = objBlock.getFirstChild(); boolean hasEqualsObject = false; while (child != null) { if (child.getType() == TokenTypes.METHOD_DEF && CheckUtils.isEqualsMethod(child)) { if (isFirstParameterObject(child)) { hasEqualsObject = true; } else { equalsMethods.add(child); } } child = child.getNextSibling(); } // report equals method definitions if (!hasEqualsObject) { for (DetailAST equalsAST : equalsMethods) { final DetailAST nameNode = equalsAST.findFirstToken(TokenTypes.IDENT); log(nameNode.getLineNo(), nameNode.getColumnNo(), MSG_KEY); } } } }
/** * Checks the Javadoc for a method. * * @param ast the token for the method * @param comment the Javadoc comment */ private void checkComment(DetailAST ast, TextBlock comment) { final List<JavadocTag> tags = getMethodTags(comment); if (hasShortCircuitTag(ast, tags)) { return; } final Iterator<JavadocTag> it = tags.iterator(); if (ast.getType() != TokenTypes.ANNOTATION_FIELD_DEF) { // Check for inheritDoc boolean hasInheritDocTag = false; while (it.hasNext() && !hasInheritDocTag) { hasInheritDocTag = it.next().isInheritDocTag(); } checkParamTags(tags, ast, !hasInheritDocTag); checkThrowsTags(tags, getThrows(ast), !hasInheritDocTag); if (CheckUtils.isVoidMethod(ast)) { checkReturnTag(tags, ast.getLineNo(), !hasInheritDocTag); } } // Dump out all unused tags for (JavadocTag javadocTag : tags) { if (!javadocTag.isSeeOrInheritDocTag()) { log(javadocTag.getLineNo(), MSG_UNUSED_TAG_GENERAL); } } }
/** * Checks a set of tags for matching parameters. * * @param tags the tags to check * @param parent the node which takes the parameters * @param reportExpectedTags whether we should report if do not find expected tag */ private void checkParamTags( final List<JavadocTag> tags, final DetailAST parent, boolean reportExpectedTags) { final List<DetailAST> params = getParameters(parent); final List<DetailAST> typeParams = CheckUtils.getTypeParameters(parent); // Loop over the tags, checking to see they exist in the params. final ListIterator<JavadocTag> tagIt = tags.listIterator(); while (tagIt.hasNext()) { final JavadocTag tag = tagIt.next(); if (!tag.isParamTag()) { continue; } tagIt.remove(); final String arg1 = tag.getFirstArg(); boolean found = removeMatchingParam(params, arg1); if (CommonUtils.startsWithChar(arg1, '<') && CommonUtils.endsWithChar(arg1, '>')) { // Loop looking for matching type param final Iterator<DetailAST> typeParamsIt = typeParams.iterator(); while (typeParamsIt.hasNext()) { final DetailAST typeParam = typeParamsIt.next(); if (typeParam .findFirstToken(TokenTypes.IDENT) .getText() .equals(arg1.substring(1, arg1.length() - 1))) { found = true; typeParamsIt.remove(); break; } } } // Handle extra JavadocTag if (!found) { log(tag.getLineNo(), tag.getColumnNo(), MSG_UNUSED_TAG, "@param", arg1); } } // Now dump out all type parameters/parameters without tags :- unless // the user has chosen to suppress these problems if (!allowMissingParamTags && reportExpectedTags) { for (DetailAST param : params) { log(param, MSG_EXCPECTED_TAG, JavadocTagInfo.PARAM.getText(), param.getText()); } for (DetailAST typeParam : typeParams) { log( typeParam, MSG_EXCPECTED_TAG, JavadocTagInfo.PARAM.getText(), "<" + typeParam.findFirstToken(TokenTypes.IDENT).getText() + ">"); } } }
/** * Creates new parameter set for given method. * * @param ast a method for process. */ private void visitMethodParameters(DetailAST ast) { DetailAST parameterDefAST = ast.findFirstToken(TokenTypes.PARAMETER_DEF); while (parameterDefAST != null) { if (parameterDefAST.getType() == TokenTypes.PARAMETER_DEF && !CheckUtils.isReceiverParameter(parameterDefAST)) { final DetailAST param = parameterDefAST.findFirstToken(TokenTypes.IDENT); parameterNames.add(param.getText()); } parameterDefAST = parameterDefAST.getNextSibling(); } }
/** * @param expr node to check. * @return true if given node contains numeric constant for zero. */ private static boolean isZero(DetailAST expr) { final int type = expr.getType(); switch (type) { case TokenTypes.NUM_FLOAT: case TokenTypes.NUM_DOUBLE: case TokenTypes.NUM_INT: case TokenTypes.NUM_LONG: final String text = expr.getText(); return Double.compare(CheckUtils.parseDouble(text, type), 0.0) == 0; default: return false; } }
/** * The JavadocMethodCheck is about to report a missing Javadoc. This hook can be used by derived * classes to allow a missing javadoc in some situations. The default implementation checks {@code * allowMissingJavadoc} and {@code allowMissingPropertyJavadoc} properties, do not forget to call * {@code super.isMissingJavadocAllowed(ast)} in case you want to keep this logic. * * @param ast the tree node for the method or constructor. * @return True if this method or constructor doesn't need Javadoc. */ protected boolean isMissingJavadocAllowed(final DetailAST ast) { return allowMissingJavadoc || allowMissingPropertyJavadoc && (CheckUtils.isSetterMethod(ast) || CheckUtils.isGetterMethod(ast)) || matchesSkipRegex(ast); }
@Override public void leaveToken(DetailAST literalIf) { if (!CheckUtils.isElseIf(literalIf)) { nestOut(); } }
@Override public void visitToken(DetailAST literalIf) { if (!CheckUtils.isElseIf(literalIf)) { nestIn(literalIf, MSG_KEY); } }