View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2018 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   * @author jrichard
29   */
30  public class ClassDefHandler extends BlockParentHandler {
31  
32      /**
33       * Construct an instance of this handler with the given indentation check,
34       * abstract syntax tree, and parent handler.
35       *
36       * @param indentCheck   the indentation check
37       * @param ast           the abstract syntax tree
38       * @param parent        the parent handler
39       */
40      public ClassDefHandler(IndentationCheck indentCheck,
41                             DetailAST ast,
42                             AbstractExpressionHandler parent) {
43          super(indentCheck, getHandlerName(ast), ast, parent);
44      }
45  
46      @Override
47      protected DetailAST getLeftCurly() {
48          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK)
49              .findFirstToken(TokenTypes.LCURLY);
50      }
51  
52      @Override
53      protected DetailAST getRightCurly() {
54          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK)
55              .findFirstToken(TokenTypes.RCURLY);
56      }
57  
58      @Override
59      protected DetailAST getTopLevelAst() {
60          return null;
61          // note: ident checked by hand in check indentation;
62      }
63  
64      @Override
65      protected DetailAST getListChild() {
66          return getMainAst().findFirstToken(TokenTypes.OBJBLOCK);
67      }
68  
69      @Override
70      public void checkIndentation() {
71          final DetailAST modifiers = getMainAst().findFirstToken(TokenTypes.MODIFIERS);
72          if (modifiers.getChildCount() == 0) {
73              if (getMainAst().getType() != TokenTypes.ANNOTATION_DEF) {
74                  final DetailAST ident = getMainAst().findFirstToken(TokenTypes.IDENT);
75                  final int lineStart = getLineStart(ident);
76                  if (!getIndent().isAcceptable(lineStart)) {
77                      logError(ident, "ident", lineStart);
78                  }
79              }
80          }
81          else {
82              checkModifiers();
83          }
84          if (getMainAst().getType() == TokenTypes.ANNOTATION_DEF) {
85              final DetailAST atAst = getMainAst().findFirstToken(TokenTypes.AT);
86              if (isOnStartOfLine(atAst)) {
87                  checkWrappingIndentation(getMainAst(), getListChild(), 0,
88                          getIndent().getFirstIndentLevel(), false);
89              }
90          }
91          else {
92              checkWrappingIndentation(getMainAst(), getListChild());
93          }
94          super.checkIndentation();
95      }
96  
97      @Override
98      protected int[] getCheckedChildren() {
99          return new int[] {
100             TokenTypes.EXPR,
101             TokenTypes.OBJBLOCK,
102             TokenTypes.LITERAL_BREAK,
103             TokenTypes.LITERAL_RETURN,
104             TokenTypes.LITERAL_THROW,
105             TokenTypes.LITERAL_CONTINUE,
106         };
107     }
108 
109     /**
110      * Creates a handler name for this class according to ast type.
111      *
112      * @param ast the abstract syntax tree.
113      * @return handler name for this class.
114      */
115     private static String getHandlerName(DetailAST ast) {
116         final String name;
117 
118         if (ast.getType() == TokenTypes.CLASS_DEF) {
119             name = "class def";
120         }
121         else if (ast.getType() == TokenTypes.ENUM_DEF) {
122             name = "enum def";
123         }
124         else if (ast.getType() == TokenTypes.ANNOTATION_DEF) {
125             name = "annotation def";
126         }
127         else {
128             name = "interface def";
129         }
130         return name;
131     }
132 
133 }