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