PMD Apex language module providing static code analysis support for Salesforce Apex programming language.
—
Lexical analysis for detecting code duplication within Apex codebases. Integrates with PMD's Copy-Paste Detection (CPD) framework to identify similar code blocks.
Tokenizes Apex code for duplicate detection analysis.
/**
* Lexer for copy-paste detection in Apex code
* Tokenizes Apex source code for duplicate block detection
*/
public class ApexCpdLexer {
/**
* Tokenize Apex code for duplicate detection
* @param textDocument - Source code document to tokenize
* @param tokenFactory - Factory for creating tokens
*/
public void tokenize(TextDocument textDocument, TokenFactory tokenFactory);
}Factory interface for creating tokens during lexical analysis.
/**
* Factory for creating tokens during CPD analysis
* Part of PMD core framework
*/
public interface TokenFactory {
/**
* Create a token for the given text and location
* @param image - Token text content
* @param beginLine - Starting line number
* @param beginColumn - Starting column number
* @param endLine - Ending line number
* @param endColumn - Ending column number
*/
void recordToken(String image, int beginLine, int beginColumn, int endLine, int endColumn);
}Represents source code document for analysis.
/**
* Represents a source code document for analysis
* Part of PMD core framework
*/
public interface TextDocument {
/** Get the full text content */
String getText();
/** Get the file name or identifier */
String getDisplayName();
/** Get character at specific position */
char charAt(int index);
/** Get length of document */
int getLength();
}Usage Examples:
import net.sourceforge.pmd.lang.apex.cpd.ApexCpdLexer;
import net.sourceforge.pmd.cpd.*;
// Create CPD lexer for Apex
ApexCpdLexer lexer = new ApexCpdLexer();
// Create token factory for collecting tokens
List<Token> tokens = new ArrayList<>();
TokenFactory tokenFactory = new TokenFactory() {
@Override
public void recordToken(String image, int beginLine, int beginColumn, int endLine, int endColumn) {
Token token = new Token(image, beginLine, beginColumn, endLine, endColumn);
tokens.add(token);
}
};
// Create text document from Apex source
String apexCode = """
public class MyClass {
public void method1() {
System.debug('Hello World');
Integer x = 5;
if (x > 0) {
System.debug('Positive');
}
}
public void method2() {
System.debug('Hello World');
Integer y = 10;
if (y > 0) {
System.debug('Positive');
}
}
}
""";
TextDocument document = new TextDocument() {
@Override
public String getText() { return apexCode; }
@Override
public String getDisplayName() { return "MyClass.cls"; }
@Override
public char charAt(int index) { return apexCode.charAt(index); }
@Override
public int getLength() { return apexCode.length(); }
};
// Tokenize the document
lexer.tokenize(document, tokenFactory);
// Tokens are now available for duplicate detection
System.out.println("Generated " + tokens.size() + " tokens for CPD analysis");
// Use with PMD CPD framework
CPDConfiguration config = new CPDConfiguration();
config.setMinimumTileSize(50); // Minimum duplicate block size
config.setLanguage(ApexLanguageModule.getInstance());
CPD cpd = new CPD(config);
cpd.add(document);
// Find duplicates
List<Mark> duplicates = cpd.getMatches();
for (Mark duplicate : duplicates) {
System.out.println("Found duplicate code at line " + duplicate.getBeginLine() +
" in " + duplicate.getTokenSrcID());
}
// Integration with language module
ApexLanguageModule apexModule = ApexLanguageModule.getInstance();
LanguagePropertyBundle properties = apexModule.newPropertyBundle();
Lexer cpdLexer = apexModule.createCpdLexer(properties);
// The returned lexer is the same ApexCpdLexer instance
assert cpdLexer instanceof ApexCpdLexer;Install with Tessl CLI
npx tessl i tessl/maven-net-sourceforge-pmd--pmd-apex