AtclauseOrderCheck #306

This commit is contained in:
maxvetrenko 2014-10-21 00:23:08 +04:00 committed by Roman Ivanov
parent d3b013d073
commit fe628e5bbd
8 changed files with 945 additions and 1 deletions

View File

@ -0,0 +1,176 @@
////////////////////////////////////////////////////////////////////////////////
// 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
* <p>
* Checks the order of at-clauses.
* </p>
*
* <p>
* The check allows to configure itself by using the following properties:
* </p>
* <ul>
* <li>
* target - allows to specify targets to check at-clauses.
* </li>
* <li>
* tagOrder - allows to specify the order by tags.
* </li>
* </ul>
* <p>
* Default configuration:
* </p>
* <pre>
* &lt;module name=&quot;AtclauseOrderCheck&quot;&gt;
* &lt;property name=&quot;tagOrder&quot; value=&quot;&#64;author, &#64;version, &#64;param,
* &#64;return, &#64;throws, &#64;exception, &#64;see, &#64;since, &#64;serial,
* &#64;serialField, &#64;serialData, &#64;deprecated&quot;/&gt;
* &lt;property name=&quot;target&quot; value=&quot;CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
* METHOD_DEF, CTOR_DEF, VARIABLE_DEF&quot;/&gt;
* &lt;/module>
* </pre>
*
* @author max
*
*/
public class AtclauseOrderCheck extends AbstractJavadocCheck
{
/**
* Some javadoc.
*/
private static final String[] DEFAULT_ORDER = {
"@author", "@version",
"@param", "@return",
"@throws", "@exception",
"@see", "@since",
"@serial", "@serialField",
"@serialData", "@deprecated",
};
/**
* Some javadoc.
*/
private List<Integer> mTarget = Arrays.asList(
TokenTypes.CLASS_DEF,
TokenTypes.INTERFACE_DEF,
TokenTypes.ENUM_DEF,
TokenTypes.METHOD_DEF,
TokenTypes.CTOR_DEF,
TokenTypes.VARIABLE_DEF
);
/**
* Some javadoc.
*/
private List<String> mTagOrder = Arrays.asList(DEFAULT_ORDER);
/**
* Some javadoc.
* @param aTarget Some javadoc.
*/
public void setTarget(String aTarget)
{
final List<Integer> customTarget = new ArrayList<Integer>();
for (String type : aTarget.split(", ")) {
customTarget.add(TokenTypes.getTokenId(type));
}
mTarget = customTarget;
}
/**
* Some javadoc.
* @param aOrder Some javadoc.
*/
public void setTagOrder(String aOrder)
{
final List<String> customOrder = new ArrayList<String>();
for (String type : aOrder.split(", ")) {
customOrder.add(type);
}
mTagOrder = customOrder;
}
@Override
public int[] getDefaultJavadocTokens()
{
return new int[] {
JavadocTokenTypes.JAVADOC,
};
}
@Override
public void visitJavadocToken(DetailNode aAst)
{
final int parentType = getParentType(getBlockCommentAst());
if (mTarget.contains(parentType)) {
checkOrderInTagSection(aAst);
}
}
/**
* Some javadoc.
* @param aJavadoc Some javadoc.
*/
private void checkOrderInTagSection(DetailNode aJavadoc)
{
int indexOrderOfPreviousTag = 0;
int indexOrderOfCurrentTag = 0;
for (DetailNode node : aJavadoc.getChildren()) {
if (node.getType() == JavadocTokenTypes.JAVADOC_TAG) {
final String tagText = JavadocUtils.getFirstChild(node).getText();
indexOrderOfCurrentTag = mTagOrder.indexOf(tagText);
if (mTagOrder.contains(tagText)
&& indexOrderOfCurrentTag < indexOrderOfPreviousTag)
{
log(node.getLineNumber(), "at.clause.order", mTagOrder.toString());
}
indexOrderOfPreviousTag = indexOrderOfCurrentTag;
}
}
}
/**
* Some javadoc.
* @param aCommentBlock Some javadoc.
* @return Some javadoc.
*/
private int getParentType(DetailAST aCommentBlock)
{
final DetailAST parentNode = aCommentBlock.getParent();
int type = parentNode.getType();
if (type == TokenTypes.TYPE || type == TokenTypes.MODIFIERS) {
type = parentNode.getParent().getType();
}
return type;
}
}

