View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.checks.indentation;
21  
22  import com.puppycrawl.tools.checkstyle.api.DetailAST;
23  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24  
25  /**
26   * Handler for class definitions.
27   *
28   */
29  public class ClassDefHandler extends BlockParentHandler {
30  
31      /**
32       * Construct an instance of this handler with the given indentation check,
33       * abstract syntax tree, and parent handler.
34       *
35       * @param indentCheck   the indentation check
36       * @param ast           the abstract syntax tree
37       * @param parent        the parent handler
38       */
39      public ClassDefHandler(IndentationCheck indentCheck,
40                             DetailAST ast,
41                             AbstractExpressionHandler parent) {
42          super(indentCheck, getHandlerName(ast), ast, parent);
43      }
44  
45      @Override
46      protected DetailAST getLeftCurly() {
47          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK)
48              .findFirstToken(TokenTypes.LCURLY);
49      }
50  
51      @Override
52      protected DetailAST getRightCurly() {
53          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK)
54              .findFirstToken(TokenTypes.RCURLY);
55      }
56  
57      @Override
58      protected DetailAST getTopLevelAst() {
59          return null;
60          // note: ident checked by hand in check indentation;
61      }
62  
63      @Override
64      protected DetailAST getListChild() {
65          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK);
66      }
67  
68      @Override
69      public void checkIndentation() {
70          final DetailAST modifiers = getMainAst().findFirstToken(TokenTypes.MODIFIERS);
71          if (modifiers.hasChildren()) {
72              checkModifiers();
73          }
74          else {
75              if (getMainAst().getType() != TokenTypes.ANNOTATION_DEF) {
76                  final DetailAST ident = getMainAst().findFirstToken(TokenTypes.IDENT);
77                  final int lineStart = getLineStart(ident);
78                  if (!getIndent().isAcceptable(lineStart)) {
79                      logError(ident, "ident", lineStart);
80                  }
81              }
82          }
83          if (getMainAst().getType() == TokenTypes.ANNOTATION_DEF) {
84              final DetailAST atAst = getMainAst().findFirstToken(TokenTypes.AT);
85              if (isOnStartOfLine(atAst)) {
86                  checkWrappingIndentation(getMainAst(), getListChild(), 0,
87                          getIndent().getFirstIndentLevel(), false);
88              }
89          }
90          else {
91              checkWrappingIndentation(getMainAst(), getListChild());
92          }
93          super.checkIndentation();
94      }
95  
96      @Override
97      protected int[] getCheckedChildren() {
98          return new int[] {
99              TokenTypes.EXPR,
100             TokenTypes.OBJBLOCK,
101             TokenTypes.LITERAL_BREAK,
102             TokenTypes.LITERAL_RETURN,
103             TokenTypes.LITERAL_THROW,
104             TokenTypes.LITERAL_CONTINUE,
105         };
106     }
107 
108     /**
109      * Creates a handler name for this class according to ast type.
110      *
111      * @param ast the abstract syntax tree.
112      * @return handler name for this class.
113      */
114     private static String getHandlerName(DetailAST ast) {
115         final String name;
116         final int tokenType = ast.getType();
117 
118         switch (tokenType) {
119             case TokenTypes.CLASS_DEF:
120                 name = "class def";
121                 break;
122             case TokenTypes.ENUM_DEF:
123                 name = "enum def";
124                 break;
125             case TokenTypes.ANNOTATION_DEF:
126                 name = "annotation def";
127                 break;
128             case TokenTypes.RECORD_DEF:
129                 name = "record def";
130                 break;
131             default:
132                 name = "interface def";
133         }
134 
135         return name;
136     }
137 
138 }