Merge branch 'text-utils-simple' into lang-registry-non-static
This commit is contained in:
@ -34,6 +34,24 @@
|
||||
</testResource>
|
||||
</testResources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@ -77,6 +95,15 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
|
@ -5,6 +5,10 @@
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.GenericToken;
|
||||
import net.sourceforge.pmd.lang.document.Chars;
|
||||
import net.sourceforge.pmd.lang.document.FileLocation;
|
||||
import net.sourceforge.pmd.lang.document.TextDocument;
|
||||
import net.sourceforge.pmd.lang.document.TextRegion;
|
||||
|
||||
import scala.meta.tokens.Token;
|
||||
|
||||
@ -13,11 +17,13 @@ import scala.meta.tokens.Token;
|
||||
*/
|
||||
public class ScalaTokenAdapter implements GenericToken<ScalaTokenAdapter> {
|
||||
|
||||
private Token token;
|
||||
private ScalaTokenAdapter previousComment;
|
||||
private final Token token;
|
||||
private final TextDocument textDocument;
|
||||
private final ScalaTokenAdapter previousComment;
|
||||
|
||||
ScalaTokenAdapter(Token token, ScalaTokenAdapter comment) {
|
||||
ScalaTokenAdapter(Token token, TextDocument textDocument, ScalaTokenAdapter comment) {
|
||||
this.token = token;
|
||||
this.textDocument = textDocument;
|
||||
this.previousComment = comment;
|
||||
}
|
||||
|
||||
@ -37,23 +43,18 @@ public class ScalaTokenAdapter implements GenericToken<ScalaTokenAdapter> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginLine() {
|
||||
return token.pos().startLine() + 1;
|
||||
public Chars getImageCs() {
|
||||
return textDocument.sliceText(getRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndLine() {
|
||||
return token.pos().endLine() + 1;
|
||||
public TextRegion getRegion() {
|
||||
return TextRegion.fromBothOffsets(token.pos().start(), token.pos().end());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginColumn() {
|
||||
return token.pos().startColumn() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndColumn() {
|
||||
return token.pos().endColumn() + 2;
|
||||
public FileLocation getReportLocation() {
|
||||
return textDocument.toLocation(getRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,6 +14,8 @@ import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.TokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.TokenMgrError;
|
||||
import net.sourceforge.pmd.lang.document.CpdCompat;
|
||||
import net.sourceforge.pmd.lang.document.TextDocument;
|
||||
import net.sourceforge.pmd.lang.scala.ScalaLanguageHandler;
|
||||
import net.sourceforge.pmd.lang.scala.ScalaLanguageModule;
|
||||
|
||||
@ -63,20 +65,19 @@ public class ScalaTokenizer implements Tokenizer {
|
||||
|
||||
@Override
|
||||
public void tokenize(SourceCode sourceCode, Tokens tokenEntries) throws IOException {
|
||||
String filename = sourceCode.getFileName();
|
||||
// create the full code file
|
||||
String fullCode = StringUtils.join(sourceCode.getCode(), "\n");
|
||||
|
||||
// create the input file for scala
|
||||
Input.VirtualFile vf = new Input.VirtualFile(filename, fullCode);
|
||||
ScalametaTokenizer tokenizer = new ScalametaTokenizer(vf, dialect);
|
||||
|
||||
// tokenize with a filter
|
||||
try {
|
||||
try (TextDocument textDoc = TextDocument.create(CpdCompat.cpdCompat(sourceCode))) {
|
||||
String fullCode = textDoc.getText().toString();
|
||||
|
||||
// create the input file for scala
|
||||
Input.VirtualFile vf = new Input.VirtualFile(sourceCode.getFileName(), fullCode);
|
||||
ScalametaTokenizer tokenizer = new ScalametaTokenizer(vf, dialect);
|
||||
|
||||
// tokenize with a filter
|
||||
scala.meta.tokens.Tokens tokens = tokenizer.tokenize();
|
||||
|
||||
// use extensions to the standard PMD TokenManager and Filter
|
||||
ScalaTokenManager scalaTokenManager = new ScalaTokenManager(tokens.iterator());
|
||||
ScalaTokenManager scalaTokenManager = new ScalaTokenManager(tokens.iterator(), textDoc);
|
||||
ScalaTokenFilter filter = new ScalaTokenFilter(scalaTokenManager);
|
||||
|
||||
ScalaTokenAdapter token;
|
||||
@ -85,10 +86,7 @@ public class ScalaTokenizer implements Tokenizer {
|
||||
continue;
|
||||
}
|
||||
TokenEntry cpdToken = new TokenEntry(token.getImage(),
|
||||
filename,
|
||||
token.getBeginLine(),
|
||||
token.getBeginColumn(),
|
||||
token.getEndColumn());
|
||||
token.getReportLocation());
|
||||
tokenEntries.add(cpdToken);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -96,7 +94,7 @@ public class ScalaTokenizer implements Tokenizer {
|
||||
// cannot catch it as it's a checked exception and Scala sneaky throws
|
||||
TokenizeException tokE = (TokenizeException) e;
|
||||
Position pos = tokE.pos();
|
||||
throw new TokenMgrError(pos.startLine() + 1, pos.startColumn() + 1, filename, "Scalameta threw", tokE);
|
||||
throw new TokenMgrError(pos.startLine() + 1, pos.startColumn() + 1, sourceCode.getFileName(), "Scalameta threw", tokE);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
@ -107,21 +105,25 @@ public class ScalaTokenizer implements Tokenizer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the generic Token Manager, also skips un-helpful tokens and comments to only register important tokens
|
||||
* Implementation of the generic Token Manager, also skips un-helpful tokens and comments to only register important
|
||||
* tokens
|
||||
* and patterns.
|
||||
*
|
||||
* Keeps track of comments, for special comment processing
|
||||
*/
|
||||
private static class ScalaTokenManager implements TokenManager<ScalaTokenAdapter> {
|
||||
|
||||
Iterator<Token> tokenIter;
|
||||
Class<?>[] skippableTokens = new Class<?>[] { Token.Space.class, Token.Tab.class, Token.CR.class,
|
||||
private final Iterator<Token> tokenIter;
|
||||
private final TextDocument textDocument;
|
||||
private static final Class<?>[] SKIPPABLE_TOKENS = {
|
||||
Token.Space.class, Token.Tab.class, Token.CR.class,
|
||||
Token.LF.class, Token.FF.class, Token.LFLF.class, Token.EOF.class, Token.Comment.class };
|
||||
|
||||
ScalaTokenAdapter previousComment = null;
|
||||
private ScalaTokenAdapter previousComment = null;
|
||||
|
||||
ScalaTokenManager(Iterator<Token> iterator) {
|
||||
ScalaTokenManager(Iterator<Token> iterator, TextDocument textDocument) {
|
||||
this.tokenIter = iterator;
|
||||
this.textDocument = textDocument;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,17 +136,17 @@ public class ScalaTokenizer implements Tokenizer {
|
||||
do {
|
||||
token = tokenIter.next();
|
||||
if (isComment(token)) {
|
||||
previousComment = new ScalaTokenAdapter(token, previousComment);
|
||||
previousComment = new ScalaTokenAdapter(token, textDocument, previousComment);
|
||||
}
|
||||
} while (token != null && skipToken(token) && tokenIter.hasNext());
|
||||
|
||||
return new ScalaTokenAdapter(token, previousComment);
|
||||
return new ScalaTokenAdapter(token, textDocument, previousComment);
|
||||
}
|
||||
|
||||
private boolean skipToken(Token token) {
|
||||
boolean skip = false;
|
||||
if (token.text() != null) {
|
||||
for (Class<?> skipTokenClazz : skippableTokens) {
|
||||
for (Class<?> skipTokenClazz : SKIPPABLE_TOKENS) {
|
||||
skip |= skipTokenClazz.isInstance(token);
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,13 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.scala.ast;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AstVisitor;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.impl.AbstractNode;
|
||||
import net.sourceforge.pmd.lang.document.FileLocation;
|
||||
import net.sourceforge.pmd.lang.document.TextRegion;
|
||||
|
||||
import scala.meta.Tree;
|
||||
import scala.meta.inputs.Position;
|
||||
@ -18,6 +23,9 @@ import scala.meta.inputs.Position;
|
||||
*/
|
||||
abstract class AbstractScalaNode<T extends Tree> extends AbstractNode<AbstractScalaNode<?>, ScalaNode<?>> implements ScalaNode<T> {
|
||||
|
||||
private static final Comparator<Position> POS_CMP =
|
||||
Comparator.comparingInt(Position::start).thenComparing(Position::end);
|
||||
|
||||
protected final T node;
|
||||
private final Position pos;
|
||||
|
||||
@ -56,23 +64,17 @@ abstract class AbstractScalaNode<T extends Tree> extends AbstractNode<AbstractSc
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginLine() {
|
||||
return pos.startLine() + 1;
|
||||
public FileLocation getReportLocation() {
|
||||
TextRegion region = TextRegion.fromBothOffsets(pos.start(), pos.end());
|
||||
return getAstInfo().getTextDocument().toLocation(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginColumn() {
|
||||
return pos.startColumn() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndLine() {
|
||||
return pos.endLine() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndColumn() {
|
||||
return pos.endColumn() + 1;
|
||||
public int compareLocation(Node node) {
|
||||
if (node instanceof AbstractScalaNode) {
|
||||
return POS_CMP.compare(((AbstractScalaNode<?>) node).pos, pos);
|
||||
}
|
||||
return ScalaNode.super.compareLocation(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,6 +6,9 @@ package net.sourceforge.pmd.lang.scala.ast
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.should
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry
|
||||
import net.sourceforge.pmd.lang.ast.Node
|
||||
import net.sourceforge.pmd.lang.ast.test.assertBounds
|
||||
import net.sourceforge.pmd.lang.ast.test.matchNode
|
||||
import net.sourceforge.pmd.lang.ast.test.assertPosition
|
||||
import net.sourceforge.pmd.lang.ast.test.shouldBe
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,40 +1,40 @@
|
||||
[Image] or [Truncated image[ Bcol Ecol
|
||||
L7
|
||||
[case] 1 6
|
||||
[class] 6 12
|
||||
[Foo] 12 16
|
||||
[(] 15 17
|
||||
[)] 16 18
|
||||
[{] 18 20
|
||||
[case] 1 5
|
||||
[class] 6 11
|
||||
[Foo] 12 15
|
||||
[(] 15 16
|
||||
[)] 16 17
|
||||
[{] 18 19
|
||||
L14
|
||||
[private] 3 11
|
||||
[def] 11 15
|
||||
[bar] 15 19
|
||||
[(] 18 20
|
||||
[i] 19 21
|
||||
[:] 20 22
|
||||
[Int] 22 26
|
||||
[)] 25 27
|
||||
[:] 27 29
|
||||
[Int] 29 33
|
||||
[=] 33 35
|
||||
[{] 35 37
|
||||
[private] 3 10
|
||||
[def] 11 14
|
||||
[bar] 15 18
|
||||
[(] 18 19
|
||||
[i] 19 20
|
||||
[:] 20 21
|
||||
[Int] 22 25
|
||||
[)] 25 26
|
||||
[:] 27 28
|
||||
[Int] 29 32
|
||||
[=] 33 34
|
||||
[{] 35 36
|
||||
L15
|
||||
[val] 5 9
|
||||
[CPD] 9 13
|
||||
[=] 13 15
|
||||
[40] 15 18
|
||||
[val] 5 8
|
||||
[CPD] 9 12
|
||||
[=] 13 14
|
||||
[40] 15 17
|
||||
L16
|
||||
[val] 5 9
|
||||
[OFF] 9 13
|
||||
[=] 13 15
|
||||
[60] 15 18
|
||||
[val] 5 8
|
||||
[OFF] 9 12
|
||||
[=] 13 14
|
||||
[60] 15 17
|
||||
L17
|
||||
[CPD] 5 9
|
||||
[-] 8 10
|
||||
[OFF] 9 13
|
||||
[CPD] 5 8
|
||||
[-] 8 9
|
||||
[OFF] 9 12
|
||||
L18
|
||||
[}] 3 5
|
||||
[}] 3 4
|
||||
L24
|
||||
[}] 1 3
|
||||
[}] 1 2
|
||||
EOF
|
||||
|
@ -1,30 +1,30 @@
|
||||
[Image] or [Truncated image[ Bcol Ecol
|
||||
L1
|
||||
[object] 1 8
|
||||
[Main] 8 13
|
||||
[{] 13 15
|
||||
[object] 1 7
|
||||
[Main] 8 12
|
||||
[{] 13 14
|
||||
L2
|
||||
[def] 2 6
|
||||
[main] 6 11
|
||||
[(] 10 12
|
||||
[args] 11 16
|
||||
[:] 15 17
|
||||
[Array] 17 23
|
||||
[\[] 22 24
|
||||
[String] 23 30
|
||||
[\]] 29 31
|
||||
[)] 30 32
|
||||
[:] 31 33
|
||||
[Unit] 33 38
|
||||
[=] 38 40
|
||||
[{] 40 42
|
||||
[def] 2 5
|
||||
[main] 6 10
|
||||
[(] 10 11
|
||||
[args] 11 15
|
||||
[:] 15 16
|
||||
[Array] 17 22
|
||||
[\[] 22 23
|
||||
[String] 23 29
|
||||
[\]] 29 30
|
||||
[)] 30 31
|
||||
[:] 31 32
|
||||
[Unit] 33 37
|
||||
[=] 38 39
|
||||
[{] 40 41
|
||||
L3
|
||||
[println] 3 11
|
||||
[(] 10 12
|
||||
["Hello, World!"] 11 27
|
||||
[)] 26 28
|
||||
[println] 3 10
|
||||
[(] 10 11
|
||||
["Hello, World!"] 11 26
|
||||
[)] 26 27
|
||||
L4
|
||||
[}] 2 4
|
||||
[}] 2 3
|
||||
L5
|
||||
[}] 1 3
|
||||
[}] 1 2
|
||||
EOF
|
||||
|
@ -21,6 +21,21 @@
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -21,6 +21,20 @@
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
Reference in New Issue
Block a user