CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-sourceforge-pmd--pmd-vm

PMD language module for static analysis of Apache Velocity Template Language (VTL) files

Pending
Overview
Eval results
Files

ast-nodes.mddocs/

AST Node Framework

Complete Abstract Syntax Tree representation of Velocity templates with 40+ specialized node types for expressions, directives, references, and control structures. The AST framework provides a comprehensive visitor pattern implementation for traversing and analyzing parsed Velocity templates.

Capabilities

Base Node Interface

Core interface implemented by all Velocity AST nodes, providing visitor pattern support and tree navigation.

/**
 * Base interface for all Velocity AST nodes.
 * Extends PMD's Node interface with Velocity-specific visitor support.
 */
public interface VmNode extends Node {
    
    /**
     * Accept a visitor and invoke the appropriate visit method.
     * Central method for visitor pattern implementation.
     * @param visitor The visitor to accept
     * @param data Context data passed through visitor traversal
     * @return Result from visitor method execution
     */
    Object jjtAccept(VmParserVisitor visitor, Object data);
    
    /**
     * Accept a visitor for all child nodes.
     * Convenience method for traversing child nodes.
     * @param visitor The visitor to apply to children
     * @param data Context data passed through visitor traversal
     * @return Result from child visitor executions
     * @deprecated This method is not useful, the logic for combining
     *     children values should be present on the visitor, not the node
     */
    @Deprecated
    Object childrenAccept(VmParserVisitor visitor, Object data);
    
    /**
     * Get a specific child node by index.
     * @param index Zero-based index of child node
     * @return Child node at specified index
     * @throws IndexOutOfBoundsException if index is invalid
     */
    VmNode getChild(int index);
    
    /**
     * Get the parent node of this node.
     * @return Parent node, or null if this is the root node
     */
    VmNode getParent();
    
    /**
     * Get an iterable over all child nodes.
     * @return Iterable for traversing child nodes
     */
    Iterable<? extends VmNode> children();
}

Base Node Implementation

Abstract base class providing common functionality for all Velocity AST nodes.

/**
 * Abstract base implementation for all Velocity AST nodes.
 * Provides common functionality including position tracking, token access,
 * and tree structure management.
 * @deprecated Marked as internal API - use VmNode interface instead
 */
@Deprecated
@InternalApi
public abstract class AbstractVmNode extends AbstractJjtreeNode implements VmNode {
    
    /**
     * Called when node is opened during parsing.
     * Part of JavaCC tree construction lifecycle.
     */
    public void jjtOpen();
    
    /**
     * Called when node is closed during parsing.
     * Part of JavaCC tree construction lifecycle.
     */
    public void jjtClose();
    
    /**
     * Get the first token associated with this node.
     * @return First token of this node's source text
     */
    public Token getFirstToken();
    
    /**
     * Get the last token associated with this node.
     * @return Last token of this node's source text
     */
    public Token getLastToken();
    
    /**
     * Get the literal text representation of this node.
     * @return String representation of the node's source text
     */
    public String literal();
    
    /**
     * Get the node type identifier.
     * @return Integer constant identifying the node type
     */
    public int getType();
    
    /**
     * Set additional information for this node.
     * @param info Integer value for node-specific metadata
     */
    public void setInfo(int info);
    
    /**
     * Get additional information for this node.
     * @return Integer value containing node-specific metadata
     */
    public int getInfo();
    
    /**
     * Mark this node as invalid due to parse errors.
     */
    public void setInvalid();
    
    /**
     * Check if this node is marked as invalid.
     * @return true if node has parse errors, false otherwise
     */
    public boolean isInvalid();
    
    /**
     * Get the line number where this node begins.
     * @return Line number (1-based) in source template
     */
    public int getLine();
    
    /**
     * Get the column number where this node begins.
     * @return Column number (1-based) in source template
     */
    public int getColumn();
    
    /**
     * Get the name of the template containing this node.
     * @return Template filename or identifier
     */
    public String getTemplateName();
    
    /**
     * Dump the AST structure starting from this node.
     * @param prefix String prefix for indentation
     * @param alreadyDumped Whether parent nodes have been dumped
     * @param writer Output writer for dump content
     */
    public void dump(String prefix, boolean alreadyDumped, Writer writer);
}

