forked from pmd/pmd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
antlr4-wrapper.xml
156 lines (120 loc) · 6.82 KB
/
antlr4-wrapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<!--
~ BSD-style license; for more info see http://pmd.sourceforge.net/license.html
-->
<project name="pmd" default="adapt-antlr-sources" basedir="../../../../">
<!-- Input properties:
- lang-name: matches the grammar name (eg "Swift")
- lang-id: the language id, used in the conventional package name (eg "swift")
- node-prefix: prefix for generated AST nodes (eg "Sw")
- root-node-name: name of the root node without prefix (eg "TopLevel"), will be made to implement RootNode
See AntlrGeneratedParserBase
-->
<property name="target-package-dir" value="${antlr4.outputDirectory}/net/sourceforge/pmd/lang/${lang-id}/ast"/>
<property name="lang-ast-package" value="net.sourceforge.pmd.lang.${lang-id}.ast" />
<property name="ast-api-package" value="net.sourceforge.pmd.lang.ast" />
<property name="ast-impl-package" value="${ast-api-package}.impl.antlr4" />
<property name="parser-name" value="${lang-name}Parser"/>
<property name="parser-file" value="${target-package-dir}/${parser-name}.java"/>
<property name="visitor-name" value="${lang-name}Visitor"/>
<property name="visitor-file" value="${target-package-dir}/${visitor-name}.java"/>
<property name="base-visitor-name" value="${lang-name}BaseVisitor"/>
<property name="base-visitor-file" value="${target-package-dir}/${base-visitor-name}.java"/>
<property name="listener-name" value="${lang-name}Listener"/>
<property name="listener-file" value="${target-package-dir}/${visitor-name}.java"/>
<property name="base-listener-name" value="${lang-name}BaseListener"/>
<property name="base-listener-file" value="${target-package-dir}/${base-visitor-name}.java"/>
<property name="node-itf-name" value="${lang-name}Node"/>
<property name="base-class-name" value="Abstract${lang-name}Node"/>
<condition property="rename-parser">
<and>
<not>
<available file="${parser-file}"/>
</not>
<available file="${target-package-dir}/${lang-name}.java"/>
</and>
</condition>
<target name="rename-parser" description="Rename the parser to our conventional name if needed"
if="rename-parser">
<replace file="${target-package-dir}/${lang-name}.java">
<replacefilter token="class ${lang-name} "
value="class ${parser-name} "/>
<replacefilter token="public ${lang-name}(TokenStream input)"
value="public ${parser-name}(TokenStream input)"/>
</replace>
<replace dir="${target-package-dir}">
<include name="${lang-name}.java"/>
<include name="${visitor-name}.java"/>
<include name="${base-visitor-name}.java"/>
<include name="${listener-name}.java"/>
<include name="${base-listener-name}.java"/>
<replacefilter token="${lang-name}." value="${parser-name}."/>
<replacefilter token="${lang-name}#" value="${parser-name}#"/>
<replacefilter token="{@link ${lang-name}}" value="{@link ${parser-name}}"/>
</replace>
<move file="${target-package-dir}/${lang-name}.java"
tofile="${parser-file}"/>
</target>
<target name="cpd-language" description="Adapt Antlr sources for CPD-only languages">
<!-- We only need the Lexer file. -->
<delete file="${parser-file}"/>
<delete>
<fileset dir="${target-package-dir}">
<include name="*"/>
<exclude name="*Lexer.java"/>
</fileset>
</delete>
</target>
<target name="pmd-language" description="Adapt Antlr sources for PMD languages" depends="rename-parser">
<!-- Adapt parser. -->
<replace file="${parser-file}">
<replacefilter token="${root-node-name}Context extends ${lang-name}InnerNode"
value="${root-node-name}Context extends ${lang-name}RootNode"/>
<replacefilter token="_ctx = _localctx;"
value="_ctx = _localctx.asAntlrNode();"/>
<replacefilter token="public <T> T accept(ParseTreeVisitor<? extends T> visitor)"
value="public <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data)" />
<replacefilter token="((${visitor-name}<? extends T>)visitor)"
value="((${visitor-name}<? super P, ? extends R>) visitor)" />
<replacefilter token="return visitor.visitChildren(this);"
value="return super.acceptVisitor(visitor, data);" />
</replace>
<replaceregexp flags="g" file="${parser-file}">
<regexp pattern="\.visit(\w++)\(this\);"/>
<substitution expression=".visit\1(this, data);"/>
</replaceregexp>
<replaceregexp flags="g" file="${parser-file}">
<regexp pattern="_sempred\(\((\w+)\)_localctx,"/>
<substitution expression="_sempred\((\1) asPmdNode(_localctx),"/>
</replaceregexp>
<!-- Transform the visitor to PMD-style. -->
<replace file="${visitor-file}">
<replacefilter token="@param <T> The return type of the visit operation. Use {@link Void} for"
value="@param <P> The parameter type of the visit * @param <R> The return type of the visit operation. Use {@link Void} for"/>
<replacefilter token="Visitor<T> extends ParseTreeVisitor<T> {"
value="Visitor<P, R> extends net.sourceforge.pmd.lang.ast.AstVisitor<P, R> {
/**
* The default visit method for ${lang-name} nodes. Unless overridden,
* the default implementations of the methods of this interface delegate
* to this method. The default calls {@link #visitNode(Node, Object)}.
*
* @param node Node to visit
* @param data Parameter of the visit
* @return Result of the visit
*/
default R visit${node-itf-name}(${node-itf-name} node, P data) { return visitNode(node, data); }
"/>
<replacefilter token="T visit" value="default R visit"/>
<replacefilter token="ctx);" value="node, P data) { return visit${node-itf-name}(node, data); }"/>
<replacefilter token="@param ctx the parse tree" value="@param node Node to visit 	 * @param data Parameter of the visit"/>
</replace>
<!-- This is in the main sources (not much to do). -->
<delete file="${base-visitor-file}" />
<replaceregexp flags="g">
<fileset dir="${target-package-dir}" />
<regexp pattern="\b([A-Z]\w*)Context\b(?<!\b(Parser)?RuleContext\b)"/>
<substitution expression="${node-prefix}\1"/>
</replaceregexp>
</target>
</project>