diff --git a/pom.xml b/pom.xml
index 23379b30a..79db2afdb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1434,7 +1434,7 @@
com/puppycrawl/tools/checkstyle/grammars/javadoc/*.class
com/puppycrawl/tools/checkstyle/gui/BaseCellEditor*.class
- com/puppycrawl/tools/checkstyle/gui/CodeSelector*.class
+ com/puppycrawl/tools/checkstyle/gui/CodeSelector.class
com/puppycrawl/tools/checkstyle/gui/JTreeTable*.class
com/puppycrawl/tools/checkstyle/gui/ListToTreeSelectionModelWrapper*.class
com/puppycrawl/tools/checkstyle/gui/Main*.class
@@ -1443,7 +1443,6 @@
com/puppycrawl/tools/checkstyle/gui/TreeTableCellRenderer*.class
com/puppycrawl/tools/checkstyle/gui/TreeTableModelAdapter*.class
- com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel*.class
com/puppycrawl/tools/checkstyle/gui/MainFrameModel*.class
com/puppycrawl/tools/checkstyle/checks/AbstractFormatCheck.class
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelector.java b/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelector.java
index f336da633..359b4c5d2 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelector.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelector.java
@@ -25,6 +25,7 @@ import java.util.List;
import javax.swing.JTextArea;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
/**
* Helper class to select a code.
@@ -38,14 +39,19 @@ public class CodeSelector {
/**
* Constructor.
- * @param ast ast node.
+ * @param node ast node.
* @param editor text area editor.
* @param lines2position list to map lines.
*/
- public CodeSelector(final DetailAST ast, final JTextArea editor,
+ public CodeSelector(final Object node, final JTextArea editor,
final List lines2position) {
this.editor = editor;
- pModel = new CodeSelectorPModel(ast, lines2position);
+ if (node instanceof DetailAST) {
+ pModel = new CodeSelectorPModel((DetailAST) node, lines2position);
+ }
+ else {
+ pModel = new CodeSelectorPModel((DetailNode) node, lines2position);
+ }
}
/**
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel.java b/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel.java
index c5a942449..c4b161fd0 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.List;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
/**
@@ -31,8 +32,8 @@ import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
* @author unknown
*/
public class CodeSelectorPModel {
- /** DetailAST node. */
- private final DetailAST ast;
+ /** DetailAST or DetailNode node. */
+ private final Object node;
/** Mapping. */
private final List lines2position;
/** Selection start position. */
@@ -46,7 +47,18 @@ public class CodeSelectorPModel {
* @param lines2position list to map lines.
*/
public CodeSelectorPModel(DetailAST ast, List lines2position) {
- this.ast = ast;
+ node = ast;
+ final List copy = new ArrayList<>(lines2position);
+ this.lines2position = Collections.unmodifiableList(copy);
+ }
+
+ /**
+ * Constructor.
+ * @param node DetailNode node.
+ * @param lines2position list to map lines.
+ */
+ public CodeSelectorPModel(DetailNode node, List lines2position) {
+ this.node = node;
final List copy = new ArrayList<>(lines2position);
this.lines2position = Collections.unmodifiableList(copy);
}
@@ -69,6 +81,19 @@ public class CodeSelectorPModel {
* Find start and end selection positions from AST line and Column.
*/
public void findSelectionPositions() {
+ if (node instanceof DetailAST) {
+ findSelectionPositions((DetailAST) node);
+ }
+ else {
+ findSelectionPositions((DetailNode) node);
+ }
+ }
+
+ /**
+ * Find start and end selection positions from AST line and Column.
+ * @param ast DetailAST node for which selection finds
+ */
+ private void findSelectionPositions(DetailAST ast) {
selectionStart = lines2position.get(ast.getLineNo()) + ast.getColumnNo();
if (ast.getChildCount() == 0
@@ -80,6 +105,17 @@ public class CodeSelectorPModel {
}
}
+ /**
+ * Find start and end selection positions from DetailNode line and Column.
+ * @param detailNode DetailNode node for which selection finds
+ */
+ private void findSelectionPositions(DetailNode detailNode) {
+ selectionStart = lines2position.get(detailNode.getLineNumber())
+ + detailNode.getColumnNumber();
+
+ selectionEnd = findLastPosition(detailNode);
+ }
+
/**
* Finds the last position of node without children.
* @param astNode DetailAST node.
@@ -94,4 +130,23 @@ public class CodeSelectorPModel {
return findLastPosition(astNode.getLastChild());
}
}
+
+ /**
+ * Finds the last position of node without children.
+ * @param detailNode DetailNode node.
+ * @return Last position of node without children.
+ */
+ private int findLastPosition(final DetailNode detailNode) {
+ final int lastPosition;
+ if (detailNode.getChildren().length == 0) {
+ lastPosition = lines2position.get(detailNode.getLineNumber())
+ + detailNode.getColumnNumber() + detailNode.getText().length();
+ }
+ else {
+ final DetailNode lastChild =
+ detailNode.getChildren()[detailNode.getChildren().length - 1];
+ lastPosition = findLastPosition(lastChild);
+ }
+ return lastPosition;
+ }
}
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/gui/JTreeTable.java b/src/main/java/com/puppycrawl/tools/checkstyle/gui/JTreeTable.java
index 0e81fed0b..7bf064a62 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/gui/JTreeTable.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/gui/JTreeTable.java
@@ -142,9 +142,7 @@ public class JTreeTable extends JTable {
* Make selection of code in a text area.
*/
private void makeCodeSelection() {
- // temporary disabled. Have to deal with Javadoc nodes as well
- // see https://github.com/checkstyle/checkstyle/issues/3432
- new CodeSelector(null, editor, linePositionMap);
+ new CodeSelector(tree.getLastSelectedPathComponent(), editor, linePositionMap).select();
}
/**
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModelTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModelTest.java
new file mode 100644
index 000000000..db86f0d9e
--- /dev/null
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModelTest.java
@@ -0,0 +1,120 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2016 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.puppycrawl.tools.checkstyle.gui;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
+
+import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode;
+
+public class CodeSelectorPModelTest {
+
+ private MainFrameModel model;
+
+ private DetailAST tree;
+
+ private List linesToPosition;
+
+ @Before
+ public void loadFile() throws CheckstyleException {
+ model = new MainFrameModel();
+ model.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
+ model.openFile(new File(getPath("InputJavadocAttributesAndMethods.java")));
+ tree = ((DetailAST) model.getParseTreeTableModel().getRoot()).getFirstChild();
+ linesToPosition = convertLinesToPosition(model.getLinesToPosition());
+ }
+
+ private static String getPath(String filename) {
+ return "src/test/resources/com/puppycrawl/tools/checkstyle/gui/" + filename;
+ }
+
+ /** Converts lineToPosition from multicharacter to one character line separator
+ * needs to support crossplatform line separators
+ * @param systemLinesToPosition lines to position mapping for current system
+ * @return lines to position mapping with one character line separator
+ */
+ private static List convertLinesToPosition(List systemLinesToPosition) {
+ final List convertedLinesToPosition = new ArrayList<>();
+ final int lineSeparationCorrection = System.lineSeparator().length() - 1;
+ convertedLinesToPosition.add(0, systemLinesToPosition.get(0));
+ for (int i = 1; i < systemLinesToPosition.size(); i++) {
+ convertedLinesToPosition.add(i,
+ systemLinesToPosition.get(i) - lineSeparationCorrection * (i - 1));
+ }
+ return convertedLinesToPosition;
+ }
+
+ @Test
+ public void testDetailASTSelection() {
+ final CodeSelectorPModel selector = new CodeSelectorPModel(tree, linesToPosition);
+ selector.findSelectionPositions();
+ Assert.assertEquals(23, selector.getSelectionStart());
+ Assert.assertEquals(212, selector.getSelectionEnd());
+ }
+
+ @Test
+ public void testDetailASTLeafSelection() {
+ final DetailAST leaf = tree.getLastChild().getFirstChild();
+ final CodeSelectorPModel selector = new CodeSelectorPModel(leaf, linesToPosition);
+ selector.findSelectionPositions();
+ Assert.assertEquals(62, selector.getSelectionStart());
+ Assert.assertEquals(63, selector.getSelectionEnd());
+ }
+
+ @Test
+ public void testDetailASTNoSelection() {
+ final DetailAST leaf = tree.getFirstChild();
+ final CodeSelectorPModel selector = new CodeSelectorPModel(leaf, linesToPosition);
+ selector.findSelectionPositions();
+ Assert.assertEquals(23, selector.getSelectionStart());
+ Assert.assertEquals(23, selector.getSelectionEnd());
+ }
+
+ @Test
+ public void testDetailNodeSelection() {
+ final DetailNode javadoc = (DetailNode) model.getParseTreeTableModel()
+ .getChild(tree.getFirstChild().getNextSibling().getFirstChild(), 0);
+ final CodeSelectorPModel selector = new CodeSelectorPModel(javadoc, linesToPosition);
+ selector.findSelectionPositions();
+ Assert.assertEquals(0, selector.getSelectionStart());
+ Assert.assertEquals(25, selector.getSelectionEnd());
+ }
+
+ @Test
+ public void testDetailNodeLeafSelection() {
+ final DetailNode javadocLeaf = ((DetailNode) model.getParseTreeTableModel()
+ .getChild(tree.getFirstChild().getNextSibling().getFirstChild(), 0))
+ .getChildren()[2].getChildren()[0];
+ final CodeSelectorPModel selector = new CodeSelectorPModel(javadocLeaf, linesToPosition);
+ selector.findSelectionPositions();
+ Assert.assertEquals(5, selector.getSelectionStart());
+ Assert.assertEquals(6, selector.getSelectionEnd());
+ }
+
+}