001/////////////////////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code and other text files for adherence to a set of rules. 003// Copyright (C) 2001-2024 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.gui; 021 022import java.util.List; 023 024import com.puppycrawl.tools.checkstyle.api.DetailAST; 025import com.puppycrawl.tools.checkstyle.api.DetailNode; 026import com.puppycrawl.tools.checkstyle.utils.TokenUtil; 027 028/** 029 * Presentation model for CodeSelector. 030 */ 031public class CodeSelectorPresentation { 032 033 /** DetailAST or DetailNode node. */ 034 private final Object node; 035 /** Mapping. */ 036 private final List<Integer> lines2position; 037 /** Selection start position. */ 038 private int selectionStart; 039 /** Selection end position. */ 040 private int selectionEnd; 041 042 /** 043 * Constructor. 044 * 045 * @param ast ast node. 046 * @param lines2position positions of lines. 047 * @noinspection AssignmentOrReturnOfFieldWithMutableType 048 * @noinspectionreason AssignmentOrReturnOfFieldWithMutableType - mutability is 049 * expected in list of lines of code 050 */ 051 public CodeSelectorPresentation(DetailAST ast, List<Integer> lines2position) { 052 node = ast; 053 this.lines2position = lines2position; 054 } 055 056 /** 057 * Constructor. 058 * 059 * @param node DetailNode node. 060 * @param lines2position list to map lines. 061 * @noinspection AssignmentOrReturnOfFieldWithMutableType 062 * @noinspectionreason AssignmentOrReturnOfFieldWithMutableType - mutability is expected 063 * in list of lines of code 064 */ 065 public CodeSelectorPresentation(DetailNode node, List<Integer> lines2position) { 066 this.node = node; 067 this.lines2position = lines2position; 068 } 069 070 /** 071 * Returns selection start position. 072 * 073 * @return selection start position. 074 */ 075 public int getSelectionStart() { 076 return selectionStart; 077 } 078 079 /** 080 * Returns selection end position. 081 * 082 * @return selection end position. 083 */ 084 public int getSelectionEnd() { 085 return selectionEnd; 086 } 087 088 /** 089 * Find start and end selection positions from AST line and Column. 090 */ 091 public void findSelectionPositions() { 092 if (node instanceof DetailAST) { 093 findSelectionPositions((DetailAST) node); 094 } 095 else { 096 findSelectionPositions((DetailNode) node); 097 } 098 } 099 100 /** 101 * Find start and end selection positions from AST line and Column. 102 * 103 * @param ast DetailAST node for which selection finds 104 */ 105 private void findSelectionPositions(DetailAST ast) { 106 selectionStart = lines2position.get(ast.getLineNo()) + ast.getColumnNo(); 107 108 if (ast.hasChildren() || !TokenUtil.getTokenName(ast.getType()).equals(ast.getText())) { 109 selectionEnd = findLastPosition(ast); 110 } 111 else { 112 selectionEnd = selectionStart; 113 } 114 } 115 116 /** 117 * Find start and end selection positions from DetailNode line and Column. 118 * 119 * @param detailNode DetailNode node for which selection finds 120 */ 121 private void findSelectionPositions(DetailNode detailNode) { 122 selectionStart = lines2position.get(detailNode.getLineNumber()) 123 + detailNode.getColumnNumber(); 124 125 selectionEnd = findLastPosition(detailNode); 126 } 127 128 /** 129 * Finds the last position of node without children. 130 * 131 * @param astNode DetailAST node. 132 * @return Last position of node without children. 133 */ 134 private int findLastPosition(final DetailAST astNode) { 135 final int lastPosition; 136 if (astNode.hasChildren()) { 137 lastPosition = findLastPosition(astNode.getLastChild()); 138 } 139 else { 140 lastPosition = lines2position.get(astNode.getLineNo()) + astNode.getColumnNo() 141 + astNode.getText().length(); 142 } 143 return lastPosition; 144 } 145 146 /** 147 * Finds the last position of node without children. 148 * 149 * @param detailNode DetailNode node. 150 * @return Last position of node without children. 151 */ 152 private int findLastPosition(final DetailNode detailNode) { 153 final int lastPosition; 154 if (detailNode.getChildren().length == 0) { 155 lastPosition = lines2position.get(detailNode.getLineNumber()) 156 + detailNode.getColumnNumber() + detailNode.getText().length(); 157 } 158 else { 159 final DetailNode lastChild = 160 detailNode.getChildren()[detailNode.getChildren().length - 1]; 161 lastPosition = findLastPosition(lastChild); 162 } 163 return lastPosition; 164 } 165 166}