Added WriteTag check which outputs a JavaDoc tag as information (patch 902110). Thanks to Daniel Grenner (dgrenner) for contribution.
This commit is contained in:
parent
ea4085cd15
commit
96c668724b
|
|
@ -334,6 +334,7 @@
|
|||
<mkdir dir="${target.dir}/style/noframes"/>
|
||||
<mkdir dir="${target.dir}/style/simple"/>
|
||||
<mkdir dir="${target.dir}/style/csv"/>
|
||||
<mkdir dir="target/style/author"/>
|
||||
<style basedir="${target.dir}"
|
||||
destdir="${target.dir}/style/noframes"
|
||||
includes="cs_errors.xml"
|
||||
|
|
@ -349,6 +350,10 @@
|
|||
<style out="${target.dir}/style/csv/report-csv.txt"
|
||||
in="${target.dir}/cs_errors.xml"
|
||||
style="contrib/checkstyle-csv.xsl"/>
|
||||
<style basedir="target"
|
||||
destdir="target/style/author"
|
||||
includes="cs_errors.xml"
|
||||
style="contrib/checkstyle-author.xsl"/>
|
||||
</target>
|
||||
|
||||
<!-- Targets to verify that JUnit is in the classpath -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="html" indent="yes"/>
|
||||
<xsl:decimal-format decimal-separator="." grouping-separator=","/>
|
||||
<!--
|
||||
Checkstyle XML Style Sheet by Daniel Grenner
|
||||
<daniel DOT grenner AT enea DOT se>
|
||||
This stylesheet groups the errors by author name, if used in combination
|
||||
with the WriteTag check:
|
||||
|
||||
<module name="WriteTag">
|
||||
<property name="tag" value="@author"/>
|
||||
<property name="tagFormat" value="\S"/>
|
||||
<property name="severity" value="ignore"/>
|
||||
</module>
|
||||
|
||||
The output contains both error and warning messages.
|
||||
Files without errors or warnings are not included.
|
||||
This stylesheet is based on checkstyle-noframes.xsl.
|
||||
-->
|
||||
|
||||
<xsl:key name="keyAuthorID" match="//file/error[contains(@message,'@author')]" use="@message" />
|
||||
<xsl:key name="keySeverityID" match="//file/error" use="@severity" />
|
||||
<xsl:template match="checkstyle">
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.bannercell {
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
body {
|
||||
margin-left: 10;
|
||||
margin-right: 10;
|
||||
font:normal 68% verdana,arial,helvetica;
|
||||
background-color:#FFFFFF;
|
||||
color:#000000;
|
||||
}
|
||||
.a td {
|
||||
background: #efefef;
|
||||
}
|
||||
.b td {
|
||||
background: #fff;
|
||||
}
|
||||
th, td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
th {
|
||||
font-weight:bold;
|
||||
background: #ccc;
|
||||
color: black;
|
||||
}
|
||||
table, th, td {
|
||||
font-size:100%;
|
||||
border: none
|
||||
}
|
||||
table.log tr td, tr th {
|
||||
|
||||
}
|
||||
h2 {
|
||||
font-weight:bold;
|
||||
font-size:140%;
|
||||
margin-bottom: 5;
|
||||
}
|
||||
h3 {
|
||||
font-size:100%;
|
||||
font-weight:bold;
|
||||
background: #525D76;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 5px;
|
||||
margin-right: 2px;
|
||||
margin-left: 2px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a name="#top"/>
|
||||
<!-- jakarta logo -->
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="bannercell" rowspan="2">
|
||||
<!--a href="http://jakarta.apache.org/">
|
||||
<img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
|
||||
</a-->
|
||||
</td>
|
||||
<td class="text-align:right">
|
||||
<h2>CheckStyle Audit</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-align:right">Designed for use with <a href="http://checkstyle.sourceforge.net/">CheckStyle</a> and <a href="http://jakarta.apache.org">Ant</a>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr size="1"/>
|
||||
|
||||
<!-- Summary part -->
|
||||
<xsl:apply-templates select="." mode="summary"/>
|
||||
<hr size="1" width="100%" align="left"/>
|
||||
|
||||
<!-- Author List part -->
|
||||
<xsl:apply-templates select="." mode="authorlist"/>
|
||||
<hr size="1" width="100%" align="left"/>
|
||||
|
||||
<!-- For each package create its part -->
|
||||
<xsl:for-each select="file">
|
||||
<xsl:sort select="./error[contains(@message,'@author=')]/@message"/>
|
||||
<xsl:apply-templates select="."/>
|
||||
<p/>
|
||||
<p/>
|
||||
</xsl:for-each>
|
||||
<hr size="1" width="100%" align="left"/>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
<xsl:template match="checkstyle" mode="summary">
|
||||
<h3>Summary</h3>
|
||||
<xsl:variable name="fileCount" select="count(file)"/>
|
||||
<xsl:variable name="errorCount" select="count(key('keySeverityID', 'error'))"/>
|
||||
<xsl:variable name="warningCount" select="count(key('keySeverityID', 'warning'))"/>
|
||||
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
|
||||
<tr>
|
||||
<th>Files</th>
|
||||
<th>Errors</th>
|
||||
<th>Warnings</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<xsl:call-template name="alternated-row"/>
|
||||
<td>
|
||||
<xsl:value-of select="$fileCount"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="$errorCount"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="$warningCount"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
<xsl:template match="checkstyle" mode="authorlist">
|
||||
<h3>Authors</h3>
|
||||
|
||||
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Errors</th>
|
||||
<th>Warnings</th>
|
||||
</tr>
|
||||
|
||||
<!-- Process each Author -->
|
||||
<xsl:for-each select="file/error[generate-id(.) = generate-id(key('keyAuthorID', @message)[1])]">
|
||||
<xsl:sort select="@message" />
|
||||
|
||||
<xsl:variable name="authorFull" select="@message"/>
|
||||
<xsl:variable name="author" select="substring-after($authorFull,'@author=')"/>
|
||||
<xsl:variable name="errors" select="count(key('keyAuthorID', @message)/../error[@severity='error'])"/>
|
||||
<xsl:variable name="warnings" select="count(key('keyAuthorID', @message)/../error[@severity='warning'])"/>
|
||||
<xsl:if test = "not ($author='' or ($errors + $warnings = 0))">
|
||||
<tr>
|
||||
<xsl:call-template name="alternated-row"/>
|
||||
<td>
|
||||
<a href="#{$author}">
|
||||
<xsl:value-of select="$author"/>
|
||||
</a>
|
||||
</td>
|
||||
<td><xsl:value-of select="$errors"/></td>
|
||||
<td><xsl:value-of select="$warnings"/></td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="file">
|
||||
<xsl:variable name="errorCount" select="count(error[@severity='error']) + count(error[@severity='warning'])"/>
|
||||
<xsl:if test="not ($errorCount=0)">
|
||||
|
||||
<xsl:variable name="author" select="substring-after(./error[contains(@message,'@author')]/@message,'@author=')"/>
|
||||
|
||||
<a name="#{$author}"/>
|
||||
<h3>File <xsl:value-of select="@name"/>
|
||||
<br/>
|
||||
Author <xsl:value-of select="$author"/>
|
||||
</h3>
|
||||
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
|
||||
<tr>
|
||||
<th>Error Description</th>
|
||||
<th>Line</th>
|
||||
</tr>
|
||||
<xsl:for-each select="error[not(@severity='info')]">
|
||||
<xsl:sort select="@line" data-type="number"/>
|
||||
<tr>
|
||||
<xsl:call-template name="alternated-row"/>
|
||||
<td>
|
||||
<xsl:value-of select="@message"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@line"/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
<a href="#top">Back to top</a>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template name="basename">
|
||||
<xsl:param name="path"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($path, '\')">
|
||||
<xsl:call-template name="basename">
|
||||
<xsl:with-param name="path">substring-after($path, '\')</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$path"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template name="alternated-row">
|
||||
<xsl:attribute name="class"><xsl:if test="position() mod 2 = 1">a</xsl:if><xsl:if test="position() mod 2 = 0">b</xsl:if></xsl:attribute>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2005 Oliver Burn
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.checks.javadoc;
|
||||
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import com.puppycrawl.tools.checkstyle.api.Check;
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.FileContents;
|
||||
import com.puppycrawl.tools.checkstyle.api.Scope;
|
||||
import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
|
||||
import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
|
||||
import com.puppycrawl.tools.checkstyle.api.TextBlock;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Outputs a JavaDoc tag as information. Can be used e.g. with the stylesheets
|
||||
* that sort the report by author name.
|
||||
* To define the format for a tag, set property tagFormat to a
|
||||
* regular expression.
|
||||
* This check uses two different severity levels. The normal one is used for
|
||||
* reporting when the tag is missing. The additional one (tagSeverity) is used
|
||||
* for the level of reporting when the tag exists. The default value for
|
||||
* tagSeverity is info.
|
||||
* </p>
|
||||
* <p> An example of how to configure the check for printing author name is:
|
||||
*</p>
|
||||
* <pre>
|
||||
* <module name="WriteTag">
|
||||
* <property name="tag" value="@author"/>
|
||||
* <property name="tagFormat" value="\S"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
* <p> An example of how to configure the check to print warnings if an
|
||||
* "@incomplete" tag is found, and not print anything if it is not found:
|
||||
*</p>
|
||||
* <pre>
|
||||
* <module name="WriteTag">
|
||||
* <property name="tag" value="@incomplete"/>
|
||||
* <property name="tagFormat" value="\S"/>
|
||||
* <property name="severity" value="ignore"/>
|
||||
* <property name="tagSeverity" value="warning"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
*
|
||||
* @author Daniel Grenner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class WriteTagCheck
|
||||
extends Check
|
||||
{
|
||||
/** compiled regexp to match tag **/
|
||||
private Pattern mTagRE;
|
||||
/** compiled regexp to match tag content **/
|
||||
private Pattern mTagFormatRE;
|
||||
|
||||
/** regexp to match tag */
|
||||
private String mTag;
|
||||
/** regexp to match tag content */
|
||||
private String mTagFormat;
|
||||
/** the severity level of found tag reports */
|
||||
private SeverityLevel mTagSeverityLevel = SeverityLevel.INFO;
|
||||
|
||||
/**
|
||||
* Sets the tag to check.
|
||||
* @param aTag tag to check
|
||||
* @throws ConversionException If the tag is not a valid regular exception.
|
||||
*/
|
||||
public void setTag(String aTag)
|
||||
throws ConversionException
|
||||
{
|
||||
try {
|
||||
mTag = aTag;
|
||||
mTagRE = Utils.getPattern(aTag + "\\s+(.*$)");
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
throw new ConversionException("unable to parse " + aTag, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tag format.
|
||||
* @param aFormat a <code>String</code> value
|
||||
* @throws ConversionException unable to parse aFormat
|
||||
*/
|
||||
public void setTagFormat(String aFormat)
|
||||
throws ConversionException
|
||||
{
|
||||
try {
|
||||
mTagFormat = aFormat;
|
||||
mTagFormatRE = Utils.getPattern(aFormat);
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
throw new ConversionException("unable to parse " + aFormat, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag severity level. The string should be one of the names
|
||||
* defined in the <code>SeverityLevel</code> class.
|
||||
*
|
||||
* @param aSeverity The new severity level
|
||||
* @see SeverityLevel
|
||||
*/
|
||||
public final void setTagSeverity(String aSeverity)
|
||||
{
|
||||
mTagSeverityLevel = SeverityLevel.getInstance(aSeverity);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.INTERFACE_DEF, TokenTypes.CLASS_DEF, };
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int[] getAcceptableTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.INTERFACE_DEF,
|
||||
TokenTypes.CLASS_DEF,
|
||||
TokenTypes.METHOD_DEF,
|
||||
};
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitToken(DetailAST aAST)
|
||||
{
|
||||
final DetailAST mods = aAST.findFirstToken(TokenTypes.MODIFIERS);
|
||||
final Scope declaredScope = ScopeUtils.getScopeFromMods(mods);
|
||||
final Scope typeScope =
|
||||
ScopeUtils.inInterfaceBlock(aAST) ? Scope.PUBLIC : declaredScope;
|
||||
final FileContents contents = getFileContents();
|
||||
final int lineNo = aAST.getLineNo();
|
||||
final TextBlock cmt =
|
||||
contents.getJavadocBefore(lineNo);
|
||||
if (cmt == null) {
|
||||
log(lineNo, "type.missingTag", mTag);
|
||||
}
|
||||
else {
|
||||
checkTag(lineNo, cmt.getText(), mTag, mTagRE, mTagFormatRE,
|
||||
mTagFormat);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a type definition has a required tag.
|
||||
* @param aLineNo the line number for the type definition.
|
||||
* @param aCmt the Javadoc comment for the type definition.
|
||||
* @param aTag the required tag name.
|
||||
* @param aTagRE regexp for the full tag.
|
||||
* @param aFormatRE regexp for the tag value.
|
||||
* @param aFormat pattern for the tag value.
|
||||
*/
|
||||
private void checkTag(
|
||||
int aLineNo,
|
||||
String[] aCmt,
|
||||
String aTag,
|
||||
Pattern aTagRE,
|
||||
Pattern aFormatRE,
|
||||
String aFormat)
|
||||
{
|
||||
if (aTagRE == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int tagCount = 0;
|
||||
for (int i = 0; i < aCmt.length; i++) {
|
||||
final String s = aCmt[i];
|
||||
final Matcher matcher = aTagRE.matcher(s);
|
||||
if (matcher.find()) {
|
||||
tagCount += 1;
|
||||
final int contentStart = matcher.start(1);
|
||||
final String content = s.substring(contentStart);
|
||||
if (aFormatRE != null && !aFormatRE.matcher(content).find()) {
|
||||
log(aLineNo + i - aCmt.length, "type.tagFormat", aTag,
|
||||
aFormat);
|
||||
}
|
||||
else {
|
||||
logTag(aLineNo + i - aCmt.length, aTag, content);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (tagCount == 0) {
|
||||
Object[] args = {aTag};
|
||||
log(aLineNo, "type.missingTag", aTag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log a message.
|
||||
*
|
||||
* @param aLine the line number where the error was found
|
||||
* @param aTag the javdoc tag to be logged
|
||||
* @param aTagValue the contents of the tag
|
||||
*
|
||||
* @see java.text.MessageFormat
|
||||
*/
|
||||
protected final void logTag(int aLine, String aTag, String aTagValue)
|
||||
{
|
||||
String originalSeverity = getSeverity();
|
||||
setSeverity(mTagSeverityLevel.getName());
|
||||
|
||||
log(aLine, "javadoc.writeTag", aTag, aTagValue);
|
||||
|
||||
setSeverity(originalSeverity);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ javadoc.unclosedhtml=Unclosed HTML tag found: {0}
|
|||
javadoc.unusedTag=Unused {0} tag for ''{1}''.
|
||||
javadoc.unusedTagGeneral=Unused Javadoc tag.
|
||||
javadoc.empty=Javadoc has empty description section.
|
||||
javadoc.writeTag={0}={1}
|
||||
|
||||
type.missingTag=Type Javadoc comment is missing an {0} tag.
|
||||
type.tagFormat=Type Javadoc tag {0} must match pattern ''{1}''.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test case file for checkstyle.
|
||||
// Created: 2004
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
/**
|
||||
* Testing tag writing
|
||||
* @author Daniel Grenner
|
||||
* @incomplete This class needs more code...
|
||||
* @doubletag first text
|
||||
* @doubletag second text
|
||||
*/
|
||||
class InputWriteTag
|
||||
{
|
||||
public void method()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add a comment
|
||||
*/
|
||||
public void anotherMethod()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ public abstract class BaseCheckTestCase
|
|||
public void fileStarted(AuditEvent evt) {}
|
||||
}
|
||||
|
||||
private final ByteArrayOutputStream mBAOS = new ByteArrayOutputStream();
|
||||
protected final ByteArrayOutputStream mBAOS = new ByteArrayOutputStream();
|
||||
protected final PrintStream mStream = new PrintStream(mBAOS);
|
||||
protected final Properties mProps = new Properties();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class AllTests {
|
|||
suite.addTest(new TestSuite(JavadocTypeCheckTest.class));
|
||||
suite.addTest(new TestSuite(JavadocVariableCheckTest.class));
|
||||
suite.addTest(new TestSuite(PackageHtmlCheckTest.class));
|
||||
suite.addTest(new TestSuite(WriteTagCheckTest.class));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.javadoc;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.BaseCheckTestCase;
|
||||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
|
||||
import com.puppycrawl.tools.checkstyle.api.Scope;
|
||||
import com.puppycrawl.tools.checkstyle.Checker;
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InputStream;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
|
||||
/**
|
||||
* @author Daniel Grenner
|
||||
*/
|
||||
public class WriteTagCheckTest extends BaseCheckTestCase
|
||||
{
|
||||
private DefaultConfiguration mCheckConfig;
|
||||
|
||||
public void setUp() {
|
||||
mCheckConfig = createCheckConfig(WriteTagCheck.class);
|
||||
}
|
||||
|
||||
public void testDefaultSettings() throws Exception
|
||||
{
|
||||
final String[] expected =
|
||||
{
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testTag() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@author");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
final String[] expected =
|
||||
{
|
||||
"10: @author=Daniel Grenner",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testMissingFormat() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@author");
|
||||
final String[] expected =
|
||||
{
|
||||
"10: @author=Daniel Grenner",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testTagSeverity() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@incomplete");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
mCheckConfig.addAttribute("tagSeverity", "warning");
|
||||
final String[] expected =
|
||||
{
|
||||
"11: warning: @incomplete=This class needs more code...",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testDoubleTag() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@doubletag");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
final String[] expected =
|
||||
{
|
||||
"12: @doubletag=first text",
|
||||
"13: @doubletag=second text",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
|
||||
public void testMissingTag() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@missingtag");
|
||||
final String[] expected =
|
||||
{
|
||||
"15: Type Javadoc comment is missing an @missingtag tag.",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testMethod() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@todo");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
mCheckConfig.addAttribute("tokens",
|
||||
"INTERFACE_DEF, CLASS_DEF, METHOD_DEF");
|
||||
mCheckConfig.addAttribute("severity", "ignore");
|
||||
final String[] expected =
|
||||
{
|
||||
"22: @todo=Add a comment",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testSeverity() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@author");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
mCheckConfig.addAttribute("severity", "ignore");
|
||||
final String[] expected =
|
||||
{
|
||||
"10: @author=Daniel Grenner",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreMissing() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@todo2");
|
||||
mCheckConfig.addAttribute("tagFormat", "\\S");
|
||||
mCheckConfig.addAttribute("severity", "ignore");
|
||||
final String[] expected =
|
||||
{
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testRegularEx()
|
||||
throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@author");
|
||||
mCheckConfig.addAttribute("tagFormat", "0*");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
public void testRegularExError()
|
||||
throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("tag", "@author");
|
||||
mCheckConfig.addAttribute("tagFormat", "ABC");
|
||||
final String[] expected = {
|
||||
"10: Type Javadoc tag @author must match pattern 'ABC'.",
|
||||
};
|
||||
verify(mCheckConfig, getPath("InputWriteTag.java"), expected);
|
||||
}
|
||||
|
||||
protected void verify(Checker aC,
|
||||
File[] aProcessedFiles,
|
||||
String aMessageFileName,
|
||||
String[] aExpected)
|
||||
throws Exception
|
||||
{
|
||||
mStream.flush();
|
||||
final int errs = aC.process(aProcessedFiles);
|
||||
|
||||
// process each of the lines
|
||||
final ByteArrayInputStream bais =
|
||||
new ByteArrayInputStream(mBAOS.toByteArray());
|
||||
final LineNumberReader lnr =
|
||||
new LineNumberReader(new InputStreamReader(bais));
|
||||
|
||||
for (int i = 0; i < aExpected.length; i++) {
|
||||
final String expected = aMessageFileName + ":" + aExpected[i];
|
||||
final String actual = lnr.readLine();
|
||||
assertEquals("error message " + i, expected, actual);
|
||||
}
|
||||
|
||||
assertTrue("unexpected output: " + lnr.readLine(),
|
||||
aExpected.length >= errs);
|
||||
|
||||
aC.destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -682,5 +682,109 @@ public int checkReturnTag(final int aTagIndex,
|
|||
</p>
|
||||
</subsection>
|
||||
</section>
|
||||
|
||||
<section name="WriteTag">
|
||||
<subsection name="Description">
|
||||
<p>
|
||||
Outputs a JavaDoc tag as information. Can be used e.g. with the stylesheets
|
||||
that sort the report by author name.
|
||||
To define the format for a tag, set property tagFormat to a regular expression.
|
||||
This check uses two different severity levels. The normal one is used for
|
||||
reporting when the tag is missing. The additional one (tagSeverity) is used
|
||||
for the level of reporting when the tag exists.
|
||||
</p>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Properties">
|
||||
<table>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
<th>type</th>
|
||||
<th>default value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tag</td>
|
||||
<td>Name of tag</td>
|
||||
<td><a href="property_types.html#string">String</a></td>
|
||||
<td><span class="default">null</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tagFormat</td>
|
||||
<td>Format of tag</td>
|
||||
<td><a href="property_types.html#regexp">regular expression</a></td>
|
||||
<td><span class="default">null</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tagSeverity</td>
|
||||
<td>Severity level when tag is found and printed</td>
|
||||
<td><a href="property_types.html#severity">severity</a></td>
|
||||
<td><span class="default">info</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Examples">
|
||||
<p>
|
||||
An example of how to configure the check for printing author name is:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="WriteTag">
|
||||
<property name="tag" value="@author"/>
|
||||
<property name="tagFormat" value="\S"/>
|
||||
</module>
|
||||
</source>
|
||||
|
||||
<p>
|
||||
An example of how to configure the check to print warnings if an
|
||||
"@incomplete" tag is found, and not print anything if it is not found:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="WriteTag">
|
||||
<property name="tag" value="@incomplete"/>
|
||||
<property name="tagFormat" value="\S"/>
|
||||
<property name="severity" value="ignore"/>
|
||||
<property name="tagSeverity" value="warning"/>
|
||||
</module>
|
||||
</source>
|
||||
|
||||
<p>
|
||||
To configure the check for javadoc which is in <span
|
||||
class="default">private</span>, but not in <span
|
||||
class="default">package</span> scope:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="JavadocStyle">
|
||||
<property name="scope" value="private"/>
|
||||
<property name="excludeScope" value="package"/>
|
||||
</module>
|
||||
</source>
|
||||
|
||||
<p>
|
||||
To configure the check to turn off first sentence checking:
|
||||
</p>
|
||||
|
||||
<source>
|
||||
<module name="JavadocStyle">
|
||||
<property name="checkFirstSentence" value="false"/>
|
||||
</module>
|
||||
</source>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Package">
|
||||
<p>
|
||||
com.puppycrawl.tools.checkstyle.checks
|
||||
</p>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Parent Module">
|
||||
<p>
|
||||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
</subsection>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
TrailingComment now can be configured to accept some trailing comments
|
||||
(such as NOI18N) (property legalComment, rfe 1385344).
|
||||
</li>
|
||||
<li>
|
||||
Added WriteTag check which outputs a JavaDoc tag as information (patch 902110)
|
||||
Thanks to Daniel Grenner (dgrenner) for contribution.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Fixed Bugs:</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue