Issue #3432: Added DetailNode support for CodeSelector, gui code selection and tests
This commit is contained in:
parent
23202260b2
commit
62d4bfe0dd
3
pom.xml
3
pom.xml
|
|
@ -1434,7 +1434,7 @@
|
|||
<exclude>com/puppycrawl/tools/checkstyle/grammars/javadoc/*.class</exclude>
|
||||
<!-- Swing related classes -->
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/BaseCellEditor*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/CodeSelector*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/CodeSelector.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/JTreeTable*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/ListToTreeSelectionModelWrapper*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/Main*.class</exclude>
|
||||
|
|
@ -1443,7 +1443,6 @@
|
|||
<exclude>com/puppycrawl/tools/checkstyle/gui/TreeTableCellRenderer*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/TreeTableModelAdapter*.class</exclude>
|
||||
<!-- GUI model classes without tests -->
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/CodeSelectorPModel*.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/gui/MainFrameModel*.class</exclude>
|
||||
<!-- deprecated classes -->
|
||||
<exclude>com/puppycrawl/tools/checkstyle/checks/AbstractFormatCheck.class</exclude>
|
||||
|
|
|
|||
|
|
@ -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<Integer> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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<Integer> lines2position;
|
||||
/** Selection start position. */
|
||||
|
|
@ -46,7 +47,18 @@ public class CodeSelectorPModel {
|
|||
* @param lines2position list to map lines.
|
||||
*/
|
||||
public CodeSelectorPModel(DetailAST ast, List<Integer> lines2position) {
|
||||
this.ast = ast;
|
||||
node = ast;
|
||||
final List<Integer> 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<Integer> lines2position) {
|
||||
this.node = node;
|
||||
final List<Integer> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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<Integer> 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<Integer> convertLinesToPosition(List<Integer> systemLinesToPosition) {
|
||||
final List<Integer> 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());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue