001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2017 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 * Returns true if indent less then minimal of 076 * acceptable indentation levels, false otherwise. 077 * @param indent indentation to check. 078 * @return true if {@code indent} less then minimal of 079 * acceptable indentation levels, false otherwise. 080 */ 081 public boolean isGreaterThan(int indent) { 082 return levels.nextSetBit(0) > indent; 083 } 084 085 /** 086 * Adds one more acceptable indentation level. 087 * @param indent new acceptable indentation. 088 */ 089 public void addAcceptedIndent(int indent) { 090 levels.set(indent); 091 } 092 093 /** 094 * Adds one more acceptable indentation level. 095 * @param indent new acceptable indentation. 096 */ 097 public void addAcceptedIndent(IndentLevel indent) { 098 levels.or(indent.levels); 099 } 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 if (levels.cardinality() == 1) { 120 return String.valueOf(levels.nextSetBit(0)); 121 } 122 final StringBuilder sb = new StringBuilder(); 123 for (int i = levels.nextSetBit(0); i >= 0; 124 i = levels.nextSetBit(i + 1)) { 125 if (sb.length() > 0) { 126 sb.append(", "); 127 } 128 sb.append(i); 129 } 130 return sb.toString(); 131 } 132}