1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks.coding;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import com.puppycrawl.tools.checkstyle.StatelessCheck;
26 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
27 import com.puppycrawl.tools.checkstyle.api.DetailAST;
28 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 @StatelessCheck
52 public class OverloadMethodsDeclarationOrderCheck extends AbstractCheck {
53
54
55
56
57
58 public static final String MSG_KEY = "overload.methods.declaration";
59
60 @Override
61 public int[] getDefaultTokens() {
62 return getRequiredTokens();
63 }
64
65 @Override
66 public int[] getAcceptableTokens() {
67 return getRequiredTokens();
68 }
69
70 @Override
71 public int[] getRequiredTokens() {
72 return new int[] {
73 TokenTypes.OBJBLOCK,
74 };
75 }
76
77 @Override
78 public void visitToken(DetailAST ast) {
79 final int parentType = ast.getParent().getType();
80
81 final int[] tokenTypes = {
82 TokenTypes.CLASS_DEF,
83 TokenTypes.ENUM_DEF,
84 TokenTypes.INTERFACE_DEF,
85 TokenTypes.LITERAL_NEW,
86 TokenTypes.RECORD_DEF,
87 };
88
89 if (TokenUtil.isOfType(parentType, tokenTypes)) {
90 checkOverloadMethodsGrouping(ast);
91 }
92 }
93
94
95
96
97
98
99
100
101 private void checkOverloadMethodsGrouping(DetailAST objectBlock) {
102 final int allowedDistance = 1;
103 DetailAST currentToken = objectBlock.getFirstChild();
104 final Map<String, Integer> methodIndexMap = new HashMap<>();
105 final Map<String, Integer> methodLineNumberMap = new HashMap<>();
106 int currentIndex = 0;
107 while (currentToken != null) {
108 if (currentToken.getType() == TokenTypes.METHOD_DEF) {
109 currentIndex++;
110 final String methodName =
111 currentToken.findFirstToken(TokenTypes.IDENT).getText();
112 final Integer previousIndex = methodIndexMap.get(methodName);
113 final DetailAST previousSibling = currentToken.getPreviousSibling();
114 final boolean isMethod = previousSibling.getType() == TokenTypes.METHOD_DEF;
115
116 if (previousIndex != null
117 && (!isMethod || currentIndex - previousIndex > allowedDistance)) {
118 final int previousLineWithOverloadMethod =
119 methodLineNumberMap.get(methodName);
120 log(currentToken, MSG_KEY,
121 previousLineWithOverloadMethod);
122 }
123 methodIndexMap.put(methodName, currentIndex);
124 methodLineNumberMap.put(methodName, currentToken.getLineNo());
125 }
126 currentToken = currentToken.getNextSibling();
127 }
128 }
129
130 }