001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2015 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.checks.indentation; 021 022import java.util.BitSet; 023 024/** 025 * Encapsulates representation of notion of expected indentation levels. 026 * Provide a way to have multiple acceptable levels. 027 * 028 * @author o_sukhodolsky 029 */ 030public class IndentLevel { 031 /** Set of acceptable indentation levels. */ 032 private final BitSet levels = new BitSet(); 033 034 /** 035 * Creates new instance with one acceptable indentation level. 036 * @param indent acceptable indentation level. 037 */ 038 public IndentLevel(int indent) { 039 levels.set(indent); 040 } 041 042 /** 043 * Creates new instance for nested structure. 044 * @param base parent's level 045 * @param offsets offsets from parent's level. 046 */ 047 public IndentLevel(IndentLevel base, int... offsets) { 048 final BitSet src = base.levels; 049 for (int i = src.nextSetBit(0); i >= 0; i = src.nextSetBit(i + 1)) { 050 for (int offset : offsets) { 051 levels.set(i + offset); 052 } 053 } 054 } 055 056 /** 057 * Checks whether we have more than one level. 058 * @return whether we have more than one level. 059 */ 060 public final boolean isMultiLevel() { 061 return levels.cardinality() > 1; 062 } 063 064 /** 065 * Checks if given indentation is acceptable. 066 * @param indent indentation to check. 067 * @return true if given indentation is acceptable, 068 * false otherwise. 069 */ 070 public boolean isAcceptable(int indent) { 071 return levels.get(indent); 072 } 073 074 /** 075 * @param indent indentation to check. 076 * @return true if {@code indent} less then minimal of 077 * acceptable indentation levels, false otherwise. 078 */ 079 public boolean isGreaterThan(int indent) { 080 return levels.nextSetBit(0) > indent; 081 } 082 083 /** 084 * Adds one more acceptable indentation level. 085 * @param indent new acceptable indentation. 086 */ 087 public void addAcceptedIndent(int indent) { 088 levels.set(indent); 089 } 090 091 /** 092 * Adds one more acceptable indentation level. 093 * @param indent new acceptable indentation. 094 */ 095 public void addAcceptedIndent(IndentLevel indent) { 096 levels.or(indent.levels); 097 } 098 099 /** 100 * Returns first indentation level. 101 * @return indentation level. 102 */ 103 public int getFirstIndentLevel() { 104 return levels.nextSetBit(0); 105 } 106 107 /** 108 * Returns last indentation level. 109 * @return indentation level. 110 */ 111 public int getLastIndentLevel() { 112 return levels.length() - 1; 113 } 114 115 @Override 116 public String toString() { 117 if (levels.cardinality() == 1) { 118 return String.valueOf(levels.nextSetBit(0)); 119 } 120 final StringBuilder sb = new StringBuilder(); 121 for (int i = levels.nextSetBit(0); i >= 0; 122 i = levels.nextSetBit(i + 1)) { 123 if (sb.length() > 0) { 124 sb.append(", "); 125 } 126 sb.append(i); 127 } 128 return sb.toString(); 129 } 130}