All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openhab.tools.analysis.checkstyle.JavadocMethodStyleCheck Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2010-2025 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.openhab.tools.analysis.checkstyle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FileContents;
import com.puppycrawl.tools.checkstyle.api.TextBlock;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.checks.javadoc.MissingJavadocMethodCheck;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

/**
 * Checks the javadoc comment of a method or constructor and generates a message if:
 *
 * 

* - There is a dash between the parameter name and the description: *

* *
 *     @param parameter_name - parameter_description
 * 
* *

* - There are empty lines between tags: *

* *
 *     @param parameter_name parameter_description
 *
 *     @param parameter_name parameter_description
 * 
* *

* - The parameter description starts on a new line: *

* *
 *     @param parameter_name
 *                           parameter_description
 * 
* * @author Kristina Simova - Initial contribution * */ public class JavadocMethodStyleCheck extends AbstractCheck { private static final Pattern CONTAINS_DASH_PATTERN = CommonUtil .createPattern("@(throws|exception|param|return){1}\\s+(\\w+)?\\s*\\-+"); private static final Pattern DESCRIPTION_ON_NEW_LINE_PATTERN = CommonUtil.createPattern( "@(throws|exception|param|return){1}\\s*(\\w+)?\\s*\\-*\\s*(\\*{1}(\\s*\\w+)+)", Pattern.MULTILINE); private static final Pattern TAG_PATTERN = CommonUtil.createPattern("@(throws|exception|param|return){1}"); private static final String MESSAGE_DASH_BETWEEN_PARAM_NAME_DESCRIPTION = "There should be no dash between the parameter name and the description in a Javadoc comment of a method or constructor."; private static final String MESSAGE_EMPTY_LINE_BETWEEN_TAGS = "There should be no empty lines between tags in a Javadoc comment of a method or constructor."; private static final String MESSAGE_PARAMETER_DESCRIPTION_NEW_LINE = "The parameter description in a Javadoc comment of a method or constructor should not start on a new line."; /** * Matches whole line with dash between parameter name and parameter description */ private static final int GROUP_DASH = 0; /** * Matches the whole new line with description */ private static final int GROUP_NEW_LINE = 3; private Map lineNumberToLineText; private List tagLines; /** * Controls whether to allow missing Javadoc on accessor methods for * properties (setters and getters). It is a configuration property * and can be changed through the check's configuration. By default * is true. */ private boolean allowMissingPropertyJavadoc; /** * Controls whether to ignore if there is no javadoc for a property accessor (setter/getter methods). It is a * configuration property and can be changed through the check's configuration. By default is true. * * @param allowMissingPropertyJavadoc a boolean value that controls whether to ignore missing javadoc */ public void setAllowMissingPropertyJavadoc(boolean allowMissingPropertyJavadoc) { this.allowMissingPropertyJavadoc = allowMissingPropertyJavadoc; } @Override public int[] getDefaultTokens() { return getAcceptableTokens(); } @Override public int[] getAcceptableTokens() { // The check will be executed for method and constructor declarations. return new int[] { TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF, }; } @Override public int[] getRequiredTokens() { return CommonUtil.EMPTY_INT_ARRAY; } @Override public void visitToken(DetailAST ast) { boolean skipCheck = (MissingJavadocMethodCheck.isSetterMethod(ast) || MissingJavadocMethodCheck.isGetterMethod(ast)) && allowMissingPropertyJavadoc; if (!skipCheck) { visit(ast); } } private void visit(DetailAST ast) { FileContents contents = getFileContents(); int methodLineNumber = ast.getLineNo(); TextBlock textBlock = contents.getJavadocBefore(methodLineNumber); if (textBlock != null) { String[] text = textBlock.getText(); lineNumberToLineText = new HashMap<>(); tagLines = new ArrayList<>(); for (int javadocLineIndex = 0; javadocLineIndex < text.length; javadocLineIndex++) { int lineNo = methodLineNumber - text.length + javadocLineIndex; String line = text[javadocLineIndex]; Matcher tagMatcher = TAG_PATTERN.matcher(line); if (tagMatcher.find()) { tagLines.add(javadocLineIndex); } lineNumberToLineText.put(lineNo, line); } checkComment(methodLineNumber, text); } // when the text block is null, it should be handled by ExportedJavadocMethodCheck } /** * Checks javadoc comment of a method or constructor for dashes between parameter name and parameter description, * parameter description starting on a new line and empty lines between tags. * * @param methodLineNumber the line number where the method or constructor starts * @param javadocComment the javadoc before a method or constructor */ private void checkComment(int methodLineNumber, String[] javadocComment) { String joinedText = String.join("\n", javadocComment); Matcher containsDashMatcher = CONTAINS_DASH_PATTERN.matcher(joinedText); Matcher descriptionNewLineMatcher = DESCRIPTION_ON_NEW_LINE_PATTERN.matcher(joinedText); while (containsDashMatcher.find()) { String group = containsDashMatcher.group(GROUP_DASH); logInformation(group, MESSAGE_DASH_BETWEEN_PARAM_NAME_DESCRIPTION); } while (descriptionNewLineMatcher.find()) { String group = descriptionNewLineMatcher.group(GROUP_NEW_LINE); logInformation(group, MESSAGE_PARAMETER_DESCRIPTION_NEW_LINE); } if (tagLines.size() > 1) { int firstTagLine = tagLines.get(0); int lastTagLine = tagLines.get(tagLines.size() - 1); for (int javadocLineIndex = firstTagLine + 1; javadocLineIndex < lastTagLine; javadocLineIndex++) { String commentLine = javadocComment[javadocLineIndex]; commentLine = commentLine.replace("*", " ").trim(); if (commentLine.isEmpty()) { int lineNo = methodLineNumber - javadocComment.length + javadocLineIndex; log(lineNo, MESSAGE_EMPTY_LINE_BETWEEN_TAGS); } } } } /** * Iterates over map and logs message where the match is found. * * @param group the actual text that the regular expression matches * @param message the message to log */ private void logInformation(String group, String message) { lineNumberToLineText.forEach((lineNumber, lineText) -> { if (lineText.contains(group)) { log(lineNumber, message); } }); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy