CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-sourceforge-pmd--pmd-jsp

PMD JSP language module providing static code analysis capabilities for JavaServer Pages files with lexical analysis, AST parsing, and rule-based code quality checks.

Pending
Overview
Eval results
Files

jsp-parser-ast.mddocs/

JSP Parser and AST

The JSP parser converts JSP source code into Abstract Syntax Trees (AST) using a JavaCC-generated parser. The AST provides a structured representation of JSP documents for analysis.

Parser

JspParser

Main parser class that converts JSP source into AST.

public final class JspParser extends JjtreeParserAdapter<ASTCompilationUnit> {
    public JspParser();
    protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException;
    protected TokenDocumentBehavior tokenBehavior();
}

Usage:

import net.sourceforge.pmd.lang.jsp.ast.JspParser;
import net.sourceforge.pmd.lang.jsp.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream;
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;

// Create parser
JspParser parser = new JspParser();

// Parse JSP content (requires PMD framework setup)
// CharStream stream = CharStream.create(document);
// ParserTask task = // ... PMD parser task
// ASTCompilationUnit ast = parser.parseImpl(stream, task);

Methods:

  • parseImpl(CharStream, ParserTask): Parses JSP source and returns the root AST node
  • tokenBehavior(): Returns token behavior configuration for the parser

Exceptions:

  • ParseException: Thrown when JSP source cannot be parsed due to syntax errors

Root AST Node

ASTCompilationUnit

Root node representing a complete JSP document.

public final class ASTCompilationUnit extends AbstractJspNode implements RootNode {
    ASTCompilationUnit(int id);
    public AstInfo<ASTCompilationUnit> getAstInfo();
    ASTCompilationUnit makeTaskInfo(ParserTask task);
    protected <P, R> R acceptVisitor(JspVisitor<? super P, ? extends R> visitor, P data);
}

Usage:

import net.sourceforge.pmd.lang.jsp.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.ast.AstInfo;

// Get AST information
AstInfo<ASTCompilationUnit> astInfo = compilationUnit.getAstInfo();

// Access document metadata
String fileName = astInfo.getTextDocument().getDisplayName();

Methods:

  • getAstInfo(): Returns metadata about the parsed AST and source document
  • acceptVisitor(JspVisitor, P): Accepts a visitor for AST traversal

Base AST Infrastructure

JspNode Interface

Root interface for all JSP AST nodes.

public interface JspNode extends JjtreeNode<JspNode> {
}

All JSP AST nodes implement this interface, providing common navigation methods:

  • getParent(): Get parent node
  • children(): Get child nodes as stream
  • getChild(int): Get child by index
  • getNumChildren(): Get number of children

AbstractJspNode

Base implementation for all JSP AST nodes.

public abstract class AbstractJspNode extends AbstractJjtreeNode<AbstractJspNode, JspNode> implements JspNode {
    protected AbstractJspNode(int id);
    public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data);
    protected abstract <P, R> R acceptVisitor(JspVisitor<? super P, ? extends R> visitor, P data);
    public String getXPathNodeName();
}

Methods:

  • acceptVisitor(AstVisitor, P): Generic visitor dispatch that delegates to JSP-specific visitors
  • acceptVisitor(JspVisitor, P): Abstract method implemented by concrete nodes for type-safe visitor dispatch
  • getXPathNodeName(): Returns the XPath node name for XPath-based rules

Content Node Base Classes

Base classes for nodes that contain textual content.

public abstract class AbstractContentNode extends AbstractJspNode {
    public String getContent();
}

public abstract class AbstractExpression extends AbstractContentNode {
}

AbstractContentNode:

  • getContent(): Returns the textual content of the node

AbstractExpression:

  • Base class for JSP expressions (JSP expressions, EL expressions, value bindings)
  • Inherits getContent() method from AbstractContentNode

Parser Integration

Token Management

The parser uses JavaCC-generated token managers for lexical analysis.

public final class JspTokenKinds {
    public static final String[] TOKEN_NAMES;
    public static TokenManager<JavaccToken> newTokenManager(CharStream cs);
}

Internal API Bridge

Bridge class for internal PMD framework integration.

public final class InternalApiBridge {
    @InternalApi
    public static JavaccTokenDocument.TokenDocumentBehavior getJspTokenBehavior();
}

Note: InternalApiBridge is marked with @InternalApi and should not be used in external code as compatibility may break.

AST Structure

The JSP parser creates a hierarchical AST structure:

ASTCompilationUnit (root)
├── ASTContent
├── ASTElement (HTML/XML tags)
│   ├── ASTAttribute
│   │   └── ASTAttributeValue
│   └── ASTText (element content)
├── ASTJspDirective (<%@ ... %>)
│   └── ASTJspDirectiveAttribute
├── ASTJspExpression (<%= ... %>)
├── ASTJspScriptlet (<% ... %>)
├── ASTElExpression (${...})
├── ASTValueBinding (#{...})
└── ASTJspComment (<%-- ... --%>)

Error Handling

Parse Exceptions

import net.sourceforge.pmd.lang.ast.ParseException;

Common parsing errors:

  • Syntax Errors: Invalid JSP/HTML syntax
  • Unclosed Tags: HTML elements without proper closing tags
  • Invalid Directives: Malformed JSP directives
  • Expression Errors: Invalid JSP or EL expression syntax

Unclosed Tag Handling

The parser tracks unclosed HTML/XML tags using OpenTagRegister:

class OpenTagRegister {
    void openTag(ASTElement elm);
    boolean closeTag(String closingTagName);
    void closeTag(ASTElement z);
}

Unclosed tags are marked with ASTElement.isUnclosed() returning true.

Examples

Basic Parsing

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

// Parse JSP and traverse AST
ASTCompilationUnit root = // ... parsed JSP
root.children().forEach(child -> {
    if (child instanceof ASTElement) {
        ASTElement element = (ASTElement) child;
        System.out.println("Element: " + element.getName());
    } else if (child instanceof ASTJspExpression) {
        ASTJspExpression expr = (ASTJspExpression) child;
        System.out.println("JSP Expression: " + expr.getContent());
    }
});

Finding Specific Nodes

// Find all JSP expressions in the document
List<ASTJspExpression> expressions = root.descendants(ASTJspExpression.class)
    .collect(Collectors.toList());

// Find elements with specific tag names
List<ASTElement> scriptTags = root.descendants(ASTElement.class)
    .filter(elem -> "script".equals(elem.getName()))
    .collect(Collectors.toList());

The parser provides a complete and accurate representation of JSP documents, enabling sophisticated analysis and rule development.

Install with Tessl CLI

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

docs

ast-node-types.md

copy-paste-detection.md

index.md

jsp-parser-ast.md

language-module.md

rule-development.md

visitor-pattern.md

tile.json