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.whitespace;
21
22 import java.util.Arrays;
23 import java.util.Locale;
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.CodePointUtil;
30 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
31
32
33
34
35
36
37
38
39 @StatelessCheck
40 public class SeparatorWrapCheck
41 extends AbstractCheck {
42
43
44
45
46
47 public static final String MSG_LINE_PREVIOUS = "line.previous";
48
49
50
51
52
53 public static final String MSG_LINE_NEW = "line.new";
54
55
56 private WrapOption option = WrapOption.EOL;
57
58
59
60
61 public SeparatorWrapCheck() {
62
63 }
64
65
66
67
68
69
70
71
72 public void setOption(String optionStr) {
73 option = WrapOption.valueOf(optionStr.trim().toUpperCase(Locale.ENGLISH));
74 }
75
76 @Override
77 public int[] getDefaultTokens() {
78 return new int[] {
79 TokenTypes.DOT,
80 TokenTypes.COMMA,
81 };
82 }
83
84 @Override
85 public int[] getAcceptableTokens() {
86 return new int[] {
87 TokenTypes.DOT,
88 TokenTypes.COMMA,
89 TokenTypes.SEMI,
90 TokenTypes.ELLIPSIS,
91 TokenTypes.AT,
92 TokenTypes.LPAREN,
93 TokenTypes.RPAREN,
94 TokenTypes.ARRAY_DECLARATOR,
95 TokenTypes.RBRACK,
96 TokenTypes.METHOD_REF,
97 };
98 }
99
100 @Override
101 public int[] getRequiredTokens() {
102 return CommonUtil.EMPTY_INT_ARRAY;
103 }
104
105 @Override
106 public void visitToken(DetailAST ast) {
107 final String text = ast.getText();
108 final int colNo = ast.getColumnNo();
109 final int lineNo = ast.getLineNo();
110 final int[] currentLine = getLineCodePoints(lineNo - 1);
111 final boolean isLineEmptyAfterToken = CodePointUtil.isBlank(
112 Arrays.copyOfRange(currentLine, colNo + text.length(), currentLine.length)
113 );
114 final boolean isLineEmptyBeforeToken = CodePointUtil.isBlank(
115 Arrays.copyOfRange(currentLine, 0, colNo)
116 );
117
118 if (option == WrapOption.NL
119 && isLineEmptyAfterToken) {
120 log(ast, MSG_LINE_NEW, text);
121 }
122 else if (option == WrapOption.EOL
123 && isLineEmptyBeforeToken) {
124 log(ast, MSG_LINE_PREVIOUS, text);
125 }
126 }
127
128 }