1 /////////////////////////////////////////////////////////////////////////////////////////////// 2 // checkstyle: Checks Java source code and other text files for adherence to a set of rules. 3 // Copyright (C) 2001-2024 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.SortedMap; 23 import java.util.TreeMap; 24 25 import com.puppycrawl.tools.checkstyle.api.DetailAST; 26 import com.puppycrawl.tools.checkstyle.utils.CommonUtil; 27 28 /** 29 * Represents a set of abstract syntax tree. 30 * 31 */ 32 public class DetailAstSet { 33 34 /** 35 * The instance of {@code IndentationCheck} used by this class. 36 */ 37 private final IndentationCheck indentCheck; 38 39 /** 40 * Maps line numbers to their ast. 41 */ 42 private final SortedMap<Integer, DetailAST> astLines = new TreeMap<>(); 43 44 /** 45 * Construct an instance of this class with {@code IndentationCheck} parameters. 46 * 47 * @param indentCheck IndentationCheck parameters 48 */ 49 public DetailAstSet(IndentationCheck indentCheck) { 50 this.indentCheck = indentCheck; 51 } 52 53 /** 54 * Add ast to the set of ast. 55 * 56 * @param ast the ast to add 57 */ 58 public void addAst(DetailAST ast) { 59 addLineWithAst(ast.getLineNo(), ast); 60 } 61 62 /** 63 * Map ast with their line number. 64 * 65 * @param lineNo line number of ast to add 66 * @param ast ast to add 67 */ 68 private void addLineWithAst(int lineNo, DetailAST ast) { 69 astLines.put(lineNo, ast); 70 } 71 72 /** 73 * Get starting column number for the ast. 74 * 75 * @param lineNum the line number as key 76 * @return start column for ast 77 */ 78 public Integer getStartColumn(int lineNum) { 79 Integer startColumn = null; 80 final DetailAST ast = getAst(lineNum); 81 82 if (ast != null) { 83 startColumn = expandedTabsColumnNo(ast); 84 } 85 86 return startColumn; 87 } 88 89 /** 90 * Check if this set of ast is empty. 91 * 92 * @return true if empty, false otherwise 93 */ 94 public boolean isEmpty() { 95 return astLines.isEmpty(); 96 } 97 98 /** 99 * The first line in set of ast. 100 * 101 * @return first line in set of ast. 102 */ 103 public DetailAST firstLine() { 104 return astLines.get(astLines.firstKey()); 105 } 106 107 /** 108 * Get the ast corresponding to line number. 109 * 110 * @param lineNum line number of ast. 111 * @return ast with their corresponding line number or null if no mapping is present 112 */ 113 public DetailAST getAst(int lineNum) { 114 return astLines.get(lineNum); 115 } 116 117 /** 118 * Get the line number of the last line. 119 * 120 * @return the line number of the last line 121 */ 122 public Integer lastLine() { 123 return astLines.lastKey(); 124 } 125 126 /** 127 * Get the column number for the start of a given expression, expanding 128 * tabs out into spaces in the process. 129 * 130 * @param ast the expression to find the start of 131 * 132 * @return the column number for the start of the expression 133 */ 134 protected final int expandedTabsColumnNo(DetailAST ast) { 135 final String line = 136 indentCheck.getLine(ast.getLineNo() - 1); 137 138 return CommonUtil.lengthExpandedTabs(line, ast.getColumnNo(), 139 indentCheck.getIndentationTabWidth()); 140 } 141 142 }