001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2018 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 032 /** Set of acceptable indentation levels. */ 033 private final BitSet levels = new BitSet(); 034 035 /** 036 * Creates new instance with one acceptable indentation level. 037 * @param indent acceptable indentation level. 038 */ 039 public IndentLevel(int indent) { 040 levels.set(indent); 041 } 042 043 /** 044 * Creates new instance for nested structure. 045 * @param base parent's level 046 * @param offsets offsets from parent's level. 047 */ 048 public IndentLevel(IndentLevel base, int... offsets) { 049 final BitSet src = base.levels; 050 for (int i = src.nextSetBit(0); i >= 0; i = src.nextSetBit(i + 1)) { 051 for (int offset : offsets) { 052 levels.set(i + offset); 053 } 054 } 055 } 056 057 /** 058 * Checks whether we have more than one level. 059 * @return whether we have more than one level. 060 */ 061 public final boolean isMultiLevel() { 062 return levels.cardinality() > 1; 063 } 064 065 /** 066 * Checks if given indentation is acceptable. 067 * @param indent indentation to check. 068 * @return true if given indentation is acceptable, 069 * false otherwise. 070 */ 071 public boolean isAcceptable(int indent) { 072 return levels.get(indent); 073 } 074 075 /** 076 * Returns true if indent less then minimal of 077 * acceptable indentation levels, false otherwise. 078 * @param indent indentation to check. 079 * @return true if {@code indent} less then minimal of 080 * acceptable indentation levels, false otherwise. 081 */ 082 public boolean isGreaterThan(int indent) { 083 return levels.nextSetBit(0) > indent; 084 } 085 086 /** 087 * Adds one more acceptable indentation level. 088 * @param indent new acceptable indentation. 089 */ 090 public void addAcceptedIndent(int indent) { 091 levels.set(indent); 092 } 093 094 /** 095 * Adds one more acceptable indentation level. 096 * @param indent new acceptable indentation. 097 */ 098 public void addAcceptedIndent(IndentLevel indent) { 099 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}