or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ast.mdcpd.mdindex.mdlanguage-module.mdmetrics.mdmultifile.mdrules.md
tile.json

tessl/maven-net-sourceforge-pmd--pmd-apex

PMD Apex language module providing static code analysis support for Salesforce Apex programming language.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/net.sourceforge.pmd/pmd-apex@7.13.x

To install, run

npx @tessl/cli install tessl/maven-net-sourceforge-pmd--pmd-apex@7.13.0

index.mddocs/

PMD Apex

PMD Apex provides comprehensive static code analysis capabilities for Salesforce Apex programming language as part of the PMD static code analyzer ecosystem. It integrates with apex-parser and Summit AST libraries to parse Apex source code and generate abstract syntax trees (AST) for rule-based analysis, enabling automated code quality checks, security vulnerability detection, and adherence to coding standards within Apex development workflows.

Package Information

  • Package Name: pmd-apex
  • Package Type: maven
  • Group ID: net.sourceforge.pmd
  • Artifact ID: pmd-apex
  • Language: Java/Kotlin
  • Installation: Add to Maven: <dependency><groupId>net.sourceforge.pmd</groupId><artifactId>pmd-apex</artifactId><version>7.13.0</version></dependency>

Core Imports

import net.sourceforge.pmd.lang.apex.ApexLanguageModule;
import net.sourceforge.pmd.lang.apex.ast.*;
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
import net.sourceforge.pmd.lang.apex.metrics.ApexMetrics;
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileAnalysis;

Basic Usage

// Register language module
ApexLanguageModule apexModule = ApexLanguageModule.getInstance();

// Parse Apex code into AST
ApexParser parser = new ApexParser();
ASTApexFile apexFile = parser.parse(parserTask);

// Create custom rule
public class MyApexRule extends AbstractApexRule {
    @Override
    public Object visit(ASTUserClass node, Object data) {
        // Rule logic for class analysis
        String className = node.getQualifiedName().getClassName();
        return super.visit(node, data);
    }
    
    @Override
    public Object visit(ASTMethod node, Object data) {
        // Rule logic for method analysis
        int complexity = MetricsUtil.computeMetric(ApexMetrics.CYCLO, node);
        return super.visit(node, data);
    }
}

// Multifile analysis
ApexMultifileAnalysis analysis = processor.getMultiFileState();
List<Issue> issues = analysis.getFileIssues("MyClass.cls");

Architecture

PMD Apex is built around several key components:

  • Language Module: Main entry point (ApexLanguageModule) for PMD integration and language registration
  • AST Framework: Complete Abstract Syntax Tree representation with 95+ node types covering all Apex language constructs
  • Visitor Pattern: ApexVisitor interface with traversal methods for each AST node type
  • Rule Engine: Base classes and built-in rules across 6 categories (40+ rules total)
  • Metrics System: Built-in complexity and quality metrics (cyclomatic, cognitive complexity, weighted method count)
  • Multifile Analysis: Cross-file dependency analysis using ApexLink integration
  • CPD Integration: Copy-paste detection capabilities for code duplication analysis

Capabilities

Language Module and Registration

Core language module registration and configuration for PMD integration. Provides entry points for parser creation, language properties, and violation suppression handling.

public class ApexLanguageModule {
    public static ApexLanguageModule getInstance();
    public ApexLanguageProcessor createProcessor(LanguagePropertyBundle bundle);
    public ApexLanguageProperties newPropertyBundle();
    public CpdLexer createCpdLexer(LanguagePropertyBundle bundle);
}

public class ApexLanguageProcessor {
    public LanguageVersionHandler services();
    public ApexMultifileAnalysis getMultiFileState();
}

Language Module

AST Parsing and Navigation

Complete Abstract Syntax Tree representation for Apex code with 95+ node types covering all language constructs. Includes parser, root nodes, and visitor pattern for tree traversal.

public class ApexParser {
    public ASTApexFile parse(ParserTask task);
}

public interface ApexNode<T> {
    boolean hasRealLoc();
    String getDefiningType();
    ASTApexFile getRoot();
}

public interface ApexVisitor<P, R> {
    R visit(ASTUserClass node, P data);
    R visit(ASTMethod node, P data);
    R visit(ASTVariableExpression node, P data);
    // 80+ additional visit methods for all AST node types
}

AST Parsing and Navigation

Built-in Metrics

Complexity and quality metrics calculation for Apex code analysis. Provides cyclomatic complexity, cognitive complexity, and weighted method count metrics.