View File

@ -35,3 +35,5 @@ tag.continuation.indent=Line continuation have incorrect indentation level, expe
summary.javaDoc=Forbidden summary fragment.
summary.first.sentence=First sentence should be present.
at.clause.order=At-clauses have to appear in the order ''{0}''.

View File

@ -0,0 +1,100 @@
////////////////////////////////////////////////////////////////////////////////
// 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.Test;
public class AtclauseOrderCheckTest extends BaseCheckTestSupport
{
@Test
public void testCorrect() throws Exception
{
DefaultConfiguration checkConfig = createCheckConfig(AtclauseOrderCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("javadoc/InputCorrectAtClauseOrderCheck.java"), expected);
}
@Test
public void testIncorrect() throws Exception
{
final String tagOrder = "'[@author, @version, @param, @return, @throws, @exception, @see,"
+ " @since, @serial, @serialField, @serialData, @deprecated]'.";
DefaultConfiguration checkConfig = createCheckConfig(AtclauseOrderCheck.class);
final String[] expected = {
"9: At-clauses have to appear in the order " + tagOrder,
"11: At-clauses have to appear in the order " + tagOrder,
"12: At-clauses have to appear in the order " + tagOrder,
"40: At-clauses have to appear in the order " + tagOrder,
"50: At-clauses have to appear in the order " + tagOrder,
"51: At-clauses have to appear in the order " + tagOrder,
"62: At-clauses have to appear in the order " + tagOrder,
"69: At-clauses have to appear in the order " + tagOrder,
"86: At-clauses have to appear in the order " + tagOrder,
"87: At-clauses have to appear in the order " + tagOrder,
"99: At-clauses have to appear in the order " + tagOrder,
"101: At-clauses have to appear in the order " + tagOrder,
"115: At-clauses have to appear in the order " + tagOrder,
"123: At-clauses have to appear in the order " + tagOrder,
"134: At-clauses have to appear in the order " + tagOrder,
"135: At-clauses have to appear in the order " + tagOrder,
"145: At-clauses have to appear in the order " + tagOrder,
"153: At-clauses have to appear in the order " + tagOrder,
"161: At-clauses have to appear in the order " + tagOrder,
"172: At-clauses have to appear in the order " + tagOrder,
"183: At-clauses have to appear in the order " + tagOrder,
"185: At-clauses have to appear in the order " + tagOrder,
"199: At-clauses have to appear in the order " + tagOrder,
"202: At-clauses have to appear in the order " + tagOrder,
"213: At-clauses have to appear in the order " + tagOrder,
"223: At-clauses have to appear in the order " + tagOrder,
"230: At-clauses have to appear in the order " + tagOrder,
"237: At-clauses have to appear in the order " + tagOrder,
"247: At-clauses have to appear in the order " + tagOrder,
"248: At-clauses have to appear in the order " + tagOrder,
"259: At-clauses have to appear in the order " + tagOrder,
"261: At-clauses have to appear in the order " + tagOrder,
"275: At-clauses have to appear in the order " + tagOrder,
"277: At-clauses have to appear in the order " + tagOrder,
"278: At-clauses have to appear in the order " + tagOrder,
"288: At-clauses have to appear in the order " + tagOrder,
};
verify(checkConfig, getPath("javadoc/InputIncorrectAtClauseOrderCheck.java"), expected);
}
@Test
public void testIncorrectCustom() throws Exception
{
final String tagOrder = "'[@author, @version, @param, @return, @throws, @exception, @see,"
+ " @since, @serial, @serialField, @serialData, @deprecated]'.";
DefaultConfiguration checkConfig = createCheckConfig(AtclauseOrderCheck.class);
checkConfig.addAttribute("target", "CLASS_DEF");
final String[] expected = {
"9: At-clauses have to appear in the order " + tagOrder,
"11: At-clauses have to appear in the order " + tagOrder,
"12: At-clauses have to appear in the order " + tagOrder,
"115: At-clauses have to appear in the order " + tagOrder,
};
verify(checkConfig, getPath("javadoc/InputIncorrectAtClauseOrderCheck.java"), expected);
}
}

View File

