forked from phoedos/pmd
Fix scala text bounds
This commit is contained in:
@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.ast.test
|
||||
|
||||
import io.kotlintest.should
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import io.kotlintest.shouldBe as ktShouldBe
|
||||
|
||||
/**
|
||||
@ -21,6 +22,7 @@ private fun <N, V> assertWrapper(callable: KCallable<N>, right: V, asserter: (N,
|
||||
fun formatName() = "::" + callable.name.removePrefix("get").decapitalize()
|
||||
|
||||
val value: N = try {
|
||||
callable.isAccessible = true
|
||||
callable.call()
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException("Couldn't fetch value for property ${formatName()}", e)
|
||||
|
@ -25,6 +25,12 @@
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -49,5 +55,10 @@
|
||||
<artifactId>pmd-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-lang-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -14,7 +14,6 @@ import org.apache.commons.io.IOUtils;
|
||||
import net.sourceforge.pmd.lang.AbstractParser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.TokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.ParseException;
|
||||
import net.sourceforge.pmd.lang.scala.ast.ASTSource;
|
||||
|
||||
|
@ -18,21 +18,47 @@ import scala.meta.inputs.Position;
|
||||
*/
|
||||
abstract class AbstractScalaNode<T extends Tree> extends AbstractNode implements ScalaNode<T> {
|
||||
private final T node;
|
||||
private final Position pos;
|
||||
|
||||
/**
|
||||
* Create the node and configure line numbers.
|
||||
*
|
||||
*
|
||||
* @param treeNode
|
||||
* the scala tree node this node wraps
|
||||
*/
|
||||
AbstractScalaNode(T treeNode) {
|
||||
super(0);
|
||||
node = treeNode;
|
||||
Position pos = node.pos();
|
||||
pos = node.pos();
|
||||
beginLine = pos.startLine() + 1;
|
||||
endLine = pos.endLine() + 1;
|
||||
beginColumn = pos.startColumn() + 1;
|
||||
endColumn = pos.endColumn() + 1;
|
||||
endColumn = pos.endColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImplicit() {
|
||||
return pos.end() - pos.start() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginLine() {
|
||||
return pos.startLine() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginColumn() {
|
||||
return pos.startColumn() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndLine() {
|
||||
return pos.endLine() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndColumn() {
|
||||
return pos.endColumn(); // no +1
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,14 +11,14 @@ import scala.meta.Tree;
|
||||
/**
|
||||
* A Base interface of a Scala Node. Defines several required methods of all
|
||||
* nodes.
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* The Scala node type that extends Scala's Tree trait
|
||||
*/
|
||||
public interface ScalaNode<T extends Tree> extends Node {
|
||||
/**
|
||||
* Accept a visitor and traverse this node.
|
||||
*
|
||||
*
|
||||
* @param <D>
|
||||
* The type of the data input
|
||||
* @param <R>
|
||||
@ -34,12 +34,24 @@ public interface ScalaNode<T extends Tree> extends Node {
|
||||
|
||||
/**
|
||||
* Get the underlying Scala Node.
|
||||
*
|
||||
*
|
||||
* @return the Scala Node for this node
|
||||
*/
|
||||
T getNode();
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the node is implicit. If this node has no non-implicit
|
||||
* descendant, then its text bounds identify an empty region of the source
|
||||
* document. In that case, the {@linkplain #getEndColumn() end column} is
|
||||
* smaller than the {@linkplain #getBeginColumn() begin column}.
|
||||
*/
|
||||
// TODO this would be useful on the node interface for 7.0.0.
|
||||
// we could filter them out from violations transparently
|
||||
// Apex has the same problem
|
||||
boolean isImplicit();
|
||||
|
||||
|
||||
@Override
|
||||
ScalaNode<?> jjtGetChild(int idx);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.scala;
|
||||
package net.sourceforge.pmd.lang.scala.ast;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.scala.rule;
|
||||
package net.sourceforge.pmd.lang.scala.rule;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
@ -30,7 +30,6 @@ import net.sourceforge.pmd.lang.scala.ScalaLanguageModule;
|
||||
import net.sourceforge.pmd.lang.scala.ast.ASTTermApply;
|
||||
import net.sourceforge.pmd.lang.scala.ast.ASTTermName;
|
||||
import net.sourceforge.pmd.lang.scala.ast.ScalaNode;
|
||||
import net.sourceforge.pmd.lang.scala.rule.ScalaRule;
|
||||
|
||||
public class ScalaRuleTest {
|
||||
private static final String SCALA_TEST = "/parserFiles/helloworld.scala";
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.scala.rule;
|
||||
package net.sourceforge.pmd.lang.scala.rule;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.scala.ast
|
||||
|
||||
import io.kotlintest.should
|
||||
import io.kotlintest.specs.FunSpec
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry
|
||||
import net.sourceforge.pmd.lang.ast.Node
|
||||
import net.sourceforge.pmd.lang.ast.test.matchNode
|
||||
import net.sourceforge.pmd.lang.ast.test.shouldBe
|
||||
import java.io.StringReader
|
||||
|
||||
class ScalaTreeTests : FunSpec({
|
||||
|
||||
|
||||
test("Test line/column numbers") {
|
||||
|
||||
"""
|
||||
class Foo {
|
||||
val I = ""
|
||||
}
|
||||
""".trim().parseScala() should matchNode<ASTSource> {
|
||||
|
||||
child<ASTDefnClass> {
|
||||
it.assertBounds(bline = 1, bcol = 1, eline = 3, ecol = 1)
|
||||
it::isImplicit shouldBe false
|
||||
|
||||
child<ASTTypeName> {
|
||||
it.assertBounds(bline = 1, bcol = 7, eline = 1, ecol = 9)
|
||||
it::isImplicit shouldBe false
|
||||
}
|
||||
|
||||
child<ASTCtorPrimary> {
|
||||
it.assertBounds(bline = 1, bcol = 11, eline = 1, ecol = 10) // node has zero length
|
||||
it::isImplicit shouldBe true
|
||||
|
||||
child<ASTNameAnonymous> {
|
||||
it.assertBounds(bline = 1, bcol = 11, eline = 1, ecol = 10) // node has zero length
|
||||
it::isImplicit shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
child<ASTTemplate> {
|
||||
it.assertBounds(bline = 1, bcol = 11, eline = 3, ecol = 1)
|
||||
it::isImplicit shouldBe false
|
||||
|
||||
child<ASTSelf> {
|
||||
it.assertBounds(bline = 2, bcol = 2, eline = 2, ecol = 1) // node has zero length
|
||||
it::isImplicit shouldBe true
|
||||
|
||||
child<ASTNameAnonymous> {
|
||||
it.assertBounds(bline = 2, bcol = 2, eline = 2, ecol = 1) // node has zero length
|
||||
it::isImplicit shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
child<ASTDefnVal> {
|
||||
it.assertBounds(bline = 2, bcol = 2, eline = 2, ecol = 11)
|
||||
it::isImplicit shouldBe false
|
||||
|
||||
child<ASTPatVar> {
|
||||
it.assertBounds(bline = 2, bcol = 6, eline = 2, ecol = 6)
|
||||
it::isImplicit shouldBe false
|
||||
|
||||
child<ASTTermName> {
|
||||
it.assertBounds(bline = 2, bcol = 6, eline = 2, ecol = 6)
|
||||
it::isImplicit shouldBe false
|
||||
}
|
||||
}
|
||||
|
||||
child<ASTLitString> {
|
||||
it.assertBounds(bline = 2, bcol = 10, eline = 2, ecol = 11)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fun String.parseScala(): ASTSource {
|
||||
val ver = LanguageRegistry.getLanguage("Scala").defaultVersion.languageVersionHandler
|
||||
val parser = ver.getParser(ver.defaultParserOptions)
|
||||
|
||||
return parser.parse(":dummy:", StringReader(this)) as ASTSource
|
||||
}
|
||||
|
||||
fun Node.assertBounds(bline: Int, bcol: Int, eline: Int, ecol: Int) {
|
||||
this::getBeginLine shouldBe bline
|
||||
this::getBeginColumn shouldBe bcol
|
||||
this::getEndLine shouldBe eline
|
||||
this::getEndColumn shouldBe ecol
|
||||
}
|
Reference in New Issue
Block a user