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>