Issue #4092: added extends, implements and annotations processing
diff --git a/config/checkstyle_checks.xml b/config/checkstyle_checks.xml
index 14272a6..25e246c 100644
--- a/config/checkstyle_checks.xml
+++ b/config/checkstyle_checks.xml
@@ -446,7 +446,8 @@
UnsupportedEncodingException, BuildException, ConversionException,
FileNotFoundException, TestException, Log, Sets, Multimap,
TokenStreamRecognitionException, RecognitionException,
- TokenStreamException, IOException"/>
+ TokenStreamException, IOException, Override, Deprecated, SafeVarargs,
+ SuppressWarnings, FunctionalInterface"/>
</module>
<module name="CyclomaticComplexity">
<property name="switchBlockAsSingleDecisionPoint" value="true"/>
diff --git a/config/suppressions.xml b/config/suppressions.xml
index 69e6615..f2c08a8 100644
--- a/config/suppressions.xml
+++ b/config/suppressions.xml
@@ -84,6 +84,7 @@
<suppress checks="ClassFanOutComplexity" files="[\\/]Main\.java"/>
<suppress checks="ClassFanOutComplexity" files="CheckstyleAntTask\.java"/>
<suppress checks="ClassFanOutComplexity" files="CheckerTest\.java"/>
+ <suppress checks="ClassFanOutComplexity" files="Checker\.java"/>
<!-- a lot of GUI elements is OK -->
<suppress checks="ClassDataAbstractionCoupling" files="(TreeTable|MainFrame)\.java"/>
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/AbstractClassCouplingCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/AbstractClassCouplingCheck.java
index 5ad56aa..dbaaa32 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/AbstractClassCouplingCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/AbstractClassCouplingCheck.java
@@ -73,6 +73,7 @@
"List", "ArrayList", "Deque", "Queue", "LinkedList",
"Set", "HashSet", "SortedSet", "TreeSet",
"Map", "HashMap", "SortedMap", "TreeMap",
+ "Override", "Deprecated", "SafeVarargs", "SuppressWarnings", "FunctionalInterface",
}).collect(Collectors.toSet()));
/** Package names to ignore. */
@@ -177,6 +178,8 @@
case TokenTypes.ENUM_DEF:
visitClassDef(ast);
break;
+ case TokenTypes.EXTENDS_CLAUSE:
+ case TokenTypes.IMPLEMENTS_CLAUSE:
case TokenTypes.TYPE:
fileContext.visitType(ast);
break;
@@ -186,6 +189,9 @@
case TokenTypes.LITERAL_THROWS:
fileContext.visitLiteralThrows(ast);
break;
+ case TokenTypes.ANNOTATION:
+ fileContext.visitAnnotationType(ast);
+ break;
default:
throw new IllegalArgumentException("Unknown type: " + ast);
}
@@ -327,6 +333,16 @@
classContext.visitLiteralThrows(ast);
}
+ /**
+ * Visit ANNOTATION literal and get its type to referenced classes of context.
+ * @param annotationAST Annotation ast.
+ */
+ private void visitAnnotationType(DetailAST annotationAST) {
+ final DetailAST children = annotationAST.getFirstChild();
+ final DetailAST type = children.getNextSibling();
+ classContext.addReferencedClassName(type.getText());
+ }
+
}
/**
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheck.java
index cca6f62..8b5ed20 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheck.java
@@ -49,6 +49,9 @@
TokenTypes.PACKAGE_DEF,
TokenTypes.IMPORT,
TokenTypes.CLASS_DEF,
+ TokenTypes.EXTENDS_CLAUSE,
+ TokenTypes.IMPLEMENTS_CLAUSE,
+ TokenTypes.ANNOTATION,
TokenTypes.INTERFACE_DEF,
TokenTypes.ENUM_DEF,
TokenTypes.TYPE,
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheckTest.java
index aeb4890..8179b86 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/metrics/ClassFanOutComplexityCheckTest.java
@@ -141,7 +141,9 @@
checkConfig.addAttribute("max", "0");
- final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
+ final String[] expected = {
+ "9:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ };
verify(checkConfig, getPath("InputClassFanOutComplexity15Extensions.java"), expected);
}
@@ -165,6 +167,9 @@
TokenTypes.PACKAGE_DEF,
TokenTypes.IMPORT,
TokenTypes.CLASS_DEF,
+ TokenTypes.EXTENDS_CLAUSE,
+ TokenTypes.IMPLEMENTS_CLAUSE,
+ TokenTypes.ANNOTATION,
TokenTypes.INTERFACE_DEF,
TokenTypes.ENUM_DEF,
TokenTypes.TYPE,
@@ -230,4 +235,46 @@
getPath("InputClassFanOutComplexityPackageName.java"), expected);
}
+ @Test
+ public void testExtends() throws Exception {
+ final DefaultConfiguration checkConfig =
+ createModuleConfig(ClassFanOutComplexityCheck.class);
+ checkConfig.addAttribute("max", "0");
+ final String[] expected = {
+ "3:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ };
+ verify(checkConfig,
+ getPath("InputClassFanOutComplexityExtends.java"), expected);
+ }
+
+ @Test
+ public void testImplements() throws Exception {
+ final DefaultConfiguration checkConfig =
+ createModuleConfig(ClassFanOutComplexityCheck.class);
+ checkConfig.addAttribute("max", "0");
+ final String[] expected = {
+ "3:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ };
+ verify(checkConfig,
+ getPath("InputClassFanOutComplexityImplements.java"), expected);
+ }
+
+ @Test
+ public void testAnnotation() throws Exception {
+ final DefaultConfiguration checkConfig =
+ createModuleConfig(ClassFanOutComplexityCheck.class);
+ checkConfig.addAttribute("max", "0");
+ final String[] expected = {
+ "9:1: " + getCheckMessage(MSG_KEY, 2, 0),
+ "25:5: " + getCheckMessage(MSG_KEY, 2, 0),
+ "34:5: " + getCheckMessage(MSG_KEY, 3, 0),
+ "44:5: " + getCheckMessage(MSG_KEY, 2, 0),
+ "59:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ "79:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ "82:1: " + getCheckMessage(MSG_KEY, 1, 0),
+ };
+ verify(checkConfig,
+ getPath("InputClassFanOutComplexityAnnotations.java"), expected);
+ }
+
}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityAnnotations.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityAnnotations.java
new file mode 100644
index 0000000..62f0da5
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityAnnotations.java
@@ -0,0 +1,93 @@
+package com.puppycrawl.tools.checkstyle.checks.metrics.classfanoutcomplexity;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/* This input file is intended to be used on strict configuration: max=0 */
+public class InputClassFanOutComplexityAnnotations { // violation
+
+ private int tokenType = TokenTypes.EXPR;
+
+ public void foo1(@TypeAnnotation char a) {}
+
+ public void foo2(final char @TypeAnnotation [] a) {}
+
+ @MethodAnnotation
+ public void foo3() {}
+
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+ @MyAnnotation // violation
+ public class InnerClass {
+
+ @MyAnnotation
+ @MethodAnnotation
+ public void innerClassMethod() {}
+
+ }
+
+ public class InnerClass2 { // violation
+
+ @MethodAnnotation
+ @MyAnnotation
+ public String innerClass2Method(@TypeAnnotation String parameter) {
+ return parameter.trim();
+ }
+
+ }
+
+ public class InnerClass3 { // violation
+
+ @TypeAnnotation
+ private final String warningsType = "boxing";
+
+ @MyAnnotation
+ @SuppressWarnings(value = warningsType)
+ public String innerClass3Method() {
+ return new Integer(5).toString();
+ }
+
+ }
+
+}
+
+class OuterClass { // violation
+
+ private static final String name = "1";
+
+ private static final String value = "4";
+
+ @TwoParametersAnnotation(value = "4", tokenType = 1)
+ public static final String EMPTY_STRING = "";
+
+ @TwoParametersAnnotation(value = value, tokenType = TokenTypes.ANNOTATION)
+ public static final String TAB = "\t";
+
+}
+
+@Target(ElementType.TYPE_USE)
+@interface TypeAnnotation {}
+
+@Target(ElementType.METHOD)
+@interface MethodAnnotation {}
+
+@MyAnnotation // violation
+class MyClass {}
+
+@MyAnnotation // violation
+interface MyInterface {}
+
+@interface MyAnnotation {}
+
+@interface TwoParametersAnnotation {
+
+ String value();
+
+ int tokenType();
+
+}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityExtends.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityExtends.java
new file mode 100644
index 0000000..df83d54
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityExtends.java
@@ -0,0 +1,6 @@
+package com.puppycrawl.tools.checkstyle.checks.metrics.classfanoutcomplexity;
+
+public class InputClassFanOutComplexityExtends extends ParentClass {
+}
+
+class ParentClass {}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityImplements.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityImplements.java
new file mode 100644
index 0000000..4b17119
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/metrics/classfanoutcomplexity/InputClassFanOutComplexityImplements.java
@@ -0,0 +1,5 @@
+package com.puppycrawl.tools.checkstyle.checks.metrics.classfanoutcomplexity;
+
+public class InputClassFanOutComplexityImplements implements Interface {}
+
+interface Interface {}
diff --git a/src/xdocs/config_metrics.xml b/src/xdocs/config_metrics.xml
index c019663..64caa90 100644
--- a/src/xdocs/config_metrics.xml
+++ b/src/xdocs/config_metrics.xml
@@ -237,13 +237,14 @@
<td>excludedClasses</td>
<td>User-configured class names to ignore</td>
<td><a href="property_types.html#stringSet">String Set</a></td>
- <td>IllegalStateException, Set, StringBuilder, HashMap, ArrayList,
- String, float, SortedSet, long, RuntimeException, NullPointerException,
- TreeSet, List, Boolean, Void, Queue, Short, IllegalArgumentException,
- UnsupportedOperationException, HashSet, void, Character, IndexOutOfBoundsException,
- byte, double, SecurityException, TreeMap, Double, Deque, int, Exception, LinkedList,
- Integer, Float, StringBuffer, boolean, Byte, SortedMap, char, Long, short,
- Throwable, Object, Class, ArrayIndexOutOfBoundsException, Map</td>
+ <td>HashMap, ArrayList, String, float, TreeSet, List, Boolean, Void, Override, Short,
+ IllegalArgumentException, UnsupportedOperationException, HashSet, void, Character,
+ IndexOutOfBoundsException, byte, double, Double, LinkedList, Float, Byte,
+ SortedMap, Long, Throwable, Object, Class, Map, IllegalStateException, Set,
+ StringBuilder, SuppressWarnings, SortedSet, long, RuntimeException, Deprecated,
+ NullPointerException, Queue, SecurityException, FunctionalInterface, TreeMap,
+ Deque, int, Exception, Integer, SafeVarargs, StringBuffer, boolean, char, short,
+ ArrayIndexOutOfBoundsException</td>
<td>5.7</td>
</tr>
<tr>
@@ -486,47 +487,7 @@
This check processes files in the following way:
<ol>
<li>
- Iterates over the list of tokens (defined below) and counts all mentioned classes.
- <ul>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#PACKAGE_DEF">
- PACKAGE_DEF</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#IMPORT">
- IMPORT</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CLASS_DEF">
- CLASS_DEF</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#INTERFACE_DEF">
- INTERFACE_DEF</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ENUM_DEF">
- ENUM_DEF</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPE">
- TYPE</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_NEW">
- LITERAL_NEW</a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_THROWS">
- LITERAL_THROWS
- </a>
- </li>
- <li>
- <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ANNOTATION_DEF">
- ANNOTATION_DEF
- </a>
- </li>
- </ul>
+ Iterates over all tokens that might contain type reference.
</li>
<li>
If a class was imported with direct import (i.e.
@@ -563,13 +524,14 @@
<td>excludedClasses</td>
<td>User-configured class names to ignore</td>
<td><a href="property_types.html#stringSet">String Set</a></td>
- <td>IllegalStateException, Set, StringBuilder, HashMap, ArrayList,
- String, float, SortedSet, long, RuntimeException, NullPointerException,
- TreeSet, List, Boolean, Void, Queue, Short, IllegalArgumentException,
- UnsupportedOperationException, HashSet, void, Character, IndexOutOfBoundsException,
- byte, double, SecurityException, TreeMap, Double, Deque, int, Exception, LinkedList,
- Integer, Float, StringBuffer, boolean, Byte, SortedMap, char, Long, short,
- Throwable, Object, Class, ArrayIndexOutOfBoundsException, Map</td>
+ <td>HashMap, ArrayList, String, float, TreeSet, List, Boolean, Void, Override, Short,
+ IllegalArgumentException, UnsupportedOperationException, HashSet, void, Character,
+ IndexOutOfBoundsException, byte, double, Double, LinkedList, Float, Byte,
+ SortedMap, Long, Throwable, Object, Class, Map, IllegalStateException, Set,
+ StringBuilder, SuppressWarnings, SortedSet, long, RuntimeException, Deprecated,
+ NullPointerException, Queue, SecurityException, FunctionalInterface, TreeMap,
+ Deque, int, Exception, Integer, SafeVarargs, StringBuffer, boolean, char, short,
+ ArrayIndexOutOfBoundsException</td>
<td>5.7</td>
</tr>
<tr>