PMD Apex language module providing static code analysis support for Salesforce Apex programming language.
—
Cross-file analysis capabilities using ApexLink for analyzing dependencies and relationships across multiple Apex files in a Salesforce project.
Handles cross-file analysis using ApexLink for comprehensive project-wide analysis.
/**
* Handles cross-file analysis using ApexLink
* Provides analysis of dependencies and relationships across multiple Apex files
*/
public class ApexMultifileAnalysis {
/**
* Check if multifile analysis failed
* @return true if analysis failed, false if successful
*/
public boolean isFailed();
/**
* Get issues for a specific file from multifile analysis
* @param fileName - Name of the Apex file to get issues for
* @return List of issues found in the specified file
*/
public List<Issue> getFileIssues(String fileName);
}Bridge to internal API components for multifile analysis.
/**
* Bridge to internal API components
* Provides access to internal multifile analysis functionality
*/
public class InternalApiBridge {
// Internal API access methods
}Issues found during multifile analysis.
/**
* Represents an issue found during multifile analysis
*/
public interface Issue {
/** Get issue message */
String getMessage();
/** Get issue severity level */
Severity getSeverity();
/** Get file location where issue occurs */
String getFileName();
/** Get line number where issue occurs */
int getLineNumber();
/** Get issue category */
String getCategory();
}
/**
* Issue severity levels
*/
public enum Severity {
ERROR, WARNING, INFO
}Usage Examples:
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileAnalysis;
import net.sourceforge.pmd.lang.apex.ApexLanguageProperties;
// Configure multifile analysis with Salesforce metadata directory
LanguagePropertyBundle properties = apexModule.newPropertyBundle();
properties.setProperty(ApexLanguageProperties.MULTIFILE_DIRECTORY, "/path/to/salesforce/project");
// Create processor with multifile analysis enabled
ApexLanguageProcessor processor = apexModule.createProcessor(properties);
ApexMultifileAnalysis multifileAnalysis = processor.getMultiFileState();
// Check if analysis was successful
if (multifileAnalysis.isFailed()) {
System.out.println("Multifile analysis failed - some cross-file issues may not be detected");
} else {
System.out.println("Multifile analysis successful");
// Get issues for specific files
List<Issue> classIssues = multifileAnalysis.getFileIssues("MyController.cls");
List<Issue> triggerIssues = multifileAnalysis.getFileIssues("AccountTrigger.trigger");
// Process issues
processIssues("MyController.cls", classIssues);
processIssues("AccountTrigger.trigger", triggerIssues);
}
private void processIssues(String fileName, List<Issue> issues) {
if (issues.isEmpty()) {
System.out.println("No multifile issues found in " + fileName);
return;
}
System.out.println("Multifile issues in " + fileName + ":");
for (Issue issue : issues) {
System.out.printf(" [%s] Line %d: %s (Category: %s)%n",
issue.getSeverity(),
issue.getLineNumber(),
issue.getMessage(),
issue.getCategory());
}
}
// Use in PMD rule that requires multifile context
public class CrossFileRule extends AbstractApexRule {
@Override
public Object visit(ASTUserClass node, Object data) {
RuleContext ctx = (RuleContext) data;
ApexMultifileAnalysis multifile = ctx.getLanguageProcessor().getMultiFileState();
if (!multifile.isFailed()) {
String fileName = ctx.getFileDisplayName();
List<Issue> issues = multifile.getFileIssues(fileName);
// Check for specific cross-file issues
for (Issue issue : issues) {
if (issue.getCategory().equals("DEPENDENCY_ISSUE")) {
ctx.addViolation(node, "Cross-file dependency issue: " + issue.getMessage());
}
}
}
return super.visit(node, data);
}
}Install with Tessl CLI
npx tessl i tessl/maven-net-sourceforge-pmd--pmd-apex