View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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 java.util.BitSet;
23  
24  /**
25   * Encapsulates representation of notion of expected indentation levels.
26   * Provide a way to have multiple acceptable levels.
27   *
28   * @author o_sukhodolsky
29   */
30  public class IndentLevel {
31      /** Set of acceptable indentation levels. */
32      private final BitSet levels = new BitSet();
33  
34      /**
35       * Creates new instance with one acceptable indentation level.
36       * @param indent acceptable indentation level.
37       */
38      public IndentLevel(int indent) {
39          levels.set(indent);
40      }
41  
42      /**
43       * Creates new instance for nested structure.
44       * @param base parent's level
45       * @param offsets offsets from parent's level.
46       */
47      public IndentLevel(IndentLevel base, int... offsets) {
48          final BitSet src = base.levels;
49          for (int i = src.nextSetBit(0); i >= 0; i = src.nextSetBit(i + 1)) {
50              for (int offset : offsets) {
51                  levels.set(i + offset);
52              }
53          }
54      }
55  
56      /**
57       * Checks whether we have more than one level.
58       * @return whether we have more than one level.
59       */
60      public final boolean isMultiLevel() {
61          return levels.cardinality() > 1;
62      }
63  
64      /**
65       * Checks if given indentation is acceptable.
66       * @param indent indentation to check.
67       * @return true if given indentation is acceptable,
68       *         false otherwise.
69       */
70      public boolean isAcceptable(int indent) {
71          return levels.get(indent);
72      }
73  
74      /**
75       * Returns true if indent less then minimal of
76       * acceptable indentation levels, false otherwise.
77       * @param indent indentation to check.
78       * @return true if {@code indent} less then minimal of
79       *         acceptable indentation levels, false otherwise.
80       */
81      public boolean isGreaterThan(int indent) {
82          return levels.nextSetBit(0) > indent;
83      }
84  
85      /**
86       * Adds one more acceptable indentation level.
87       * @param indent new acceptable indentation.
88       */
89      public void addAcceptedIndent(int indent) {
90          levels.set(indent);
91      }
92  
93      /**
94       * Adds one more acceptable indentation level.
95       * @param indent new acceptable indentation.
96       */
97      public void addAcceptedIndent(IndentLevel indent) {
98          levels.or(indent.levels);
99      }
100 
101     /**
102      * Returns first indentation level.
103      * @return indentation level.
104      */
105     public int getFirstIndentLevel() {
106         return levels.nextSetBit(0);
107     }
108 
109     /**
110      * Returns last indentation level.
111      * @return indentation level.
112      */
113     public int getLastIndentLevel() {
114         return levels.length() - 1;
115     }
116 
117     @Override
118     public String toString() {
119         final String result;
120         if (levels.cardinality() == 1) {
121             result = String.valueOf(levels.nextSetBit(0));
122         }
123         else {
124             final StringBuilder sb = new StringBuilder(50);
125             for (int i = levels.nextSetBit(0); i >= 0;
126                  i = levels.nextSetBit(i + 1)) {
127                 if (sb.length() > 0) {
128                     sb.append(", ");
129                 }
130                 sb.append(i);
131             }
132             result = sb.toString();
133         }
134         return result;
135     }
136 }