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.utils;
21  
22  import java.util.AbstractMap;
23  import java.util.Map;
24  
25  import org.antlr.v4.runtime.CommonToken;
26  
27  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
28  import com.puppycrawl.tools.checkstyle.api.DetailAST;
29  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
30  
31  
32  
33  
34  public final class ParserUtil {
35  
36      
37      private static final String JAVADOC_START = "/**";
38      
39      private static final String BLOCK_MULTIPLE_COMMENT_BEGIN = "/*";
40      
41      private static final String BLOCK_MULTIPLE_COMMENT_END = "*/";
42  
43      
44      private ParserUtil() {
45      }
46  
47      
48  
49  
50  
51  
52  
53      public static DetailAST createBlockCommentNode(String content) {
54          final DetailAstImpl blockCommentBegin = new DetailAstImpl();
55          blockCommentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
56          blockCommentBegin.setText(BLOCK_MULTIPLE_COMMENT_BEGIN);
57          blockCommentBegin.setLineNo(0);
58          blockCommentBegin.setColumnNo(-JAVADOC_START.length());
59  
60          final DetailAstImpl commentContent = new DetailAstImpl();
61          commentContent.setType(TokenTypes.COMMENT_CONTENT);
62          commentContent.setText("*" + content);
63          commentContent.setLineNo(0);
64          
65          
66          commentContent.setColumnNo(-1);
67  
68          final DetailAstImpl blockCommentEnd = new DetailAstImpl();
69          blockCommentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
70          blockCommentEnd.setText(BLOCK_MULTIPLE_COMMENT_END);
71  
72          blockCommentBegin.setFirstChild(commentContent);
73          commentContent.setNextSibling(blockCommentEnd);
74          return blockCommentBegin;
75      }
76  
77      
78  
79  
80  
81  
82  
83      public static DetailAST createBlockCommentNode(CommonToken token) {
84          final DetailAstImpl blockComment = new DetailAstImpl();
85          blockComment.initialize(TokenTypes.BLOCK_COMMENT_BEGIN, BLOCK_MULTIPLE_COMMENT_BEGIN);
86  
87          final int tokenCharPositionInLine = token.getCharPositionInLine();
88          final int tokenLine = token.getLine();
89          final String tokenText = token.getText();
90  
91          blockComment.setColumnNo(tokenCharPositionInLine);
92          blockComment.setLineNo(tokenLine);
93  
94          final DetailAstImpl blockCommentContent = new DetailAstImpl();
95          blockCommentContent.setType(TokenTypes.COMMENT_CONTENT);
96  
97          
98          blockCommentContent.setColumnNo(tokenCharPositionInLine + 2);
99          blockCommentContent.setLineNo(tokenLine);
100         blockCommentContent.setText(tokenText);
101 
102         final DetailAstImpl blockCommentClose = new DetailAstImpl();
103         blockCommentClose.initialize(TokenTypes.BLOCK_COMMENT_END, BLOCK_MULTIPLE_COMMENT_END);
104 
105         final Map.Entry<Integer, Integer> linesColumns = countLinesColumns(
106                 tokenText, tokenLine, tokenCharPositionInLine + 1);
107         blockCommentClose.setLineNo(linesColumns.getKey());
108         blockCommentClose.setColumnNo(linesColumns.getValue());
109 
110         blockComment.addChild(blockCommentContent);
111         blockComment.addChild(blockCommentClose);
112         return blockComment;
113     }
114 
115     
116 
117 
118 
119 
120 
121 
122 
123     private static Map.Entry<Integer, Integer> countLinesColumns(
124         String text, int initialLinesCnt, int initialColumnsCnt) {
125         int lines = initialLinesCnt;
126         int columns = initialColumnsCnt;
127         boolean foundCr = false;
128         for (char c : text.toCharArray()) {
129             if (c == '\n') {
130                 foundCr = false;
131                 lines++;
132                 columns = 0;
133             }
134             else {
135                 if (foundCr) {
136                     foundCr = false;
137                     lines++;
138                     columns = 0;
139                 }
140                 if (c == '\r') {
141                     foundCr = true;
142                 }
143                 columns++;
144             }
145         }
146         if (foundCr) {
147             lines++;
148             columns = 0;
149         }
150         return new AbstractMap.SimpleEntry<>(lines, columns);
151     }
152 }