1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.google.common.collect.Lists;
8 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
9 import com.puppycrawl.tools.checkstyle.api.DetailAST;
10 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
11 import com.puppycrawl.tools.checkstyle.utils.AnnotationUtil;
12 import java.util.List;
13
14
15
16
17
18
19
20 public final class ProtectedMethodInFinalClassCheck extends AbstractCheck {
21
22 @Override
23 public int[] getDefaultTokens() {
24 return new int[] {
25 TokenTypes.CLASS_DEF,
26 };
27 }
28
29 @Override
30 public int[] getAcceptableTokens() {
31 return this.getDefaultTokens();
32 }
33
34 @Override
35 public int[] getRequiredTokens() {
36 return this.getDefaultTokens();
37 }
38
39 @Override
40 public void visitToken(final DetailAST ast) {
41 if (ast.getType() == TokenTypes.CLASS_DEF) {
42 final DetailAST modifiers = ast.findFirstToken(
43 TokenTypes.MODIFIERS
44 );
45 if (modifiers.findFirstToken(TokenTypes.FINAL) != null) {
46 this.checkMethods(ast);
47 }
48 }
49 }
50
51
52
53
54
55 private void checkMethods(final DetailAST ast) {
56 final DetailAST objblock = ast.findFirstToken(TokenTypes.OBJBLOCK);
57 for (final DetailAST method
58 : ProtectedMethodInFinalClassCheck.findAllChildren(
59 objblock, TokenTypes.METHOD_DEF
60 )
61 ) {
62 if (method
63 .findFirstToken(TokenTypes.MODIFIERS)
64 .findFirstToken(TokenTypes.LITERAL_PROTECTED) != null) {
65 if (AnnotationUtil.containsAnnotation(method, "Override")) {
66 this.log(
67 method.getLineNo(),
68 "Protected method is overriding default scoped method"
69 );
70 } else {
71 this.log(
72 method.getLineNo(),
73 "Final class should not contain protected methods"
74 );
75 }
76 }
77 }
78 }
79
80
81
82
83
84
85
86 private static Iterable<DetailAST> findAllChildren(final DetailAST base,
87 final int type) {
88 final List<DetailAST> children = Lists.newArrayList();
89 DetailAST child = base.getFirstChild();
90 while (child != null) {
91 if (child.getType() == type) {
92 children.add(child);
93 }
94 child = child.getNextSibling();
95 }
96 return children;
97 }
98 }