1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
8 import com.puppycrawl.tools.checkstyle.api.DetailAST;
9 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public final class MethodDeclarationLengthCheck extends AbstractCheck {
41
42
43
44
45 private int max = 80;
46
47
48
49
50
51 public void setMax(final int value) {
52 this.max = value;
53 }
54
55 @Override
56 public int[] getDefaultTokens() {
57 return this.getRequiredTokens();
58 }
59
60 @Override
61 public int[] getAcceptableTokens() {
62 return this.getRequiredTokens();
63 }
64
65 @Override
66 public int[] getRequiredTokens() {
67 return new int[] {TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF};
68 }
69
70 @Override
71 public void visitToken(final DetailAST ast) {
72 final DetailAST start = MethodDeclarationLengthCheck.head(ast);
73 final DetailAST end = MethodDeclarationLengthCheck.tail(ast);
74 if (start != null && end != null
75 && start.getLineNo() < end.getLineNo()) {
76 this.verify(start, end);
77 }
78 }
79
80
81
82
83
84
85 private void verify(final DetailAST start, final DetailAST end) {
86 final String[] lines = this.getLines();
87 final int first = start.getLineNo();
88 final int last = end.getLineNo();
89 final int col = start.getColumnNo();
90 final StringBuilder joined = new StringBuilder(
91 lines[first - 1].substring(col).trim()
92 );
93 for (int idx = first; idx < last; idx += 1) {
94 final String trimmed = lines[idx].trim();
95 if (!trimmed.isEmpty()) {
96 joined.append(' ').append(trimmed);
97 }
98 }
99 if (col + joined.length() <= this.max) {
100 this.log(
101 first,
102 "Method declaration can be placed on a single line"
103 );
104 }
105 }
106
107
108
109
110
111
112
113 private static DetailAST head(final DetailAST def) {
114 final DetailAST modifiers = def.findFirstToken(TokenTypes.MODIFIERS);
115 DetailAST child = modifiers.getFirstChild();
116 while (child != null && child.getType() == TokenTypes.ANNOTATION) {
117 child = child.getNextSibling();
118 }
119 final DetailAST result;
120 if (child == null) {
121 DetailAST fallback = def.findFirstToken(TokenTypes.TYPE);
122 if (fallback == null) {
123 fallback = def.findFirstToken(TokenTypes.IDENT);
124 }
125 result = fallback;
126 } else {
127 result = child;
128 }
129 return result;
130 }
131
132
133
134
135
136
137
138 private static DetailAST tail(final DetailAST def) {
139 DetailAST end = def.findFirstToken(TokenTypes.SLIST);
140 if (end == null) {
141 end = def.findFirstToken(TokenTypes.SEMI);
142 }
143 return end;
144 }
145 }