View Javadoc
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.gui;
21  
22  import java.util.List;
23  
24  import com.puppycrawl.tools.checkstyle.api.DetailAST;
25  import com.puppycrawl.tools.checkstyle.api.DetailNode;
26  import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
27  
28  /**
29   * Presentation model for CodeSelector.
30   */
31  public class CodeSelectorPresentation {
32  
33      /** DetailAST or DetailNode node. */
34      private final Object node;
35      /** Mapping. */
36      private final List<Integer> lines2position;
37      /** Selection start position. */
38      private int selectionStart;
39      /** Selection end position. */
40      private int selectionEnd;
41  
42      /**
43       * Constructor.
44       *
45       * @param ast ast node.
46       * @param lines2position positions of lines.
47       * @noinspection AssignmentOrReturnOfFieldWithMutableType
48       * @noinspectionreason AssignmentOrReturnOfFieldWithMutableType - mutability is
49       *      expected in list of lines of code
50       */
51      public CodeSelectorPresentation(DetailAST ast, List<Integer> lines2position) {
52          node = ast;
53          this.lines2position = lines2position;
54      }
55  
56      /**
57       * Constructor.
58       *
59       * @param node DetailNode node.
60       * @param lines2position list to map lines.
61       * @noinspection AssignmentOrReturnOfFieldWithMutableType
62       * @noinspectionreason AssignmentOrReturnOfFieldWithMutableType - mutability is expected
63       *      in list of lines of code
64       */
65      public CodeSelectorPresentation(DetailNode node, List<Integer> lines2position) {
66          this.node = node;
67          this.lines2position = lines2position;
68      }
69  
70      /**
71       * Returns selection start position.
72       *
73       * @return selection start position.
74       */
75      public int getSelectionStart() {
76          return selectionStart;
77      }
78  
79      /**
80       * Returns selection end position.
81       *
82       * @return selection end position.
83       */
84      public int getSelectionEnd() {
85          return selectionEnd;
86      }
87  
88      /**
89       * Find start and end selection positions from AST line and Column.
90       */
91      public void findSelectionPositions() {
92          if (node instanceof DetailAST) {
93              findSelectionPositions((DetailAST) node);
94          }
95          else {
96              findSelectionPositions((DetailNode) node);
97          }
98      }
99  
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 }