SummaryJavaDocCheck #307 by Max Vetrenko
This commit is contained in:
parent
cc9e00d9a0
commit
d3b013d073
|
|
@ -0,0 +1,144 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2014 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 java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailNode;
|
||||
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Checks that <a href="
|
||||
* http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html#firstsentence">
|
||||
* Javadoc summary sentence</a> does not contain phrases that are not recommended to use.
|
||||
* By default Check validate that first sentence is not empty:</p><br/>
|
||||
* <pre>
|
||||
* <module name="SummaryJavadocCheck"/>
|
||||
* </pre>
|
||||
* <p>
|
||||
* To ensure that summary do not contain phrase like "This method returns" , use following config:
|
||||
* <p>
|
||||
* <pre>
|
||||
* <module name="SummaryJavadocCheck">
|
||||
* <property name="forbiddenSummaryFragments"
|
||||
* value="^This method returns.*"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
*
|
||||
* @author max
|
||||
*
|
||||
*/
|
||||
public class SummaryJavadocCheck extends AbstractJavadocCheck
|
||||
{
|
||||
|
||||
/**
|
||||
* Some javadoc.
|
||||
*/
|
||||
private Pattern mForbiddenSummaryFragments = Utils.createPattern("^$");
|
||||
|
||||
/**
|
||||
* Some javadoc.
|
||||
* @param aPattern Some javadoc.
|
||||
*/
|
||||
public void setForbiddenSummaryFragments(String aPattern)
|
||||
{
|
||||
mForbiddenSummaryFragments = Utils.createPattern(aPattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDefaultJavadocTokens()
|
||||
{
|
||||
return new int[] {
|
||||
JavadocTokenTypes.JAVADOC,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavadocToken(DetailNode aAst)
|
||||
{
|
||||
String firstSentence = getFirstSentence(aAst);
|
||||
final int endOfSentence = firstSentence.lastIndexOf(".");
|
||||
if (endOfSentence == -1) {
|
||||
log(aAst.getLineNumber(), "summary.first.sentence");
|
||||
}
|
||||
else {
|
||||
firstSentence = firstSentence.substring(0, endOfSentence);
|
||||
if (containsForbiddenFragment(firstSentence)) {
|
||||
log(aAst.getLineNumber(), "summary.javaDoc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some javadoc.
|
||||
* @param aAst Some javadoc.
|
||||
* @return Some javadoc.
|
||||
*/
|
||||
private String getFirstSentence(DetailNode aAst)
|
||||
{
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for (DetailNode child : aAst.getChildren()) {
|
||||
if (child.getType() != JavadocTokenTypes.JAVADOC_INLINE_TAG
|
||||
&& child.getText().contains(". "))
|
||||
{
|
||||
result.append(getCharsTillDot(child));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
result.append(child.getText());
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some javadoc.
|
||||
* @param aTextNode Some javadoc.
|
||||
* @return Some javadoc.
|
||||
*/
|
||||
private String getCharsTillDot(DetailNode aTextNode)
|
||||
{
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for (DetailNode child : aTextNode.getChildren()) {
|
||||
result.append(child.getText());
|
||||
if (".".equals(child.getText())
|
||||
&& JavadocUtils.getNextSibling(child).getType() == JavadocTokenTypes.WS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some javadoc.
|
||||
* @param aFirstSentence Some javadoc.
|
||||
* @return Some javadoc.
|
||||
*/
|
||||
private boolean containsForbiddenFragment(String aFirstSentence)
|
||||
{
|
||||
// This regexp is used to convert multiline javadoc to single line without stars.
|
||||
String javadocText = aFirstSentence.replaceAll("\n[ ]+(\\*)|^[ ]+(\\*)", " ");
|
||||
javadocText = CharMatcher.WHITESPACE.trimAndCollapseFrom(javadocText, ' ');
|
||||
return mForbiddenSummaryFragments.matcher(javadocText).find();
|
||||
}
|
||||
}
|
||||
|
|
@ -32,3 +32,6 @@ non.empty.atclause=At-clause should have a non-empty description.
|
|||
|
||||
tag.continuation.indent=Line continuation have incorrect indentation level, expected level should be {0}.
|
||||
|
||||
summary.javaDoc=Forbidden summary fragment.
|
||||
summary.first.sentence=First sentence should be present.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2014 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 com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
|
||||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SummaryJavadocCheckTest extends BaseCheckTestSupport
|
||||
{
|
||||
private DefaultConfiguration mCheckConfig;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
mCheckConfig = createCheckConfig(SummaryJavadocCheck.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrect() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("forbiddenSummaryFragments",
|
||||
"^@return the *|^This method returns *|^A [{]@code [a-zA-Z0-9]+[}]( is a )");
|
||||
final String[] expected = {
|
||||
};
|
||||
|
||||
verify(mCheckConfig, getPath("javadoc/InputCorrectSummaryJavaDocCheck.java"), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncorrect() throws Exception
|
||||
{
|
||||
mCheckConfig.addAttribute("forbiddenSummaryFragments",
|
||||
"^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )");
|
||||
final String[] expected = {
|
||||
"14: First sentence should be present.",
|
||||
"37: First sentence should be present.",
|
||||
"47: Forbidden summary fragment.",
|
||||
"58: Forbidden summary fragment.",
|
||||
"69: First sentence should be present.",
|
||||
"83: Forbidden summary fragment.",
|
||||
"103: First sentence should be present.",
|
||||
};
|
||||
verify(mCheckConfig, getPath("javadoc/InputIncorrectSummaryJavaDocCheck.java"), expected);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.puppycrawl.tools.checkstyle.javadoc;
|
||||
|
||||
/**
|
||||
* Some Javadoc A {@code Foo} is a simple Javadoc.
|
||||
*/
|
||||
class InputCorrectJavaDocParagraphCheck {
|
||||
|
||||
/**
|
||||
* Some Javadoc This method returns.
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* As of JDK 1.1, replaced by {@link #setBounds(int,int,int,int)}.
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs.
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/** An especially This method returns short bit of Javadoc. */
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short
|
||||
* bit of Javadoc. This method returns.
|
||||
*/
|
||||
void foo6() {}
|
||||
|
||||
/**
|
||||
* <a href="mailto:vlad@htmlbook.ru"/>
|
||||
*/
|
||||
class InnerInputCorrectJavaDocParagraphCheck {
|
||||
|
||||
/**
|
||||
* foooo@foooo.
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* Some java@doc.
|
||||
* This method returns.
|
||||
*/
|
||||
public static final byte NUL_2 = 0;
|
||||
|
||||
/**
|
||||
* Returns the customer ID. This method returns
|
||||
*/
|
||||
int getId() {return 666;}
|
||||
|
||||
/**
|
||||
* <a href="mailto:vlad@htmlbook.ru"/>.
|
||||
*/
|
||||
void foo2() {}
|
||||
|
||||
/**
|
||||
* As of JDK 1.1,
|
||||
* replaced by {@link #setBounds(int,int,int,int)}. This method returns.
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs.
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/**
|
||||
* JAXB Provider Use Only: Provides partial default
|
||||
* implementations for some of the javax.xml.bind interfaces.
|
||||
*/
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short (int... A) bit of Javadoc. This
|
||||
* method returns
|
||||
*/
|
||||
void foo6() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some
|
||||
* javadoc. A {@code Foo} is a simple Javadoc.
|
||||
*
|
||||
* Some Javadoc. A {@code Foo}
|
||||
* is a simple Javadoc.
|
||||
*/
|
||||
InnerInputCorrectJavaDocParagraphCheck anon = new InnerInputCorrectJavaDocParagraphCheck() {
|
||||
|
||||
/**
|
||||
* JAXB 1.0 only default validation event handler.
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* Returns the current state.
|
||||
* This method returns.
|
||||
*/
|
||||
boolean emulated(String s) {return false;}
|
||||
|
||||
/**
|
||||
* As of JDK 1.1, replaced by {@link #setBounds(int,int,int,int)}.
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs.
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/** An especially short bit of Javadoc. */
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short bit of Javadoc.
|
||||
*/
|
||||
void foo6() {}
|
||||
|
||||
/**
|
||||
* Some Javadoc. This method returns some javadoc.
|
||||
*/
|
||||
boolean emulated() {return false;}
|
||||
|
||||
/**
|
||||
* Some Javadoc. This method returns some javadoc. Some Javadoc.
|
||||
*/
|
||||
boolean emulated1() {return false;}
|
||||
|
||||
/**
|
||||
* @return Some Javadoc the customer ID.
|
||||
*/
|
||||
int geId() {return 666;}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package com.puppycrawl.tools.checkstyle.javadoc;
|
||||
|
||||
/**
|
||||
* A {@code Foo. Foo}
|
||||
* is a simple Javadoc. Some javadoc.
|
||||
*/
|
||||
class InputCorrectJavaDocParagraphCheck {
|
||||
|
||||
/**
|
||||
* As of JDK 1.1, replaced by {@link #setBounds(int,int,int,int)}
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/** An especially short bit of Javadoc. */
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short bit of Javadoc.
|
||||
*/
|
||||
void foo6() {}
|
||||
|
||||
/**
|
||||
* Some Javadoc.
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* <a href="mailto:vlad@htmlbook.ru"/>
|
||||
*/
|
||||
class InnerInputCorrectJavaDocParagraphCheck {
|
||||
|
||||
/**
|
||||
* foooo@foooo
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* Some java@doc.
|
||||
*/
|
||||
public static final byte NUL_2 = 0;
|
||||
|
||||
/**
|
||||
* This method
|
||||
* returns some javadoc. Some javadoc.
|
||||
*/
|
||||
boolean emulated() {return false;}
|
||||
|
||||
/**
|
||||
* <a href="mailto:vlad@htmlbook.ru"/>
|
||||
*/
|
||||
void foo2() {}
|
||||
|
||||
/**
|
||||
* @return the
|
||||
* customer ID some javadoc.
|
||||
*/
|
||||
int geId() {return 666;}
|
||||
|
||||
/**
|
||||
* As of JDK 1.1, replaced by {@link #setBounds(int,int,int,int)}
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/** An especially short bit of Javadoc. */
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short bit of Javadoc.
|
||||
*/
|
||||
void foo6() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code InnerInputCorrectJavaDocParagraphCheck} is a simple code.
|
||||
*/
|
||||
InnerInputCorrectJavaDocParagraphCheck anon = new InnerInputCorrectJavaDocParagraphCheck() {
|
||||
|
||||
/**
|
||||
* Some Javadoc.
|
||||
*/
|
||||
public static final byte NUL = 0;
|
||||
|
||||
/**
|
||||
* Some Javadoc.
|
||||
*/
|
||||
void emulated(String s) {}
|
||||
|
||||
/**
|
||||
* As of JDK 1.1, replaced by {@link #setBounds(int,int,int,int)}
|
||||
*/
|
||||
void foo3() {}
|
||||
|
||||
/**
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
void foo4() throws Exception {}
|
||||
|
||||
/** An especially short bit of Javadoc. */
|
||||
void foo5() {}
|
||||
|
||||
/**
|
||||
* An especially short bit of Javadoc.
|
||||
*/
|
||||
void foo6() {}
|
||||
};
|
||||
}
|
||||
|
|
@ -658,6 +658,11 @@
|
|||
<td>Checks that string literals are not used with
|
||||
<code>==</code> or <code>!=</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="config_javadoc.html#SummaryJavadoc">SummaryJavadoc</a></td>
|
||||
<td>
|
||||
Checks that Javadoc summary sentence does not contain phrases that are not recommended to use.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="config_coding.html#SuperClone">SuperClone</a></td>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -830,7 +830,6 @@ public boolean isSomething()
|
|||
</subsection>
|
||||
</section>
|
||||
|
||||
<<<<<<< HEAD
|
||||
<section name="NonEmptyAtclauseDescription">
|
||||
<subsection name="Description">
|
||||
<p>
|
||||
|
|
@ -917,5 +916,65 @@ public boolean isSomething()
|
|||
</subsection>
|
||||
</section>
|
||||
|
||||
<section name="SummaryJavadoc">
|
||||
<subsection name="Description">
|
||||
<p>
|
||||
Checks that <a href="http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html#firstsentence">
|
||||
Javadoc summary sentence</a> does not contain phrases that are not recommended to use.
|
||||
</p>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Properties">
|
||||
<table>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
<th>type</th>
|
||||
<th>default value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>forbiddenSummaryFragments</td>
|
||||
<td>forbidden summary fragments</td>
|
||||
<td><a href="property_types.html#regexp">regular expression</a></td>
|
||||
<td><code>^$</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Examples">
|
||||
<p>
|
||||
Default configuration
|
||||
</p>
|
||||
<source>
|
||||
<module name="JavaDocTagContinuationIndentation">
|
||||
<property name="tagContinuationIndentation" value="4"/>
|
||||
By default Check validate that first sentence is not empty:
|
||||
</p>
|
||||
<source>
|
||||
<module name="SummaryJavadocCheck"/>
|
||||
</source>
|
||||
<p>
|
||||
To ensure that summary do not contain phrase like "This method returns" , use following config:
|
||||
</p>
|
||||
<source>
|
||||
<module name="SummaryJavadocCheck">
|
||||
<property name="forbiddenSummaryFragments" value="^This method returns.*"/>
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -1266,12 +1266,10 @@
|
|||
href="http://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s7.2-summary-fragment">7.2 The summary fragment</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://github.com/maxvetrenko/checkstyle/issues/17">SummaryJavaDocCheck</a>
|
||||
(check for text before any at-clause).
|
||||
<br />
|
||||
additionally we need to have list of forbidden phrases
|
||||
<br />
|
||||
in the beginning of summary (regexp).
|
||||
<img
|
||||
src="images/ok_green.png"
|
||||
alt="" />
|
||||
<a href="config_javadoc.html#SummaryJavadoc">SummaryJavadoc</a>
|
||||
</td>
|
||||
<td>[]</td>
|
||||
</tr>
|
||||
|
|
|
|||
Loading…
Reference in New Issue