@ -0,0 +1,291 @@
package com.puppycrawl.tools.checkstyle.javadoc;
import java.io.Serializable;
/**
* Some javadoc.
*
* @author max
* @version 1.0
* @see Some javadoc.
* @since Some javadoc.
* @deprecated Some javadoc.
*/
class WithAnnotations implements Serializable
{
/**
* The client's first name.
* @serial
*/
private String fFirstName;
/**
* The client's first name.
* @serial
*/
private String sSecondName;
/**
* The client's first name.
* @serialField
*/
private String tThirdName;
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
* @deprecated Some text.
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @throws Exception Some text.
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
void method3() throws Exception {}
/**
* Some text.
* @return Some text.
* @throws Exception Some text.
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @serialData Some javadoc.
* @deprecated Some text.
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @param aInt Some text.
* @param aBoolean Some text.
* @return Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
/**
*
* @author max
* @version 1.0
* @since Some javadoc.
*/
class InnerClassWithAnnotations
{
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @throws Exception Some text.
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
void method3() throws Exception {}
/**
* Some text.
* @return Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @serialData Some javadoc.
* @deprecated Some text.
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @param aInt Some text.
* @param aBoolean Some text.
* @return Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
}
InnerClassWithAnnotations anon = new InnerClassWithAnnotations()
{
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @throws Exception Some text.
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
void method3() throws Exception {}
/**
* Some text.
* @return Some text.
* @throws Exception Some text.
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @deprecated Some text.
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @param aInt Some text.
* @param aBoolean Some text.
* @return Some text.
* @throws Exception Some text.
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
};
}
/**
* Some javadoc.
*
* @author max
* @version 1.0
* @see Some javadoc.
* @since Some javadoc.
* @deprecated Some javadoc.
*/
enum Foo {}
/**
* Some javadoc.
*
* @author max
* @version 1.0
* @see Some javadoc.
* @since Some javadoc.
* @deprecated Some javadoc.
*/
interface FooIn {}

View File

@ -0,0 +1,290 @@
package com.puppycrawl.tools.checkstyle.javadoc;
import java.io.Serializable;
/**
* Some javadoc.
*
* @since Some javadoc.
* @version 1.0 //warn //warn
* @deprecated Some javadoc.
* @see Some javadoc. //warn
* @author max //warn
*/
class WithAnnotations implements Serializable
{
/**
* The client's first name.
* @serial
*/
private String fFirstName;
/**
* The client's first name.
* @serial
*/
private String sSecondName;
/**
* The client's first name.
* @serialField
*/
private String tThirdName;
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @serialData Some javadoc.
* @deprecated Some text.
* @throws Exception Some text. //warn
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @serialData Some javadoc.
* @return Some text. //warn
* @param aString Some text. //warn
* @throws Exception Some text.
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @throws Exception Some text.
* @param aString Some text. //warn
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @deprecated Some text.
* @throws Exception Some text. //warn
*/
void method3() throws Exception {}
/**
* Some text.
* @return Some text.
* @throws Exception Some text.
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @deprecated Some text.
* @return Some text. //warn
* @param aString Some text. //warn
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @serialData Some javadoc.
* @param aInt Some text. //warn
* @throws Exception Some text.
* @param aBoolean Some text. //warn
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
/**
* Some javadoc.
*
* @version 1.0
* @since Some javadoc.
* @serialData Some javadoc.
* @author max //warn
*/
class InnerClassWithAnnotations
{
/**
* Some text.
* @return Some text.
* @deprecated Some text.
* @param aString Some text. //warn
* @throws Exception Some text.
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @throws Exception Some text.
* @return Some text. //warn
* @param aString Some text. //warn
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @serialData Some javadoc.
* @param aString Some text. //warn
* @throws Exception Some text.
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @deprecated Some text.
* @throws Exception Some text. //warn
*/
void method3() throws Exception {}
/**
* Some text.
* @throws Exception Some text.
* @serialData Some javadoc.
* @return Some text. //warn
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @deprecated Some text.
* @return Some text. //warn
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @param aInt Some text. //warn
* @throws Exception Some text.
* @param aBoolean Some text. //warn
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
}
InnerClassWithAnnotations anon = new InnerClassWithAnnotations()
{
/**
* Some text.
* @throws Exception Some text.
* @param aString Some text. //warn
* @serialData Some javadoc.
* @deprecated Some text.
* @return Some text. //warn
*/
String method(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @throws Exception Some text.
* @return Some text. //warn
*/
String method1(String aString) throws Exception
{
return "null";
}
/**
* Some text.
* @throws Exception Some text.
* @param aString Some text. //warn
*/
void method2(String aString) throws Exception {}
/**
* Some text.
* @deprecated Some text.
* @throws Exception Some text. //warn
*/
void method3() throws Exception {}
/**
* Some text.
* @throws Exception Some text.
* @return Some text. //warn
*/
String method4() throws Exception
{
return "null";
}
/**
* Some text.
* @deprecated Some text.
* @return Some text. //warn
* @param aString Some text. //warn
*/
String method5(String aString)
{
return "null";
}
/**
* Some text.
* @param aString Some text.
* @return Some text.
* @param aInt Some text. //warn
* @throws Exception Some text.
* @param aBoolean Some text. //warn
* @deprecated Some text.
*/
String method6(String aString, int aInt, boolean aBoolean) throws Exception
{
return "null";
}
};
}
/**
* Some javadoc.
*
* @since Some javadoc.
* @version 1.0 //warn //warn
* @deprecated Some javadoc.
* @see Some javadoc. //warn
* @author max //warn
*/
enum Foo {}
/**
* Some javadoc.
*
* @version 1.0
* @since Some javadoc.
* @serialData Some javadoc.
* @author max //warn
*/
interface FooIn {}

View File

@ -50,6 +50,10 @@
<td><a href="config_misc.html#ArrayTypeStyle">ArrayTypeStyle</a></td>
<td>Checks the style of array type definitions.</td>
</tr>
<tr>
<td><a href="config_javadoc.html#AtclauseOrder">AtclauseOrder</a></td>
<td>Checks the order of at-clauses.</td>
</tr>
<tr>
<td><a href="config_misc.html#AvoidEscapedUnicodeCharacters">AvoidEscapedUnicodeCharacters</a></td>
<td>Restrict using Unicode escapes.</td>

View File

@ -976,5 +976,83 @@ public boolean isSomething()
</subsection>
</section>
<section name="AtclauseOrder">
<subsection name="Description">
<p>
Checks the order of at-clauses.
</p>
</subsection>
<subsection name="Properties">
<table>
<tr>
<th>name</th>
<th>description</th>
<th>type</th>
<th>default value</th>
</tr>
<tr>
<td>target</td>
<td>allows to specify targets to check at-clauses.</td>
<td>subset of tokens <a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CLASS_DEF">CLASS_DEF</a>,
<a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#INTERFACE_DEF">INTERFACE_DEF</a>,
<a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ENUM_DEF">ENUM_DEF</a>,
<a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#METHOD_DEF">METHOD_DEF</a>,
<a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CTOR_DEF">CTOR_DEF</a>,
<a
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#VARIABLE_DEF">VARIABLE_DEF</a></td>
<td><code>All of tokens</code></td>
</tr>
<tr>
<td>tagOrder</td>
<td>allows to specify the order by tags.</td>
<td><a href="property_types.html#string">String</a></td>
<td><code>&#64;author, &#64;version, &#64;param,
&#64;return, &#64;throws, &#64;exception, &#64;see, &#64;since, &#64;serial,
&#64;serialField, &#64;serialData, &#64;deprecated</code></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><code>info</code></td>
</tr>
</table>
</subsection>
<subsection name="Examples">
<p>
Default configuration
</p>
<source>
&lt;module name=&quot;AtclauseOrder&quot;&gt;
&lt;property name=&quot;tagOrder&quot; value=&quot;&#64;author, &#64;version, &#64;param,
&#64;return, &#64;throws, &#64;exception, &#64;see, &#64;since, &#64;serial,
&#64;serialField, &#64;serialData, &#64;deprecated&quot;/&gt;
&lt;property name=&quot;target&quot; value=&quot;CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
METHOD_DEF, CTOR_DEF, VARIABLE_DEF&quot;/&gt;
&lt;/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>

View File

@ -1246,7 +1246,10 @@
href="http://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s7.1.3-javadoc-at-clauses">7.1.3 At-clauses</a>
</td>
<td>
<a href="https://github.com/maxvetrenko/checkstyle/issues/7">AtClauseOrder</a>
<img
src="images/ok_green.png"
alt="" />
<a href="config_javadoc.html#AtclauseOrder">AtclauseOrder</a>
<br/>
<img
src="images/ok_green.png"