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