PMD JSP language module providing static code analysis capabilities for JavaServer Pages files with lexical analysis, AST parsing, and rule-based code quality checks.
—
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.
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 nodetokenBehavior(): Returns token behavior configuration for the parserExceptions:
ParseException: Thrown when JSP source cannot be parsed due to syntax errorsRoot 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 documentacceptVisitor(JspVisitor, P): Accepts a visitor for AST traversalRoot 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 nodechildren(): Get child nodes as streamgetChild(int): Get child by indexgetNumChildren(): Get number of childrenBase 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 visitorsacceptVisitor(JspVisitor, P): Abstract method implemented by concrete nodes for type-safe visitor dispatchgetXPathNodeName(): Returns the XPath node name for XPath-based rulesBase 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 nodeAbstractExpression:
getContent() method from AbstractContentNodeThe 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);
}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.
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 (<%-- ... --%>)import net.sourceforge.pmd.lang.ast.ParseException;Common parsing errors:
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.
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());
}
});// 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