Visitor Pattern Implementation

Default visitor adapter providing base traversal logic for all AST node types.

/**
 * Default implementation of VmParserVisitor that provides base traversal
 * logic for all Velocity AST node types. Extend this class to create
 * custom visitors that only override specific visit methods.
 */
public class VmParserVisitorAdapter implements VmParserVisitor {
    
    /**
     * Default visit method for base VmNode interface.
     * @param node The node being visited
     * @param data Context data passed through traversal
     * @return null by default, subclasses may return meaningful values
     */
    public Object visit(VmNode node, Object data);
    
    // Visit methods for all specific node types
    public Object visit(ASTprocess node, Object data);
    public Object visit(ASTReference node, Object data);
    public Object visit(ASTDirective node, Object data);
    public Object visit(ASTMethod node, Object data);
    public Object visit(ASTIndex node, Object data);
    
    // Mathematical operation nodes
    public Object visit(ASTAddNode node, Object data);
    public Object visit(ASTSubtractNode node, Object data);
    public Object visit(ASTMulNode node, Object data);
    public Object visit(ASTDivNode node, Object data);
    public Object visit(ASTModNode node, Object data);
    public Object visit(ASTMathNode node, Object data);
    
    // Logical operation nodes
    public Object visit(ASTOrNode node, Object data);
    public Object visit(ASTAndNode node, Object data);
    public Object visit(ASTNotNode node, Object data);
    
    // Comparison operation nodes
    public Object visit(ASTEQNode node, Object data);
    public Object visit(ASTNENode node, Object data);
    public Object visit(ASTLTNode node, Object data);
    public Object visit(ASTGTNode node, Object data);
    public Object visit(ASTLENode node, Object data);
    public Object visit(ASTGENode node, Object data);
    
    // Control flow nodes
    public Object visit(ASTIfStatement node, Object data);
    public Object visit(ASTElseStatement node, Object data);
    public Object visit(ASTElseIfStatement node, Object data);
    public Object visit(ASTForeachStatement node, Object data);
    public Object visit(ASTSetDirective node, Object data);
    public Object visit(ASTBlock node, Object data);
    
    // Expression and assignment nodes
    public Object visit(ASTExpression node, Object data);
    public Object visit(ASTAssignment node, Object data);
    
    // Data structure nodes
    public Object visit(ASTMap node, Object data);
    public Object visit(ASTObjectArray node, Object data);
    public Object visit(ASTIntegerRange node, Object data);
    
    // Content and text nodes
    public Object visit(ASTText node, Object data);
    public Object visit(ASTTextblock node, Object data);
    public Object visit(ASTComment node, Object data);
    
    // Literal value nodes
    public Object visit(ASTFloatingPointLiteral node, Object data);
    public Object visit(ASTIntegerLiteral node, Object data);
    public Object visit(ASTStringLiteral node, Object data);
    public Object visit(ASTTrue node, Object data);
    public Object visit(ASTFalse node, Object data);
    
    // Identifier and word nodes
    public Object visit(ASTIdentifier node, Object data);
    public Object visit(ASTWord node, Object data);
    
    // Escape and directive nodes
    public Object visit(ASTEscape node, Object data);
    public Object visit(ASTEscapedDirective node, Object data);
}

Key AST Node Types

Reference Nodes

Represent Velocity variable references ($variable, $object.property).

/**
 * AST node representing Velocity variable references.
 * Handles both simple references ($var) and complex references ($obj.prop).
 */
public class ASTReference extends AbstractVmNode {
    
    /**
     * Get the root identifier string of the reference.
     * For $user.name, returns "user".
     * @return Root variable name
     */
    public String getRootString();
    
    /**
     * Set the literal text representation of this reference.
     * @param literal String representation to set
     */
    public void setLiteral(String literal);
    
    /**
     * Get the literal text representation of this reference.
     * @return Complete reference string including $ prefix
     */
    public String literal();
}

Directive Nodes

