/
KotlinCpdLexer.java
73 lines (61 loc) · 2.39 KB
/
KotlinCpdLexer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.kotlin.cpd;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer;
import net.sourceforge.pmd.cpd.impl.AntlrTokenFilter;
import net.sourceforge.pmd.lang.TokenManager;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken;
import net.sourceforge.pmd.lang.kotlin.ast.KotlinLexer;
/**
* The Kotlin Tokenizer
*
* <p>Note: This class has been called KotlinTokenizer in PMD 6</p>.
*/
public class KotlinCpdLexer extends AntlrCpdLexer {
@Override
protected Lexer getLexerForSource(CharStream charStream) {
return new KotlinLexer(charStream);
}
@Override
protected TokenManager<AntlrToken> filterTokenStream(TokenManager<AntlrToken> tokenManager) {
return new KotlinTokenFilter(tokenManager);
}
/**
* The {@link KotlinTokenFilter} extends the {@link AntlrTokenFilter} to discard
* Kotlin-specific tokens.
* <p>
* By default, it discards package and import statements, and
* enables annotation-based CPD suppression.
* </p>
*/
private static class KotlinTokenFilter extends AntlrTokenFilter {
private boolean discardingPackageAndImport = false;
private boolean discardingNL = false;
/* default */ KotlinTokenFilter(final TokenManager<AntlrToken> tokenManager) {
super(tokenManager);
}
@Override
protected void analyzeToken(final AntlrToken currentToken) {
skipPackageAndImport(currentToken);
skipNewLines(currentToken);
}
private void skipPackageAndImport(final AntlrToken currentToken) {
final int type = currentToken.getKind();
if (type == KotlinLexer.PACKAGE || type == KotlinLexer.IMPORT) {
discardingPackageAndImport = true;
} else if (discardingPackageAndImport && (type == KotlinLexer.SEMICOLON || type == KotlinLexer.NL)) {
discardingPackageAndImport = false;
}
}
private void skipNewLines(final AntlrToken currentToken) {
discardingNL = currentToken.getKind() == KotlinLexer.NL;
}
@Override
protected boolean isLanguageSpecificDiscarding() {
return discardingPackageAndImport || discardingNL;
}
}
}