2020-05-02 02:57:14 +02:00
|
|
|
<!--
|
|
|
|
~ BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
|
|
|
-->
|
|
|
|
|
|
|
|
<project name="pmd" default="adapt-antlr-sources" basedir="../../../../">
|
|
|
|
|
2020-05-02 21:48:50 +02:00
|
|
|
<!-- Input properties:
|
|
|
|
- lang-name: matches the grammar name (eg "Swift")
|
2024-02-23 17:45:23 +01:00
|
|
|
- lang-id: the language id, used in the conventional package name (eg "swift")
|
2020-06-17 21:39:03 +02:00
|
|
|
- node-prefix: prefix for generated AST nodes (eg "Sw")
|
2022-03-03 20:58:46 +01:00
|
|
|
- root-node-name: name of the root node without prefix (eg "TopLevel"), will be made to implement RootNode
|
2020-05-02 21:48:50 +02:00
|
|
|
|
|
|
|
See AntlrGeneratedParserBase
|
|
|
|
-->
|
2024-10-12 17:28:18 -03:00
|
|
|
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
|
2020-05-02 21:48:50 +02:00
|
|
|
|
2024-02-23 17:45:23 +01:00
|
|
|
<property name="target-package-dir" value="${antlr4.outputDirectory}/net/sourceforge/pmd/lang/${lang-id}/ast"/>
|
2024-10-06 19:48:30 -03:00
|
|
|
<property name="stamp-file" value="${project.build.directory}/last-generated-timestamp" />
|
2020-05-02 02:57:14 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
|
2024-02-23 17:45:23 +01:00
|
|
|
<property name="lang-ast-package" value="net.sourceforge.pmd.lang.${lang-id}.ast" />
|
2020-06-17 20:25:56 +02:00
|
|
|
<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"/>
|
|
|
|
|
2021-09-15 16:55:37 +02:00
|
|
|
<property name="listener-name" value="${lang-name}Listener"/>
|
2024-10-06 17:24:42 -03:00
|
|
|
<property name="listener-file" value="${target-package-dir}/${listener-name}.java"/>
|
2021-09-15 16:55:37 +02:00
|
|
|
|
|
|
|
<property name="base-listener-name" value="${lang-name}BaseListener"/>
|
2024-10-06 17:24:42 -03:00
|
|
|
<property name="base-listener-file" value="${target-package-dir}/${base-listener-name}.java"/>
|
2021-09-15 16:55:37 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
<property name="node-itf-name" value="${lang-name}Node"/>
|
|
|
|
<property name="base-class-name" value="Abstract${lang-name}Node"/>
|
|
|
|
|
2024-10-06 20:07:37 -03:00
|
|
|
<property name="lexer-name" value="${lang-name}Lexer"/>
|
|
|
|
<property name="lexer-file" value="${target-package-dir}/${lexer-name}.java"/>
|
|
|
|
|
2024-10-06 19:48:30 -03:00
|
|
|
<target name="check-up-to-date"
|
|
|
|
description="Checks the input files are up to date">
|
|
|
|
|
|
|
|
<uptodate property="processing-not-required" targetfile="${stamp-file}">
|
|
|
|
<srcfiles dir="${target-package-dir}" includes="*.java" />
|
|
|
|
<srcfiles file="${ant.file}" />
|
|
|
|
</uptodate>
|
|
|
|
<echo message="Up-to-date check: processing-not-required=${processing-not-required}" />
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="update-stamp-file" unless="processing-not-required">
|
|
|
|
<touch file="${stamp-file}" />
|
|
|
|
</target>
|
|
|
|
|
2024-10-06 19:58:43 -03:00
|
|
|
<target name="annotate-classes" description="Adds the @Generated annotation to all classes"
|
|
|
|
unless="processing-not-required">
|
|
|
|
<if>
|
|
|
|
<available file="${parser-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${parser-file}"
|
|
|
|
token="public class ${parser-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public class ${parser-name}'/>
|
|
|
|
|
|
|
|
<!-- Parse tree classes for each element -->
|
|
|
|
<replace file="${parser-file}"
|
|
|
|
token="public static class "
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public static class '/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
|
|
|
|
<if>
|
|
|
|
<available file="${visitor-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${visitor-file}"
|
|
|
|
token="public interface ${visitor-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public interface ${visitor-name}'/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
|
|
|
|
<if>
|
|
|
|
<available file="${base-visitor-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${base-visitor-file}"
|
|
|
|
token="public class ${base-visitor-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public class ${base-visitor-name}'/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
|
|
|
|
<if>
|
|
|
|
<available file="${listener-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${listener-file}"
|
|
|
|
token="public interface ${listener-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public interface ${listener-name}'/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
|
|
|
|
<if>
|
|
|
|
<available file="${base-listener-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${base-listener-file}"
|
|
|
|
token="public class ${base-listener-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public class ${base-listener-name}'/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
|
|
|
|
<if>
|
|
|
|
<available file="${lexer-file}"/>
|
|
|
|
<then>
|
|
|
|
<replace file="${lexer-file}"
|
|
|
|
token="public class ${lexer-name}"
|
|
|
|
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
|
|
|
public class ${lexer-name}'/>
|
|
|
|
</then>
|
|
|
|
</if>
|
|
|
|
</target>
|
|
|
|
|
2021-09-15 16:55:37 +02:00
|
|
|
<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}."/>
|
2024-03-07 20:55:22 +01:00
|
|
|
<replacefilter token="${lang-name}#" value="${parser-name}#"/>
|
|
|
|
<replacefilter token="{@link ${lang-name}}" value="{@link ${parser-name}}"/>
|
2021-09-15 16:55:37 +02:00
|
|
|
</replace>
|
|
|
|
|
|
|
|
<move file="${target-package-dir}/${lang-name}.java"
|
|
|
|
tofile="${parser-file}"/>
|
|
|
|
</target>
|
|
|
|
|
2024-10-06 19:58:43 -03:00
|
|
|
<target name="cpd-language" depends="check-up-to-date, annotate-classes, cpd-language-processing, update-stamp-file"/>
|
2024-10-06 19:48:30 -03:00
|
|
|
<target name="cpd-language-processing" description="Adapt Antlr sources for CPD-only languages"
|
|
|
|
unless="processing-not-required">
|
2020-08-30 18:50:01 +02:00
|
|
|
<!-- 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>
|
|
|
|
|
2024-11-14 16:47:20 -03:00
|
|
|
<target name="pmd-language" depends="check-up-to-date, rename-parser, annotate-classes, pmd-language-processing, update-stamp-file"/>
|
|
|
|
<target name="pmd-language-processing" description="Adapt Antlr sources for PMD languages"
|
2024-10-06 20:07:47 -03:00
|
|
|
unless="processing-not-required">
|
2020-05-02 02:57:14 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
<!-- Adapt parser. -->
|
|
|
|
<replace file="${parser-file}">
|
|
|
|
<replacefilter token="${root-node-name}Context extends ${lang-name}InnerNode"
|
2020-11-15 17:40:14 +01:00
|
|
|
value="${root-node-name}Context extends ${lang-name}RootNode"/>
|
2020-06-17 20:25:56 +02:00
|
|
|
|
|
|
|
<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)" />
|
2020-05-02 02:57:14 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
<replacefilter token="return visitor.visitChildren(this);"
|
2020-07-01 11:14:55 +02:00
|
|
|
value="return super.acceptVisitor(visitor, data);" />
|
2020-05-02 02:57:14 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
</replace>
|
2020-05-02 02:57:14 +02:00
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
<replaceregexp flags="g" file="${parser-file}">
|
|
|
|
<regexp pattern="\.visit(\w++)\(this\);"/>
|
|
|
|
<substitution expression=".visit\1(this, data);"/>
|
|
|
|
</replaceregexp>
|
|
|
|
|
|
|
|
<replaceregexp flags="g" file="${parser-file}">
|
2020-05-02 02:57:14 +02:00
|
|
|
<regexp pattern="_sempred\(\((\w+)\)_localctx,"/>
|
|
|
|
<substitution expression="_sempred\((\1) asPmdNode(_localctx),"/>
|
|
|
|
</replaceregexp>
|
|
|
|
|
2020-06-17 20:25:56 +02:00
|
|
|
<!-- Transform the visitor to PMD-style. -->
|
|
|
|
<replace file="${visitor-file}">
|
|
|
|
|
2024-03-07 20:55:22 +01:00
|
|
|
<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"/>
|
2020-06-17 20:25:56 +02:00
|
|
|
<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); }"/>
|
2024-03-07 20:55:22 +01:00
|
|
|
<replacefilter token="@param ctx the parse tree" value="@param node Node to visit 	 * @param data Parameter of the visit"/>
|
2020-06-17 20:25:56 +02:00
|
|
|
|
|
|
|
</replace>
|
|
|
|
|
2020-06-17 21:39:03 +02:00
|
|
|
<!-- This is in the main sources (not much to do). -->
|
|
|
|
<delete file="${base-visitor-file}" />
|
2020-06-17 20:25:56 +02:00
|
|
|
|
|
|
|
|
2020-06-17 21:39:03 +02:00
|
|
|
<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>
|
2020-06-17 20:25:56 +02:00
|
|
|
|
|
|
|
|
2020-05-02 02:57:14 +02:00
|
|
|
</target>
|
|
|
|
</project>
|