CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-sourceforge-pmd--pmd-visualforce

PMD language module that provides static code analysis capabilities for Salesforce Visualforce pages and components

Pending
Overview
Eval results
Files

ast-parsing.mddocs/

AST Parsing and Node Types

Complete Abstract Syntax Tree generation with specialized node types for parsing and representing Visualforce markup structures. This capability provides the foundation for all static analysis of Visualforce files.

Capabilities

VfParser

Main parser that converts Visualforce markup into a structured AST for analysis.

/**
 * Parser for the Visualforce language
 * Extends JjtreeParserAdapter to create AST from Visualforce markup
 */
public final class VfParser extends JjtreeParserAdapter<ASTCompilationUnit> {
    /**
     * Create parser with Visualforce-specific configuration
     * @param vfProperties Configuration including Apex and Object directory paths
     */
    public VfParser(VfLanguageProperties vfProperties);
    
    /**
     * Parse Visualforce content into AST (protected method called by PMD framework)
     * @param cs Character stream of Visualforce content
     * @param task Parser task context
     * @return Root AST node with type information attached
     * @throws ParseException if content cannot be parsed
     */
    protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException;
}

Usage Example:

import net.sourceforge.pmd.lang.visualforce.ast.VfParser;
import net.sourceforge.pmd.lang.visualforce.VfLanguageProperties;

// Create parser with properties
VfLanguageProperties properties = new VfLanguageProperties();
VfParser parser = new VfParser(properties);

// Parser is typically used by PMD framework, not directly by users
// PMD calls parseImpl() internally during analysis

Base AST Interfaces

Core interfaces that define the structure of Visualforce AST nodes.

/**
 * Base interface for all Visualforce AST nodes
 * Extends JjtreeNode to integrate with PMD's AST framework
 */
public interface VfNode extends JjtreeNode<VfNode> {}

/**
 * Abstract base class for all concrete Visualforce AST nodes
 * Provides common functionality and visitor pattern integration
 */
abstract class AbstractVfNode extends AbstractJjtreeNode<AbstractVfNode, VfNode> implements VfNode {
    /**
     * Accept a Visualforce-specific visitor for AST traversal
     * @param visitor Visitor implementation to accept
     * @param data Context data passed through visitation
     * @return Result from visitor
     */
    protected abstract <P, R> R acceptVfVisitor(VfVisitor<? super P, ? extends R> visitor, P data);
    
    /**
     * Get XPath node name for this AST node type
     * @return String name used in XPath expressions
     */
    @Override
    public String getXPathNodeName();
}

/**
 * Abstract base class for AST nodes that represent data values
 * Implements VfTypedNode to provide type analysis capabilities
 */
abstract class AbstractVFDataNode extends AbstractVfNode implements VfTypedNode {
    /**
     * Get the resolved data type for this node's value
     * @return DataType representing the node's type, or null if no metadata found
     */
    @Override
    public DataType getDataType();
    
    /**
     * Set the data type for this node (used internally by type visitor)
     * @param dataType DataType to assign to this node
     */
    void setDataType(DataType dataType);
}

Root AST Node

The top-level node representing a complete Visualforce file.

/**
 * Root node of the AST representing a complete Visualforce file
 * Implements RootNode to serve as the AST entry point
 */
public final class ASTCompilationUnit extends AbstractVfNode implements RootNode {
    /**
     * Get AST metadata and parsing information
     * @return AstInfo containing task context and root reference
     */
    @Override
    public AstInfo<ASTCompilationUnit> getAstInfo();
    
    /**
     * Internal method to attach parser task information (used by parser)
     * @param task Parser task context
     * @return This compilation unit with task info attached
     */
    ASTCompilationUnit makeTaskInfo(ParserTask task);
    
    /**
     * Accept Visualforce visitor
     * @param visitor Visitor to accept
     * @param data Context data
     * @return Visitor result
     */
    @Override
    protected <P, R> R acceptVfVisitor(VfVisitor<? super P, ? extends R> visitor, P data);
}

Element Nodes

AST nodes representing XML/HTML elements and their components in Visualforce markup.

/**
 * Represents XML/HTML elements in Visualforce markup
 * Examples: <apex:page>, <c:customComponent>, <div>
 */
public final class ASTElement extends AbstractVfNode {
    /**
     * Check if element has namespace prefix (e.g., "apex:" in "apex:page")
     * @return true if element name contains namespace prefix
     */
    public boolean isHasNamespacePrefix();
    
    /**
     * Get the namespace prefix part of element name
     * @return String before first colon, or null if no namespace
     */
    public String getNamespacePrefix();
    
    /**
     * Get the local name part of element (after namespace prefix)
     * @return String after first colon, or full name if no namespace
     */
    public String getLocalName();
    
    /**
     * Get complete element name including namespace
     * @return Full element name as it appears in markup
     */
    public String getName();
    
    /**
     * Check if element is self-closing (e.g., <apex:input />)
     * @return true if element uses empty tag syntax
     */
    public boolean isEmpty();
    
    /**
     * Check if element is unclosed (missing end tag)
     * @return true if parser could not find proper closing tag
     */
    public boolean isUnclosed();
}