public class ApexMetrics {
    public static final Metric<ASTMethod, Integer> CYCLO;
    public static final Metric<ASTMethod, Integer> COGNITIVE_COMPLEXITY;
    public static final Metric<ASTUserClass, Integer> WEIGHED_METHOD_COUNT;
}

Metrics

Multifile Analysis

Cross-file analysis capabilities using ApexLink for analyzing dependencies and relationships across multiple Apex files in a Salesforce project.

public class ApexMultifileAnalysis {
    public boolean isFailed();
    public List<Issue> getFileIssues(String fileName);
}

Multifile Analysis

Rule Development Framework

Base classes and framework for creating custom PMD rules. Includes abstract base rule class with visitor pattern integration and access to AST traversal.

public abstract class AbstractApexRule implements ApexVisitor<Object, Object> {
    public void apply(Node target, RuleContext ctx);
    // Inherits 80+ visit methods from ApexVisitor
}

Rule Development

Copy-Paste Detection

Lexical analysis for detecting code duplication within Apex codebases. Integrates with PMD's Copy-Paste Detection (CPD) framework.

public class ApexCpdLexer {
    public void tokenize(TextDocument textDocument, TokenFactory tokenFactory);
}

Copy-Paste Detection

Types

Core Interfaces

public interface ApexNode<T> {
    boolean hasRealLoc();
    String getDefiningType();
    ASTApexFile getRoot();
}

public interface ApexVisitor<P, R> {
    R visit(ASTApexFile node, P data);
    R visit(ASTUserClass node, P data);
    R visit(ASTUserInterface node, P data);
    R visit(ASTUserEnum node, P data);
    R visit(ASTUserTrigger node, P data);
    R visit(ASTMethod node, P data);
    R visit(ASTField node, P data);
    R visit(ASTProperty node, P data);
    R visit(ASTParameter node, P data);
    R visit(ASTBlockStatement node, P data);
    R visit(ASTIfBlockStatement node, P data);
    R visit(ASTWhileLoopStatement node, P data);
    R visit(ASTForLoopStatement node, P data);
    R visit(ASTVariableExpression node, P data);
    R visit(ASTMethodCallExpression node, P data);
    R visit(ASTBinaryExpression node, P data);
    R visit(ASTAssignmentExpression node, P data);
    R visit(ASTSoqlExpression node, P data);
    R visit(ASTSoslExpression node, P data);
    // 70+ additional visit methods for remaining AST node types
}

public interface ApexQualifiableNode {
    ApexQualifiedName getQualifiedName();
}

public interface AccessNode {
    // Access modifier related methods
}

Operator Enums

public enum BinaryOperator {
    ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION,
    LEFT_SHIFT, RIGHT_SHIFT_SIGNED, RIGHT_SHIFT_UNSIGNED,
    BITWISE_AND, BITWISE_OR, BITWISE_XOR, NULL_COALESCING
}

public enum BooleanOperator {
    EQUAL, NOT_EQUAL, ALT_NOT_EQUAL, EXACTLY_EQUAL, EXACTLY_NOT_EQUAL,
    LESS_THAN, GREATER_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL,
    LOGICAL_AND, LOGICAL_OR
}

public enum AssignmentOperator {
    EQUALS, ADDITION_EQUALS, SUBTRACTION_EQUALS, MULTIPLICATION_EQUALS,
    DIVISION_EQUALS, LEFT_SHIFT_EQUALS, RIGHT_SHIFT_SIGNED_EQUALS,
    RIGHT_SHIFT_UNSIGNED_EQUALS, BITWISE_AND_EQUALS, BITWISE_OR_EQUALS,
    BITWISE_XOR_EQUALS
}

public enum PrefixOperator {
    POSITIVE, NEGATIVE, LOGICAL_NOT, BITWISE_NOT, INCREMENT, DECREMENT
}

public enum PostfixOperator {
    INCREMENT, DECREMENT
}

public enum ReferenceType {
    LOAD, STORE, METHOD, CLASS, NONE
}

public enum TriggerUsage {
    AFTER_DELETE, AFTER_INSERT, AFTER_UNDELETE, AFTER_UPDATE,
    BEFORE_DELETE, BEFORE_INSERT, BEFORE_UNDELETE, BEFORE_UPDATE
}

Utility Classes

public class ApexQualifiedName {
    public boolean isClass();
    public boolean isOperation();
    public String getClassName();
    public static ApexQualifiedName ofString(String qualifiedName);
}