Represent Velocity directives (#if, #foreach, #set, etc.).

/**
 * AST node representing Velocity directives.
 * Handles all directive types including control flow and utility directives.
 */
public class ASTDirective extends AbstractVmNode {
    // Inherits all AbstractVmNode functionality
    // Specific directive behavior determined by child nodes and context
}

Method Call Nodes

Represent method invocations within Velocity templates.

/**
 * AST node representing method calls in Velocity templates.
 * Handles both simple method calls and chained method invocations.
 */
public class ASTMethod extends AbstractVmNode {
    // Inherits all AbstractVmNode functionality
    // Method name and parameters accessible via child nodes
}

Mathematical Operation Nodes

Specialized nodes for different mathematical operations.

/**
 * AST node representing addition operations.
 */
public class ASTAddNode extends AbstractVmNode {
    // Inherits position tracking and tree navigation
    // Left and right operands accessible via child nodes
}

/**
 * AST node representing subtraction operations.
 */
public class ASTSubtractNode extends AbstractVmNode;

/**
 * AST node representing multiplication operations.
 */
public class ASTMulNode extends AbstractVmNode;

/**
 * AST node representing division operations.
 */
public class ASTDivNode extends AbstractVmNode;

/**
 * AST node representing modulo operations.
 */
public class ASTModNode extends AbstractVmNode;

/**
 * Base AST node for mathematical operations.
 */
public class ASTMathNode extends AbstractVmNode;

Escape Sequence Nodes

Handle Velocity escape sequences and escaped directives.

/**
 * AST node representing escape sequences in Velocity templates.
 * Handles backslash escaping of special characters.
 */
public class ASTEscape extends AbstractVmNode {
    // Inherits all AbstractVmNode functionality
    // Escaped character accessible via token information
}

Utility Classes

Node Utilities

Helper methods for common AST node operations.

/**
 * Utility class providing helper methods for AST node operations.
 * Contains static methods for common node analysis tasks.
 */
public class NodeUtils {
    // Static utility methods for node analysis and manipulation
    // Implementation details vary based on specific utility needs
}

Usage Examples

Basic AST Traversal

import net.sourceforge.pmd.lang.vm.ast.VmParserVisitorAdapter;
import net.sourceforge.pmd.lang.vm.ast.ASTReference;
import net.sourceforge.pmd.lang.vm.ast.ASTDirective;

public class TemplateAnalyzer extends VmParserVisitorAdapter {
    
    @Override
    public Object visit(ASTReference node, Object data) {
        String refName = node.getRootString();
        System.out.println("Found reference: " + refName + 
                         " at line " + node.getLine());
        return super.visit(node, data);
    }
    
    @Override
    public Object visit(ASTDirective node, Object data) {
        System.out.println("Found directive at line " + node.getLine());
        // Traverse child nodes to analyze directive structure
        return node.childrenAccept(this, data);
    }
}

Node Information Access

import net.sourceforge.pmd.lang.vm.ast.VmNode;

public void analyzeNode(VmNode node) {
    // Position information
    int line = node.getLine();
    int column = node.getColumn();
    String template = node.getTemplateName();
    
    // Content information
    String literal = node.literal();
    Token firstToken = node.getFirstToken();
    Token lastToken = node.getLastToken();
    
    // Tree navigation
    VmNode parent = node.getParent();
    int childCount = node.getNumChildren();
    
    // Child iteration
    for (VmNode child : node.children()) {
        analyzeNode(child);
    }
}

Custom Visitor Implementation

import net.sourceforge.pmd.lang.vm.ast.VmParserVisitor;

public class CustomVelocityVisitor implements VmParserVisitor {
    
    @Override
    public Object visit(VmNode node, Object data) {
        // Default handling for any node type
        return node.childrenAccept(this, data);
    }
    
    @Override
    public Object visit(ASTReference node, Object data) {
        // Custom handling for variable references
        String refName = node.getRootString();
        if (isProblematicReference(refName)) {
            reportIssue(node, "Problematic reference: " + refName);
        }
        return null;
    }
    
    // Implement only the visit methods you need
    // Unimplemented methods will use default behavior
    
    private boolean isProblematicReference(String refName) {
        return refName != null && refName.length() > 50;
    }
    
    private void reportIssue(VmNode node, String message) {
        System.err.println(message + " at " + 
                         node.getTemplateName() + ":" + node.getLine());
    }
}

Install with Tessl CLI

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

docs

ast-nodes.md

builtin-rules.md

index.md

language-integration.md

parsing.md

rule-development.md

tile.json