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  
62  
63  
64  
65      public void setOption(String optionStr) {
66          option = WrapOption.valueOf(optionStr.trim().toUpperCase(Locale.ENGLISH));
67      }
68  
69      @Override
70      public int[] getDefaultTokens() {
71          return new int[] {
72              TokenTypes.DOT,
73              TokenTypes.COMMA,
74          };
75      }
76  
77      @Override
78      public int[] getAcceptableTokens() {
79          return new int[] {
80              TokenTypes.DOT,
81              TokenTypes.COMMA,
82              TokenTypes.SEMI,
83              TokenTypes.ELLIPSIS,
84              TokenTypes.AT,
85              TokenTypes.LPAREN,
86              TokenTypes.RPAREN,
87              TokenTypes.ARRAY_DECLARATOR,
88              TokenTypes.RBRACK,
89              TokenTypes.METHOD_REF,
90          };
91      }
92  
93      @Override
94      public int[] getRequiredTokens() {
95          return CommonUtil.EMPTY_INT_ARRAY;
96      }
97  
98      @Override
99      public void visitToken(DetailAST ast) {
100         final String text = ast.getText();
101         final int colNo = ast.getColumnNo();
102         final int lineNo = ast.getLineNo();
103         final int[] currentLine = getLineCodePoints(lineNo - 1);
104         final boolean isLineEmptyAfterToken = CodePointUtil.isBlank(
105                 Arrays.copyOfRange(currentLine, colNo + text.length(), currentLine.length)
106         );
107         final boolean isLineEmptyBeforeToken = CodePointUtil.isBlank(
108                 Arrays.copyOfRange(currentLine, 0, colNo)
109         );
110 
111         if (option == WrapOption.NL
112                  && isLineEmptyAfterToken) {
113             log(ast, MSG_LINE_NEW, text);
114         }
115         else if (option == WrapOption.EOL
116                 && isLineEmptyBeforeToken) {
117             log(ast, MSG_LINE_PREVIOUS, text);
118         }
119     }
120 
121 }