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
52
53 @StatelessCheck
54 public class OverloadMethodsDeclarationOrderCheck extends AbstractCheck {
55
56
57
58
59
60 public static final String MSG_KEY = "overload.methods.declaration";
61
62 @Override
63 public int[] getDefaultTokens() {
64 return getRequiredTokens();
65 }
66
67 @Override
68 public int[] getAcceptableTokens() {
69 return getRequiredTokens();
70 }
71
72 @Override
73 public int[] getRequiredTokens() {
74 return new int[] {
75 TokenTypes.OBJBLOCK,
76 };
77 }
78
79 @Override
80 public void visitToken(DetailAST ast) {
81 final int parentType = ast.getParent().getType();
82
83 final int[] tokenTypes = {
84 TokenTypes.CLASS_DEF,
85 TokenTypes.ENUM_DEF,
86 TokenTypes.INTERFACE_DEF,
87 TokenTypes.LITERAL_NEW,
88 TokenTypes.RECORD_DEF,
89 };
90
91 if (TokenUtil.isOfType(parentType, tokenTypes)) {
92 checkOverloadMethodsGrouping(ast);
93 }
94 }
95
96
97
98
99
100
101
102
103 private void checkOverloadMethodsGrouping(DetailAST objectBlock) {
104 final int allowedDistance = 1;
105 DetailAST currentToken = objectBlock.getFirstChild();
106 final Map<String, Integer> methodIndexMap = new HashMap<>();
107 final Map<String, Integer> methodLineNumberMap = new HashMap<>();
108 int currentIndex = 0;
109 while (currentToken != null) {
110 if (currentToken.getType() == TokenTypes.METHOD_DEF) {
111 currentIndex++;
112 final String methodName =
113 currentToken.findFirstToken(TokenTypes.IDENT).getText();
114 final Integer previousIndex = methodIndexMap.get(methodName);
115 final DetailAST previousSibling = currentToken.getPreviousSibling();
116 final boolean isMethod = previousSibling.getType() == TokenTypes.METHOD_DEF;
117
118 if (previousIndex != null
119 && (!isMethod || currentIndex - previousIndex > allowedDistance)) {
120 final int previousLineWithOverloadMethod =
121 methodLineNumberMap.get(methodName);
122 log(currentToken, MSG_KEY,
123 previousLineWithOverloadMethod);
124 }
125 methodIndexMap.put(methodName, currentIndex);
126 methodLineNumberMap.put(methodName, currentToken.getLineNo());
127 }
128 currentToken = currentToken.getNextSibling();
129 }
130 }
131
132 }