0
# PMD Velocity Module
1
2
PMD Velocity Module (pmd-vm) is a specialized language module within the PMD static analysis framework that provides comprehensive support for Apache Velocity Template Language (VTL) analysis. It implements a complete parser and rule engine for Velocity templates, enabling developers to apply static analysis rules to template files and identify issues such as unused macro parameters, parameter reassignment violations, excessive template length, inline JavaScript/CSS usage, and other template-specific code quality concerns.
3
4
## Package Information
5
6
- **Package Name**: pmd-vm
7
- **Package Type**: Maven module
8
- **Language**: Java (implementation), supports Apache Velocity Template Language (VTL)
9
- **Installation**: Maven dependency `net.sourceforge.pmd:pmd-vm:6.55.0`
10
- **License**: BSD-style
11
12
## Core Imports
13
14
```java
15
import net.sourceforge.pmd.lang.vm.VmLanguageModule;
16
import net.sourceforge.pmd.lang.vm.VmHandler;
17
import net.sourceforge.pmd.lang.vm.rule.AbstractVmRule;
18
import net.sourceforge.pmd.lang.vm.ast.VmNode;
19
import net.sourceforge.pmd.lang.vm.ast.VmParserVisitorAdapter;
20
```
21
22
## Basic Usage
23
24
### Language Module Registration
25
26
```java
27
// PMD automatically registers language modules via VmLanguageModule
28
VmLanguageModule vmModule = new VmLanguageModule();
29
// Module provides NAME="VM" and TERSE_NAME="vm" constants
30
```
31
32
### Creating Custom Rules
33
34
```java
35
import net.sourceforge.pmd.lang.vm.rule.AbstractVmRule;
36
import net.sourceforge.pmd.lang.vm.ast.ASTReference;
37
import net.sourceforge.pmd.lang.vm.ast.VmNode;
38
39
public class CustomVelocityRule extends AbstractVmRule {
40
41
@Override
42
public Object visit(ASTReference node, Object data) {
43
// Analyze Velocity references ($variable)
44
String refName = node.getRootString();
45
if (shouldReportViolation(refName)) {
46
addViolation(data, node, "Custom rule violation: " + refName);
47
}
48
return super.visit(node, data);
49
}
50
51
private boolean shouldReportViolation(String refName) {
52
// Custom logic for rule violation detection
53
return refName != null && refName.startsWith("temp");
54
}
55
}
56
```
57
58
### AST Traversal and Analysis
59
60
```java
61
import net.sourceforge.pmd.lang.vm.ast.VmParserVisitorAdapter;
62
import net.sourceforge.pmd.lang.vm.ast.ASTDirective;
63
import net.sourceforge.pmd.lang.vm.ast.ASTMethod;
64
65
public class VelocityAnalyzer extends VmParserVisitorAdapter {
66
67
@Override
68
public Object visit(ASTDirective node, Object data) {
69
// Analyze Velocity directives (#if, #foreach, etc.)
70
System.out.println("Found directive at line " + node.getLine());
71
return super.visit(node, data);
72
}
73
74
@Override
75
public Object visit(ASTMethod node, Object data) {
76
// Analyze method calls in templates
77
System.out.println("Found method call");
78
return super.visit(node, data);
79
}
80
}
81
```
82
83
## Architecture
84
85
PMD Velocity Module is structured around several key components:
86
87
- **Language Module System**: Integration with PMD's multi-language architecture via `VmLanguageModule`
88
- **Parser Framework**: JavaCC-generated parser for Velocity syntax with token management
89
- **AST Node Hierarchy**: 40+ specialized node types representing different Velocity constructs
90
- **Rule Framework**: Base classes and visitor patterns for implementing static analysis rules
91
- **Built-in Rules**: Production-ready rules for common Velocity template issues
92
- **Visitor Pattern**: Standardized traversal mechanism for AST analysis
93
94
## Capabilities
95
96
### Language Module Integration
97
98
Core integration with PMD framework providing language registration, parsing coordination, and rule violation handling.
99
100
```java { .api }
101
public class VmLanguageModule extends BaseLanguageModule {
102
public static final String NAME = "VM";
103
public static final String TERSE_NAME = "vm";
104
public VmLanguageModule();
105
}
106
107
public class VmHandler extends AbstractLanguageVersionHandler {
108
public RuleViolationFactory getRuleViolationFactory();
109
public Parser getParser(ParserOptions parserOptions);
110
public VisitorStarter getDumpFacade(Writer writer, String prefix, boolean recurse);
111
}
112
```
113
114
[Language Module Integration](./language-integration.md)
115
116
### AST Node Framework
117
118
Complete Abstract Syntax Tree representation of Velocity templates with 40+ specialized node types for expressions, directives, references, and control structures.
119
120
```java { .api }
121
public interface VmNode extends Node {
122
Object jjtAccept(VmParserVisitor visitor, Object data);
123
@Deprecated
124
Object childrenAccept(VmParserVisitor visitor, Object data);
125
VmNode getChild(int index);
126
VmNode getParent();
127
Iterable<? extends VmNode> children();
128
}
129
130
public class VmParserVisitorAdapter implements VmParserVisitor {
131
// Default implementations for all visit methods
132
public Object visit(VmNode node, Object data);
133
public Object visit(ASTReference node, Object data);
134
public Object visit(ASTDirective node, Object data);
135
// ... 40+ visit methods
136
}
137
```
138
139
[AST Node Framework](./ast-nodes.md)
140
141
### Rule Development Framework
142
143
Base classes and utilities for creating custom static analysis rules for Velocity templates.
144
145
```java { .api }
146
public abstract class AbstractVmRule extends AbstractRule
147
implements VmParserVisitor, ImmutableLanguage {
148
public void apply(List<? extends Node> nodes, RuleContext ctx);
149
protected void visitAll(List<? extends Node> nodes, RuleContext ctx);
150
// All VmParserVisitor methods available for override
151
}
152
153
public abstract class AbstractStatisticalVmRule extends AbstractVmRule {
154
// Base class for statistical rules (complexity, length, etc.)
155
}
156
```
157
158
[Rule Development Framework](./rule-development.md)
159
160
### Built-in Static Analysis Rules
161
162
Production-ready rules for detecting common issues in Velocity templates including best practices, design problems, and error-prone patterns.
163
164
```java { .api }
165
// Best Practices Rules
166
public class AvoidReassigningParametersRule extends AbstractVmRule;
167
public class UnusedMacroParameterRule extends AbstractVmRule;
168
169
// Design Rules
170
public class ExcessiveTemplateLengthRule extends AbstractStatisticalVmRule;
171
public class AvoidDeeplyNestedIfStmtsRule extends AbstractStatisticalVmRule;
172
public class CollapsibleIfStatementsRule extends AbstractVmRule;
173
public class NoInlineJavaScriptRule extends AbstractVmRule;
174
175
// Error-Prone Rules
176
public class EmptyIfStmtRule extends AbstractVmRule;
177
public class EmptyForeachStmtRule extends AbstractVmRule;
178
```
179
180
[Built-in Rules](./builtin-rules.md)
181
182
### Template Parsing and Token Management
183
184
Low-level parsing capabilities for Velocity template syntax with comprehensive error handling.
185
186
```java { .api }
187
@Deprecated
188
@InternalApi
189
public class VmParser extends AbstractParser {
190
public TokenManager createTokenManager(Reader source);
191
public Node parse(String fileName, Reader source) throws ParseException;
192
public Map<Integer, String> getSuppressMap();
193
}
194
195
@Deprecated
196
@InternalApi
197
public class VmTokenManager implements TokenManager {
198
public Token getNextToken();
199
public void setFileName(String fileName);
200
}
201
```
202
203
[Parsing and Token Management](./parsing.md)
204
205
## Types
206
207
### Core Interfaces
208
209
```java { .api }
210
public interface VmParserVisitor {
211
Object visit(VmNode node, Object data);
212
Object visit(ASTReference node, Object data);
213
Object visit(ASTDirective node, Object data);
214
Object visit(ASTMethod node, Object data);
215
Object visit(ASTAddNode node, Object data);
216
Object visit(ASTSubtractNode node, Object data);
217
Object visit(ASTMulNode node, Object data);
218
Object visit(ASTDivNode node, Object data);
219
Object visit(ASTModNode node, Object data);
220
Object visit(ASTOrNode node, Object data);
221
Object visit(ASTAndNode node, Object data);
222
Object visit(ASTEQNode node, Object data);
223
Object visit(ASTNENode node, Object data);
224
Object visit(ASTLTNode node, Object data);
225
Object visit(ASTGTNode node, Object data);
226
Object visit(ASTLENode node, Object data);
227
Object visit(ASTGENode node, Object data);
228
Object visit(ASTNotNode node, Object data);
229
Object visit(ASTIfStatement node, Object data);
230
Object visit(ASTElseStatement node, Object data);
231
Object visit(ASTElseIfStatement node, Object data);
232
Object visit(ASTForeachStatement node, Object data);
233
Object visit(ASTSetDirective node, Object data);
234
Object visit(ASTBlock node, Object data);
235
Object visit(ASTExpression node, Object data);
236
Object visit(ASTAssignment node, Object data);
237
Object visit(ASTMap node, Object data);
238
Object visit(ASTObjectArray node, Object data);
239
Object visit(ASTIntegerRange node, Object data);
240
Object visit(ASTIndex node, Object data);
241
Object visit(ASTText node, Object data);
242
Object visit(ASTTextblock node, Object data);
243
Object visit(ASTComment node, Object data);
244
Object visit(ASTFloatingPointLiteral node, Object data);
245
Object visit(ASTIntegerLiteral node, Object data);
246
Object visit(ASTStringLiteral node, Object data);
247
Object visit(ASTIdentifier node, Object data);
248
Object visit(ASTWord node, Object data);
249
Object visit(ASTTrue node, Object data);
250
Object visit(ASTFalse node, Object data);
251
Object visit(ASTEscape node, Object data);
252
Object visit(ASTEscapedDirective node, Object data);
253
Object visit(ASTprocess node, Object data);
254
}
255
```
256
257
### Exception Types
258
259
```java { .api }
260
@Deprecated
261
public class TemplateParseException extends ParseException {
262
public TemplateParseException(String message);
263
public TemplateParseException(String message, String templateName, int lineNumber, int columnNumber);
264
public String getTemplateName();
265
public int getLineNumber();
266
public int getColumnNumber();
267
}
268
269
public class MacroParseException extends ParseException {
270
// Macro-specific parse exceptions
271
}
272
273
public class TokenMgrError {
274
// Token manager error handling
275
}
276
```