View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
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  import java.util.regex.Matcher;
11  import java.util.regex.Pattern;
12  
13  /**
14   * C++ style inline comment is not allowed.
15   * Use //-style comment instead.
16   * @since 0.18
17   */
18  public final class SingleLineCommentCheck extends AbstractCheck {
19  
20      /**
21       * Pattern for check.
22       * It is not final as it is initialized from the configuration.
23       */
24      private Pattern format = Pattern.compile("^$");
25  
26      /**
27       * The message to report for a match.
28       * It is not final as it is initialized from the configuration.
29       */
30      private String message = "";
31  
32      /**
33       * Comment line.
34       * It is not final because the visitToken method is called many times
35       * during the class under test and the field is reinitialized with a new object.
36       */
37      @SuppressWarnings("PMD.AvoidStringBufferField")
38      private final StringBuilder line = new StringBuilder();
39  
40      /**
41       * When inside a block comment, holds begin line number.
42       */
43      private int begin;
44  
45      @Override
46      public boolean isCommentNodesRequired() {
47          return true;
48      }
49  
50      @Override
51      public int[] getDefaultTokens() {
52          return new int[]{
53              TokenTypes.BLOCK_COMMENT_BEGIN,
54              TokenTypes.COMMENT_CONTENT,
55              TokenTypes.BLOCK_COMMENT_END,
56          };
57      }
58  
59      @Override
60      public int[] getAcceptableTokens() {
61          return this.getDefaultTokens();
62      }
63  
64      @Override
65      public int[] getRequiredTokens() {
66          return this.getDefaultTokens();
67      }
68  
69      @Override
70      public void visitToken(final DetailAST ast) {
71          if (ast.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) {
72              this.line.setLength(0);
73              this.line.append(ast.getText());
74              this.begin = ast.getLineNo();
75          } else if (ast.getType() == TokenTypes.COMMENT_CONTENT) {
76              this.line.append(ast.getText());
77          } else {
78              this.line.append(ast.getText());
79              final Matcher matcher = this.format.matcher(this.line.toString());
80              if (matcher.matches() && this.singleLineCStyleComment(ast)) {
81                  this.log(ast, this.message);
82              }
83          }
84      }
85  
86      /**
87       * The method is called from checkstyle to configure this class.
88       * The parameter is set from the checks.xml file
89       * <module name="com.qulice.checkstyle.SingleLineCommentCheck"/> and
90       * <property name="format" value=" this regexp "/> property
91       *
92       * @param fmt Validatig regexp.
93       */
94      public void setFormat(final String fmt) {
95          this.format = Pattern.compile(fmt);
96      }
97  
98      /**
99       * The method is called from checkstyle to configure this class.
100      * The parameter is set from the checks.xml file
101      * <module name="com.qulice.checkstyle.SingleLineCommentCheck"/> and
102      * <property name="message" value="This kind of comment is not allowed."/>
103      * property
104      *
105      * @param msg Error message.
106      */
107     public void setMessage(final String msg) {
108         this.message = msg;
109     }
110 
111     /**
112      * Checks for the end of a comment line.
113      * @param ast Checkstyle's AST nodes.
114      * @return True if this is the end of the comment
115      *  and the starting line number is equal to the ending line number.
116      */
117     private boolean singleLineCStyleComment(final DetailAST ast) {
118         return ast.getType() == TokenTypes.BLOCK_COMMENT_END && this.begin == ast.getLineNo();
119     }
120 }