/**
 * Represents element attributes in Visualforce markup
 * Examples: rendered="{!condition}", value="{!account.name}"
 */
public final class ASTAttribute extends AbstractVfNode {
    /**
     * Get attribute name
     * @return Attribute name string
     */
    public String getName();
}

/**
 * Represents attribute values, including literal values and expressions
 */
public final class ASTAttributeValue extends AbstractVfNode {
    /**
     * Get the literal value of the attribute
     * @return String value or null for expression values
     */
    public String getValue();
}

Expression Nodes

AST nodes for Visualforce Expression Language (EL) constructs.

/**
 * Represents Expression Language expressions in Visualforce
 * Examples: {!account.name}, {!IF(condition, 'yes', 'no')}
 */
public final class ASTElExpression extends AbstractVfNode {
    /**
     * Accept Visualforce visitor
     * @param visitor Visitor to accept  
     * @param data Context data
     * @return Visitor result
     */
    @Override
    protected <P, R> R acceptVfVisitor(VfVisitor<? super P, ? extends R> visitor, P data);
}

/**
 * Represents general expressions within EL contexts
 * Provides advanced parsing of complex expressions with data node analysis
 */
public final class ASTExpression extends AbstractVfNode {
    /**
     * Maps strings from Visualforce page to terminal AST nodes (ASTIdentifier or ASTLiteral)
     * that the strings represent. The terminal node represents the type of data displayed.
     * 
     * Examples:
     * - {!MyValue} returns Map<ASTIdentifier, "MyValue">
     * - {!MyObject__c.Text__c} returns Map<ASTIdentifier, "MyObject__c.Text__c">
     * 
     * @return Map of terminal nodes to their string representations
     * @throws DataNodeStateException if expression contains unsupported syntax
     */
    public Map<VfTypedNode, String> getDataNodes() throws DataNodeStateException;
    
    /**
     * Exception thrown when identifiers in expression can't be successfully parsed
     * Occurs with unsupported syntax like array notation: MyObject__c['Text__c']
     */
    public static final class DataNodeStateException extends Exception {}
}

/**
 * Represents dot notation expressions for property access
 * Examples: account.name, user.profile.name
 */
public final class ASTDotExpression extends AbstractVfNode {}

/**
 * Represents negation expressions
 * Examples: !condition, !account.isActive
 */
public final class ASTNegationExpression extends AbstractVfNode {}

/**
 * Represents identifiers in expressions
 * Examples: account, condition, customObject
 * Implements VfTypedNode for type analysis support
 */
public final class ASTIdentifier extends AbstractVFDataNode {}

/**
 * Represents literal values in expressions
 * Examples: 'string literal', 123, true
 * Implements VfTypedNode for type analysis support
 */
public final class ASTLiteral extends AbstractVFDataNode {}

/**
 * Represents function arguments in expressions
 * Examples: arguments in IF(condition, 'true', 'false')
 */
public final class ASTArguments extends AbstractVfNode {}

Content and Text Nodes

AST nodes for textual content within Visualforce markup.

/**
 * Represents text content within elements
 */
public final class ASTText extends AbstractVfNode {}

/**
 * Represents CDATA sections in markup
 */
public final class ASTCData extends AbstractVfNode {}

/**
 * Represents general content within elements (container for text and child elements)
 */
public final class ASTContent extends AbstractVfNode {}

/**
 * Represents HTML script blocks within Visualforce pages
 */
public final class ASTHtmlScript extends AbstractVfNode {}

Document Structure Nodes

AST nodes for document-level constructs.

/**
 * Represents XML declarations at the start of documents
 */
public final class ASTDeclaration extends AbstractVfNode {}

/**
 * Represents DOCTYPE declarations
 */
public final class ASTDoctypeDeclaration extends AbstractVfNode {}

/**
 * Represents external ID in DOCTYPE declarations
 */
public final class ASTDoctypeExternalId extends AbstractVfNode {}

Usage Example:

import net.sourceforge.pmd.lang.visualforce.ast.*;

// Example of traversing AST nodes (typically done in rules or visitors)
public class ExampleVisitor extends VfVisitorBase<Void, Void> {
    @Override
    public Void visit(ASTElement element, Void data) {
        // Check for specific Visualforce elements
        if ("apex:page".equals(element.getName())) {
            System.out.println("Found apex:page element");
            
            if (element.isHasNamespacePrefix()) {
                System.out.println("Namespace: " + element.getNamespacePrefix());
                System.out.println("Local name: " + element.getLocalName());
            }
        }
        
        // Visit child nodes
        return super.visit(element, data);
    }
    
    @Override
    public Void visit(ASTElExpression expression, Void data) {
        System.out.println("Found EL expression");
        // Process expression content
        return super.visit(expression, data);
    }
}

Visitor Pattern Integration

All AST nodes support the visitor pattern through the VfVisitor interface, enabling systematic traversal and analysis of the Visualforce AST structure. The visitor pattern is the primary mechanism for implementing PMD rules and other analysis tools.

Install with Tessl CLI

npx tessl i tessl/maven-net-sourceforge-pmd--pmd-visualforce

docs

ast-parsing.md

index.md

language-module.md

rule-development.md

type-analysis.md

tile.json