diff options
Diffstat (limited to 'antlr4-maven-plugin')
24 files changed, 1194 insertions, 151 deletions
diff --git a/antlr4-maven-plugin/pom.xml b/antlr4-maven-plugin/pom.xml index b9e144d..319418a 100644 --- a/antlr4-maven-plugin/pom.xml +++ b/antlr4-maven-plugin/pom.xml @@ -1,40 +1,14 @@ <!-- - -[The "BSD license"] - ANTLR - Copyright (c) Terence Parr, Sam Harwell - Maven Plugin - Copyright (c) Jim Idle - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.antlr</groupId> <artifactId>antlr4-master</artifactId> - <version>4.5.4-SNAPSHOT</version> + <version>4.6</version> </parent> <artifactId>antlr4-maven-plugin</artifactId> <packaging>maven-plugin</packaging> @@ -48,11 +22,16 @@ <!-- Ancilliary information for completeness --> <inceptionYear>2009</inceptionYear> + <properties> + <mavenVersion>3.3.9</mavenVersion> + <takariLifecycleVersion>1.11.12</takariLifecycleVersion> + </properties> + <!-- ============================================================================= --> - <!-- What are we depedent on for the Mojos to execute? We need the plugin - API itself and of course we need the ANTLR Tool and runtime and any of their - dependencies, which we inherit. The Tool itself provides us with all the + <!-- What are we depedent on for the Mojos to execute? We need the plugin + API itself and of course we need the ANTLR Tool and runtime and any of their + dependencies, which we inherit. The Tool itself provides us with all the dependencies, so we need only name it here. --> <dependencies> @@ -64,11 +43,6 @@ <scope>compile</scope> </dependency> <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-project</artifactId> - <version>2.2.1</version> - </dependency> - <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-compiler-api</artifactId> <version>2.2</version> @@ -78,8 +52,8 @@ <artifactId>plexus-build-api</artifactId> <version>0.0.7</version> </dependency> - <!-- The version of ANTLR tool that this version of the plugin controls. - We have decided that this should be in lockstep with ANTLR itself, other + <!-- The version of ANTLR tool that this version of the plugin controls. + We have decided that this should be in lockstep with ANTLR itself, other than -1 -2 -3 etc patch releases. --> <dependency> <groupId>org.antlr</groupId> @@ -90,13 +64,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.11</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.maven.shared</groupId> - <artifactId>maven-plugin-testing-harness</artifactId> - <version>1.1</version> + <version>4.12</version> <scope>test</scope> </dependency> <dependency> @@ -105,9 +73,49 @@ <version>3.2</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>io.takari.maven.plugins</groupId> + <artifactId>takari-plugin-testing</artifactId> + <version>2.9.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>${mavenVersion}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>${mavenVersion}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.15</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> </dependencies> <build> + <resources> + <resource> + <directory>resources</directory> + </resource> + </resources> + <testSourceDirectory>src/test</testSourceDirectory> + <testResources> + <testResource> + <directory>src/test/resources</directory> + </testResource> + </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -132,6 +140,21 @@ </execution> </executions> </plugin> + <plugin> + <groupId>io.takari.maven.plugins</groupId> + <artifactId>takari-lifecycle-plugin</artifactId> + <version>${takariLifecycleVersion}</version> + <extensions>true</extensions> + <executions> + <execution> + <id>testProperties</id> + <phase>process-test-resources</phase> + <goals> + <goal>testProperties</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> @@ -145,7 +168,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> - <version>2.9</version> + <version>2.10.4</version> <configuration> <quiet>true</quiet> </configuration> @@ -153,7 +176,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jxr-plugin</artifactId> - <version>2.3</version> + <version>2.5</version> </plugin> </plugins> </reporting> diff --git a/antlr4-maven-plugin/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/antlr4-maven-plugin/resources/META-INF/m2e/lifecycle-mapping-metadata.xml index de806ee..84a4919 100644 --- a/antlr4-maven-plugin/resources/META-INF/m2e/lifecycle-mapping-metadata.xml +++ b/antlr4-maven-plugin/resources/META-INF/m2e/lifecycle-mapping-metadata.xml @@ -1,4 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4ErrorLog.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4ErrorLog.java index b251878..92d2377 100644 --- a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4ErrorLog.java +++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4ErrorLog.java @@ -1,31 +1,8 @@ /* - [The "BSD license"] - Copyright (c) 2012 Terence Parr - Copyright (c) 2012 Sam Harwell - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ package org.antlr.mojo.antlr4; import org.antlr.v4.Tool; diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java index d8712ee..0afe54f 100644 --- a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java +++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java @@ -1,31 +1,8 @@ /* - [The "BSD license"] - Copyright (c) 2012 Terence Parr - Copyright (c) 2012 Sam Harwell - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ package org.antlr.mojo.antlr4; @@ -59,6 +36,7 @@ import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.net.URI; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -95,7 +73,13 @@ public class Antlr4Mojo extends AbstractMojo { * specify grammar file encoding; e.g., euc-jp */ @Parameter(property = "project.build.sourceEncoding") - protected String encoding; + protected String inputEncoding; + + /** + * specify output file encoding; defaults to source encoding + */ + @Parameter(property = "project.build.sourceEncoding") + protected String outputEncoding; /** * Generate parse tree listener interface and base class. @@ -184,6 +168,12 @@ public class Antlr4Mojo extends AbstractMojo { @Parameter(defaultValue = "${basedir}/src/main/antlr4/imports") private File libDirectory; + /** + * The directory where build status information is located. + */ + @Parameter(defaultValue = "${project.build.directory}/maven-status/antlr4", readonly=true) + private File statusDirectory; + @Component private BuildContext buildContext; @@ -222,6 +212,8 @@ public class Antlr4Mojo extends AbstractMojo { Log log = getLog(); + outputEncoding = validateEncoding(outputEncoding); + if (log.isDebugEnabled()) { for (String e : excludes) { log.debug("ANTLR: Exclude: " + e); @@ -249,16 +241,22 @@ public class Antlr4Mojo extends AbstractMojo { outputDir.mkdirs(); } + GrammarDependencies dependencies = new GrammarDependencies(sourceDirectory, libDirectory, arguments, getDependenciesStatusFile(), getLog()); + // Now pick up all the files and process them with the Tool // List<List<String>> argumentSets; + Set<File> grammarFiles; + Set<File> importGrammarFiles; try { List<String> args = getCommandArguments(); - argumentSets = processGrammarFiles(args, sourceDirectory); - } catch (InclusionScanException ie) { - log.error(ie); - throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze", ie); + grammarFiles = getGrammarFiles(sourceDirectory); + importGrammarFiles = getImportFiles(sourceDirectory); + argumentSets = processGrammarFiles(args, grammarFiles, dependencies, sourceDirectory); + } catch (Exception e) { + log.error(e); + throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze", e); } log.debug("Output directory base will be " + outputDirectory.getAbsolutePath()); @@ -272,6 +270,14 @@ public class Antlr4Mojo extends AbstractMojo { throw new MojoFailureException("Error creating an instanceof the ANTLR tool.", e); } + try { + dependencies.analyze(grammarFiles, importGrammarFiles, tool); + } catch (Exception e) { + log.error("Dependency analysis failed, see exception report for details", + e); + throw new MojoFailureException("Dependency analysis failed.", e); + } + // Set working directory for ANTLR to be the base source directory tool.inputDirectory = sourceDirectory; @@ -288,6 +294,12 @@ public class Antlr4Mojo extends AbstractMojo { // Tell Maven that there are some new source files underneath the output directory. addSourceRoot(this.getOutputDirectory()); } + + try { + dependencies.save(); + } catch (IOException ex) { + log.warn("Could not save grammar dependency status", ex); + } } private List<String> getCommandArguments() { @@ -310,9 +322,10 @@ public class Antlr4Mojo extends AbstractMojo { args.add("-atn"); } - if (encoding != null && !encoding.isEmpty()) { + if ( inputEncoding!=null && !inputEncoding.isEmpty()) { args.add("-encoding"); - args.add(encoding); + outputEncoding = inputEncoding; + args.add(inputEncoding); } if (listener) { @@ -355,22 +368,11 @@ public class Antlr4Mojo extends AbstractMojo { * @param sourceDirectory * @exception InclusionScanException */ - - private List<List<String>> processGrammarFiles(List<String> args, File sourceDirectory) throws InclusionScanException { - // Which files under the source set should we be looking for as grammar files - SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet()); - - // What are the sets of includes (defaulted or otherwise). - Set<String> includes = getIncludesPatterns(); - - // Now, to the excludes, we need to add the imports directory - // as this is autoscanned for imported grammars and so is auto-excluded from the - // set of grammar fields we should be analyzing. - excludes.add("imports/**"); - - SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes); - scan.addSourceMapping(mapping); - Set<File> grammarFiles = scan.getIncludedSources(sourceDirectory, null); + private List<List<String>> processGrammarFiles( + List<String> args, + Set<File> grammarFiles, + GrammarDependencies dependencies, + File sourceDirectory) throws InclusionScanException, IOException { // We don't want the plugin to run for every grammar, regardless of whether // it's changed since the last compilation. Check the mtime of the tokens vs @@ -381,7 +383,8 @@ public class Antlr4Mojo extends AbstractMojo { String tokensFileName = grammarFile.getName().split("\\.")[0] + ".tokens"; File outputFile = new File(outputDirectory, tokensFileName); if ( (! outputFile.exists()) || - outputFile.lastModified() < grammarFile.lastModified() ) { + outputFile.lastModified() < grammarFile.lastModified() || + dependencies.isDependencyChanged(grammarFile)) { grammarFilesToProcess.add(grammarFile); } } @@ -405,7 +408,7 @@ public class Antlr4Mojo extends AbstractMojo { getLog().debug("Grammar file '" + grammarFile.getPath() + "' detected."); - String relPathBase = findSourceSubdir(sourceDirectory, grammarFile.getPath()); + String relPathBase = MojoUtils.findSourceSubdir(sourceDirectory, grammarFile); String relPath = relPathBase + grammarFile.getName(); getLog().debug(" ... relative path is: " + relPath); @@ -430,6 +433,39 @@ public class Antlr4Mojo extends AbstractMojo { return result; } + private Set<File> getImportFiles(File sourceDirectory) throws InclusionScanException { + if (!libDirectory.exists()) return Collections.emptySet(); + + Set<String> includes = new HashSet<String>(); + includes.add("*.g4"); + includes.add("*.tokens"); + + SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, + Collections.<String>emptySet()); + scan.addSourceMapping(new SuffixMapping("G4", "g4")); + + return scan.getIncludedSources(libDirectory, null); + } + + private Set<File> getGrammarFiles(File sourceDirectory) throws InclusionScanException + { + // Which files under the source set should we be looking for as grammar files + SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet()); + + // What are the sets of includes (defaulted or otherwise). + Set<String> includes = getIncludesPatterns(); + + // Now, to the excludes, we need to add the imports directory + // as this is autoscanned for imported grammars and so is auto-excluded from the + // set of grammar fields we should be analyzing. + excludes.add("imports/**"); + + SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes); + scan.addSourceMapping(mapping); + + return scan.getIncludedSources(sourceDirectory, null); + } + private static String getPackageName(String relativeFolderPath) { if (relativeFolderPath.contains("..")) { throw new UnsupportedOperationException("Cannot handle relative paths containing '..'"); @@ -450,30 +486,14 @@ public class Antlr4Mojo extends AbstractMojo { return includes; } - /** - * Given the source directory File object and the full PATH to a grammar, - * produce the path to the named grammar file in relative terms to the - * {@code sourceDirectory}. This will then allow ANTLR to produce output - * relative to the base of the output directory and reflect the input - * organization of the grammar files. - * - * @param sourceDirectory The source directory {@link File} object - * @param grammarFileName The full path to the input grammar file - * @return The path to the grammar file relative to the source directory - */ - private String findSourceSubdir(File sourceDirectory, String grammarFileName) { - String srcPath = sourceDirectory.getPath() + File.separator; + private File getDependenciesStatusFile() { + File statusFile = new File(statusDirectory, "dependencies.ser"); - if (!grammarFileName.startsWith(srcPath)) { - throw new IllegalArgumentException("expected " + grammarFileName + " to be prefixed with " + sourceDirectory); + if (!statusFile.getParentFile().exists()) { + statusFile.getParentFile().mkdirs(); } - File unprefixedGrammarFileName = new File(grammarFileName.substring(srcPath.length())); - if (unprefixedGrammarFileName.getParent() == null) { - return ""; - } - - return unprefixedGrammarFileName.getParent() + File.separator; + return statusFile; } private final class CustomTool extends Tool { @@ -515,7 +535,21 @@ public class Antlr4Mojo extends AbstractMojo { URI relativePath = project.getBasedir().toURI().relativize(outputFile.toURI()); getLog().debug(" Writing file: " + relativePath); OutputStream outputStream = buildContext.newFileOutputStream(outputFile); - return new BufferedWriter(new OutputStreamWriter(outputStream)); + if ( outputEncoding!=null && !outputEncoding.isEmpty()) { + return new BufferedWriter(new OutputStreamWriter(outputStream, outputEncoding)); + } + else { + return new BufferedWriter(new OutputStreamWriter(outputStream)); + } } } + + /** + * Validates the given encoding. + * + * @return the validated encoding. If {@code null} was provided, returns the platform default encoding. + */ + private String validateEncoding(String encoding) { + return (encoding == null) ? Charset.defaultCharset().name() : Charset.forName(encoding.trim()).name(); + } } diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java new file mode 100644 index 0000000..f8ebb1e --- /dev/null +++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ + +package org.antlr.mojo.antlr4; + +import org.antlr.runtime.tree.Tree; +import org.antlr.v4.Tool; +import org.antlr.v4.misc.Graph; +import org.antlr.v4.parse.ANTLRParser; +import org.antlr.v4.tool.ast.GrammarAST; +import org.antlr.v4.tool.ast.GrammarRootAST; +import org.apache.maven.plugin.logging.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +class GrammarDependencies { + private final Graph<String> graph = new Graph<String>(); + private final File sourceDirectory; + private final File libDirectory; + private final File statusFile; + private final String packageName; + + /** Map grammars to their checksum and references. */ + private final Map<File, Map.Entry<byte[], Collection<String>>> grammars; + private final Log log; + + public GrammarDependencies(File sourceDirectory, File libDirectory, + List<String> arguments, File status, Log log) { + this.log = log; + this.sourceDirectory = sourceDirectory; + this.libDirectory = libDirectory; + this.statusFile = status; + this.grammars = loadStatus(status); + this.packageName = getPackage(arguments); + } + + /** + * Determines the package to use. + * + * @param arguments the tool arguments. + * + * @return the package. Returns {@code null} to indicate that no package should be + * used. + */ + private String getPackage(List<String> arguments) { + int index = (arguments != null) ? arguments.indexOf("-package") : -1; + + return (index > -1) + ? (arguments.get(index + 1).replace('.', File.separatorChar) + + File.separatorChar) + : null; + } + + public void save() throws IOException { + if (!grammars.isEmpty()) { + log.debug("Persisting grammars dependency status: " + statusFile); + + ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( + statusFile)); + + try { + out.writeObject(grammars); + } finally { + out.close(); + } + } + } + + /** + * Performs dependency analysis for the given grammar files. + * + * @param grammarFiles the grammar files. + * @param importGrammarFiles the import grammar files. + * @param tool the tool to use. + * + * @return self-reference. + */ + public GrammarDependencies analyze(Set<File> grammarFiles, + Set<File> importGrammarFiles, Tool tool) throws IOException { + log.debug("Analysing grammar dependencies " + sourceDirectory); + + // for dependency analysis we require all grammars + Collection<File> grammarsAndTokens = new HashSet<File>(); + grammarsAndTokens.addAll(importGrammarFiles); + grammarsAndTokens.addAll(grammarFiles); + + for (File grammarFile : grammarsAndTokens) { + // .tokens files must not be parsed, they can just be referenced + if (!grammarFile.getName().endsWith(".tokens")) + analyse(grammarFile, grammarsAndTokens, tool); + } + + for (File grammarFile : grammarFiles) { + Collection<String> usages = findUsages(getRelativePath(grammarFile)); + + if (!usages.isEmpty()) { + grammars.put(grammarFile, + new AbstractMap.SimpleImmutableEntry<byte[], Collection<String>>( + MojoUtils.checksum(grammarFile), usages)); + + log.debug(" " + getRelativePath(grammarFile) + " used by " + usages); + } + } + + for (File grammarFile : importGrammarFiles) { + // imported files are not allowed to be qualified + Collection<String> usages = findUsages(grammarFile.getName()); + + if (!usages.isEmpty()) { + grammars.put(grammarFile, + new AbstractMap.SimpleImmutableEntry<byte[], Collection<String>>( + MojoUtils.checksum(grammarFile), usages)); + + log.debug(" " + grammarFile.getName() + " imported by " + usages); + } + } + + return this; + } + + + /** + * Determines whether a grammar used by the given grammar was modified since the last + * build. + * + * @param grammarFile the grammar. + * + * @return {@code true} if a grammar used by the given grammar has been modified. + */ + public boolean isDependencyChanged(File grammarFile) throws IOException { + String grammarPath = getRelativePath(grammarFile); + + for (Map.Entry<File, Map.Entry<byte[], Collection<String>>> e : grammars.entrySet()) { + File depGrammarFile = e.getKey(); + byte[] checksum = e.getValue().getKey(); + Collection<String> usages = e.getValue().getValue(); + + if (usages.contains(grammarPath)) { + if (!depGrammarFile.exists() || !Arrays.equals(MojoUtils.checksum(depGrammarFile), checksum)) { + log.debug(" " + grammarPath + ": dependency " + + depGrammarFile.getName() + " changed"); + + return true; + } + } + } + + return false; + } + + /** + * Determines the relative target path of the given grammar file. + * + * @param grammarFile the grammar file. + * + * @return the relative path. + */ + private String getRelativePath(File grammarFile) { + // the library directory does not allow sub-directories + if (grammarFile.getPath().startsWith(libDirectory.getPath())) + return grammarFile.getName(); + + // if a package is given, we have to use it + if (packageName != null) + return packageName + grammarFile.getName(); + + // otherwise resolve the path relative to the source directory + String path = MojoUtils.findSourceSubdir(sourceDirectory, grammarFile); + + return path + grammarFile.getName(); + } + + /** + * Returns the grammar file names that directly or indirectly use the given grammar. + * + * @param grammarFileName the grammar file name. + * + * @return the grammar file names that use the given grammar file. + */ + private Collection<String> findUsages(String grammarFileName) { + Collection<String> result = new ArrayList<String>(); + explore(grammarFileName, result); + + return result; + } + + private void explore(String grammarName, Collection<String> result) { + for (Graph.Node<String> node : graph.getNode(grammarName).edges) { + result.add(node.payload); + explore(node.payload, result); + } + } + + private void analyse(File grammarFile, Collection<File> grammarFiles, Tool tool) { + GrammarRootAST grammar = tool.parseGrammar(grammarFile.getAbsolutePath()); + + if (grammar == null) + return; + + for (GrammarAST importDecl : grammar.getAllChildrenWithType(ANTLRParser.IMPORT)) { + Tree id = importDecl.getFirstChildWithType(ANTLRParser.ID); + + // missing id is not valid, but we don't want to prevent the root cause from + // being reported by the ANTLR tool + if (id != null) { + String grammarPath = getRelativePath(grammarFile); + + graph.addEdge(id.getText() + ".g4", grammarPath); + } + } + + for (GrammarAST options : grammar.getAllChildrenWithType(ANTLRParser.OPTIONS)) { + for (int i = 0, count = options.getChildCount(); i < count; i++) { + Tree option = options.getChild(i); + + if (option.getType() == ANTLRParser.ASSIGN) { + String key = option.getChild(0).getText(); + String value = option.getChild(1).getText(); + + if ("tokenVocab".equals(key)) { + String name = stripQuotes(value); + // the grammar name may be qualified, but we resolve the path anyway + String grammarName = stripPath(name); + String grammarPath = MojoUtils.findSourceSubdir(sourceDirectory, + grammarFile); + File depGrammarFile = resolve(grammarName, grammarPath); + + // if a package has been given, we use it instead of the file directory path + // (files probably reside in the root directory anyway with such a configuration ) + if (packageName != null) + grammarPath = packageName; + + graph.addEdge(getRelativePath(depGrammarFile), + grammarPath + grammarFile.getName()); + } + } + } + } + } + + /** + * Resolves the given grammar name. + * + * @param name the name. + * @param path the relative path. + * + * @return the grammar file. + */ + private File resolve(String name, String path) { + File file = new File(sourceDirectory, path + name + ".g4"); + + if (file.exists()) + return file; + + file = new File(libDirectory, name + ".g4"); + + if (file.exists()) + return file; + + return new File(libDirectory, name + ".tokens"); + } + + private Map<File, Map.Entry<byte[], Collection<String>>> loadStatus(File statusFile) { + if (statusFile.exists()) { + log.debug("Load grammars dependency status: " + statusFile); + + try { + ObjectInputStream in = new ObjectInputStream(new FileInputStream( + statusFile)); + + try { + @SuppressWarnings("unchecked") + Map<File, Map.Entry<byte[], Collection<String>>> data = + (Map<File, Map.Entry<byte[], Collection<String>>>) + in.readObject(); + + return data; + } finally { + in.close(); + } + } catch (Exception ex) { + log.warn("Could not load grammar dependency status information", ex); + } + } + + return new HashMap<File, Map.Entry<byte[], Collection<String>>>(); + } + + private String stripPath(String str) { + return str.replaceAll("^.*[/\\\\]", ""); + } + + private String stripQuotes(String str) { + return str.replaceAll("\\A'|'\\Z", ""); + } +} diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/MojoUtils.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/MojoUtils.java new file mode 100644 index 0000000..56da59b --- /dev/null +++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/MojoUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ + +package org.antlr.mojo.antlr4; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + + +class MojoUtils { + /** + * Creates the MD5 checksum for the given file. + * + * @param file the file. + * + * @return the checksum. + */ + public static byte[] checksum(File file) throws IOException { + try { + InputStream in = new FileInputStream(file); + byte[] buffer = new byte[2048]; + MessageDigest complete = MessageDigest.getInstance("MD5"); + + try { + int n; + + do { + n = in.read(buffer); + + if (n > 0) { + complete.update(buffer, 0, n); + } + } while (n != -1); + } finally { + in.close(); + } + + return complete.digest(); + } catch (NoSuchAlgorithmException ex) { + throw new IOException("Could not create checksum " + file, ex); + } + } + + /** + * Given the source directory File object and the full PATH to a grammar, produce the + * path to the named grammar file in relative terms to the {@code sourceDirectory}. + * This will then allow ANTLR to produce output relative to the base of the output + * directory and reflect the input organization of the grammar files. + * + * @param sourceDirectory The source directory {@link File} object + * @param grammarFileName The full path to the input grammar file + * + * @return The path to the grammar file relative to the source directory + */ + public static String findSourceSubdir(File sourceDirectory, File grammarFile) { + String srcPath = sourceDirectory.getPath() + File.separator; + String path = grammarFile.getPath(); + + if (!path.startsWith(srcPath)) { + throw new IllegalArgumentException("expected " + path + + " to be prefixed with " + sourceDirectory); + } + + File unprefixedGrammarFileName = new File(path.substring(srcPath.length())); + + if (unprefixedGrammarFileName.getParent() == null) { + return ""; + } + + return unprefixedGrammarFileName.getParent() + File.separator; + } +} diff --git a/antlr4-maven-plugin/src/site/site.xml b/antlr4-maven-plugin/src/site/site.xml index 0cf1aa2..23cd29c 100644 --- a/antlr4-maven-plugin/src/site/site.xml +++ b/antlr4-maven-plugin/src/site/site.xml @@ -1,5 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + <project name="ANTLR v4 Maven plugin"> <publishDate position="left"/> @@ -7,7 +13,7 @@ <poweredBy> <logo name="ANTLR Web Site" href="http://antlr.org/" - img="http://www.antlr.org/wiki/download/attachments/292/ANTLR4"/> + img="http://www.antlr.org/images/antlr-logo.png"/> </poweredBy> <body> diff --git a/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java b/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java new file mode 100644 index 0000000..12c45cd --- /dev/null +++ b/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ + +package org.antlr.mojo.antlr4; + +import io.takari.maven.testing.TestMavenRuntime; +import io.takari.maven.testing.TestResources; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + + +public class Antlr4MojoTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public final TestResources resources = new TestResources(); + + @Rule + public final TestMavenRuntime maven = new TestMavenRuntime(); + + @Test + public void importTokens() throws Exception { + Path baseDir = resources.getBasedir("importTokens").toPath(); + Path antlrDir = baseDir.resolve("src/main/antlr4"); + Path generatedSources = baseDir.resolve("target/generated-sources/antlr4"); + + Path genParser = generatedSources.resolve("test/SimpleParser.java"); + Path tokens = antlrDir.resolve("imports/SimpleLexer.tokens"); + + MavenProject project = maven.readMavenProject(baseDir.toFile()); + MavenSession session = maven.newMavenSession(project); + MojoExecution exec = maven.newMojoExecution("antlr4"); + + //////////////////////////////////////////////////////////////////////// + // 1st - all grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + assertFalse(Files.exists(genParser)); + + maven.executeMojo(session, project, exec); + + assertTrue(Files.exists(genParser)); + + //////////////////////////////////////////////////////////////////////// + // 2nd - nothing has been modified, no grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + { + byte[] sum = checksum(genParser); + + maven.executeMojo(session, project, exec); + + assertTrue(Arrays.equals(sum, checksum(genParser))); + } + + //////////////////////////////////////////////////////////////////////// + // 3rd - the imported grammar changed, every dependency has to be processed + //////////////////////////////////////////////////////////////////////// + + try(Change change = Change.of(tokens, "DOT=4")) { + byte[] sum = checksum(genParser); + + maven.executeMojo(session, project, exec); + + assertFalse(Arrays.equals(sum, checksum(genParser))); + } + } + + @Test + public void importsCustomLayout() throws Exception { + Path baseDir = resources.getBasedir("importsCustom").toPath(); + Path antlrDir = baseDir.resolve("src/main/antlr4"); + Path generatedSources = baseDir.resolve("src/main/java"); + + Path genTestLexer = generatedSources.resolve("foo/TestLexer.java"); + Path genTestParser = generatedSources.resolve("foo/TestParser.java"); + Path genHello = generatedSources.resolve("foo/HelloParser.java"); + + Path baseGrammar = antlrDir.resolve("imports/TestBaseLexer.g4"); + Path lexerGrammar = antlrDir.resolve("TestLexer.g4"); + Path parserGrammar = antlrDir.resolve("TestParser.g4"); + + Xpp3Dom outputDirectory = TestMavenRuntime.newParameter("outputDirectory", + "src/main/java/foo"); + Xpp3Dom arguments = new Xpp3Dom("arguments"); + arguments.addChild(TestMavenRuntime.newParameter("argument", "-package")); + arguments.addChild(TestMavenRuntime.newParameter("argument", "foo")); + + MavenProject project = maven.readMavenProject(baseDir.toFile()); + MavenSession session = maven.newMavenSession(project); + MojoExecution exec = maven.newMojoExecution("antlr4", outputDirectory, arguments); + + //////////////////////////////////////////////////////////////////////// + // 1st - all grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + assertFalse(Files.exists(genHello)); + assertFalse(Files.exists(genTestParser)); + assertFalse(Files.exists(genTestLexer)); + + maven.executeMojo(session, project, exec); + + assertTrue(Files.exists(genHello)); + assertTrue(Files.exists(genTestParser)); + assertTrue(Files.exists(genTestLexer)); + + //////////////////////////////////////////////////////////////////////// + // 2nd - nothing has been modified, no grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertTrue(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 3rd - the imported grammar changed, every dependency has to be processed + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(baseGrammar, "DOT: '.' ;")) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 4th - the lexer grammar changed, the parser grammar has to be processed as well + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(lexerGrammar, "fragment DOT : '.';")) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 5th - the parser grammar changed, no other grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(parserGrammar, " t : WS* ;")) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + } + + @Test + public void importsStandardLayout() throws Exception { + Path baseDir = resources.getBasedir("importsStandard").toPath(); + Path antlrDir = baseDir.resolve("src/main/antlr4"); + Path generatedSources = baseDir.resolve("target/generated-sources/antlr4"); + + Path genTestLexer = generatedSources.resolve("test/TestLexer.java"); + Path genTestParser = generatedSources.resolve("test/TestParser.java"); + Path genHello = generatedSources.resolve("test/HelloParser.java"); + + Path baseGrammar = antlrDir.resolve("imports/TestBaseLexer.g4"); + Path lexerGrammar = antlrDir.resolve("test/TestLexer.g4"); + Path parserGrammar = antlrDir.resolve("test/TestParser.g4"); + + MavenProject project = maven.readMavenProject(baseDir.toFile()); + MavenSession session = maven.newMavenSession(project); + MojoExecution exec = maven.newMojoExecution("antlr4"); + + //////////////////////////////////////////////////////////////////////// + // 1st - all grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + assertFalse(Files.exists(genHello)); + assertFalse(Files.exists(genTestParser)); + assertFalse(Files.exists(genTestLexer)); + + maven.executeMojo(session, project, exec); + + assertTrue(Files.exists(genHello)); + assertTrue(Files.exists(genTestParser)); + assertTrue(Files.exists(genTestLexer)); + + //////////////////////////////////////////////////////////////////////// + // 2nd - nothing has been modified, no grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertTrue(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 3rd - the imported grammar changed, every dependency has to be processed + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(baseGrammar, "DOT: '.' ;")) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 4th - the lexer grammar changed, the parser grammar has to be processed as well + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(lexerGrammar)) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + + //////////////////////////////////////////////////////////////////////// + // 5th - the parser grammar changed, no other grammars have to be processed + //////////////////////////////////////////////////////////////////////// + + // modify the grammar to make checksum comparison detect a change + try(Change change = Change.of(parserGrammar, " t : WS* ;")) { + byte[] testLexerSum = checksum(genTestLexer); + byte[] testParserSum = checksum(genTestParser); + byte[] helloSum = checksum(genHello); + + maven.executeMojo(session, project, exec); + + assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer))); + assertFalse(Arrays.equals(testParserSum, checksum(genTestParser))); + assertTrue(Arrays.equals(helloSum, checksum(genHello))); + } + } + + @Test + public void processWhenDependencyRemoved() throws Exception { + Path baseDir = resources.getBasedir("dependencyRemoved").toPath(); + Path antlrDir = baseDir.resolve("src/main/antlr4"); + + Path baseGrammar = antlrDir.resolve("imports/HelloBase.g4"); + + MavenProject project = maven.readMavenProject(baseDir.toFile()); + MavenSession session = maven.newMavenSession(project); + MojoExecution exec = maven.newMojoExecution("antlr4"); + + maven.executeMojo(session, project, exec); + + try(Change temp = Change.of(baseGrammar)) { + // if the base grammar no longer exists, processing must be performed + Files.delete(baseGrammar); + + thrown.expect(MojoExecutionException.class); + thrown.expectMessage("ANTLR 4 caught 1 build errors."); + + maven.executeMojo(session, project, exec); + } + } + + private byte[] checksum(Path path) throws IOException { + return MojoUtils.checksum(path.toFile()); + } + + private static class Change implements AutoCloseable { + final Path file; + final byte[] original; + + public Change(Path file, String change) { + this.file = file; + + try { + original = Files.readAllBytes(file); + } catch (IOException ex) { + throw new RuntimeException("Could not read file " + file); + } + + String text = new String(original, StandardCharsets.UTF_8) + change; + + write(file, text.getBytes(StandardCharsets.UTF_8)); + } + + private void write(Path file, byte[] data) { + try { + Files.write(file, data); + } catch (IOException ex) { + throw new RuntimeException("Could not write file " + file); + } + } + + public static Change of(Path file, String change) { + return new Change(file, change); + } + + public static Change of(Path file) { + return new Change(file, "\n"); + } + + @Override + public void close() { + write(file, original); + } + } +} diff --git a/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml new file mode 100644 index 0000000..3163b81 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml @@ -0,0 +1,33 @@ +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>deps.removed</groupId> + <artifactId>depRemoved</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + <name>Test processing after dependency removed</name> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>antlr4-maven-plugin</artifactId> + <configuration> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/imports/HelloBase.g4 b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/imports/HelloBase.g4 new file mode 100644 index 0000000..5fcc6d3 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/imports/HelloBase.g4 @@ -0,0 +1,16 @@ +lexer grammar TestBaseLexer; + +tokens { Name } + +// Default "mode": Everything OUTSIDE of a tag +Comment : '<!--' .*? '-->' ; +CDSect : '<![CDATA[' .*? ']]>' ; + +fragment +Whitespace : ' ' | '\n' | '\t' | '\r' ; + +fragment +Hexdigit : [a-fA-F0-9] ; + +fragment +Digit : [0-9] ; diff --git a/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/test/Hello.g4 b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/test/Hello.g4 new file mode 100644 index 0000000..54f998c --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/src/main/antlr4/test/Hello.g4 @@ -0,0 +1,7 @@ +grammar Hello; + +import HelloBase; + +r : 'hello' ID ; +ID : [a-z]+ ; +WS : [ \r\t\n]+ -> skip ; diff --git a/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml b/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml new file mode 100644 index 0000000..478b517 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml @@ -0,0 +1,33 @@ +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>import.tokens</groupId> + <artifactId>importTokens</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + <name>Test importing tokens file</name> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>antlr4-maven-plugin</artifactId> + <configuration> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/imports/SimpleLexer.tokens b/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/imports/SimpleLexer.tokens new file mode 100644 index 0000000..4637d6e --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/imports/SimpleLexer.tokens @@ -0,0 +1,3 @@ +ID=1 +INT=2 +SEMI=3 diff --git a/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/test/SimpleParser.g4 b/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/test/SimpleParser.g4 new file mode 100644 index 0000000..bbd8274 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importTokens/src/main/antlr4/test/SimpleParser.g4 @@ -0,0 +1,8 @@ +parser grammar SimpleParser; +options { + // get token types from SimpleLexer.tokens; don't name it + // SimpleParser.tokens as ANTLR will overwrite! + tokenVocab=SimpleLexer; +} + +s : ( ID | INT )* SEMI ; diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml b/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml new file mode 100644 index 0000000..a5826bc --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml @@ -0,0 +1,48 @@ +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>imports.custom</groupId> + <artifactId>importsCustom</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + <name>Test importing, custom layout</name> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>antlr4-maven-plugin</artifactId> + <configuration> + <outputDirectory>${basedir}/src/main/java/com/foo</outputDirectory> + <arguments> + <argument>-visitor</argument> + <argument>-no-listener</argument> + <argument>-Xlog</argument> + <argument>-package</argument> + <argument>com.foo</argument> + </arguments> + </configuration> + <executions> + <execution> + <goals> + <goal>antlr4</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/Hello.g4 b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/Hello.g4 new file mode 100644 index 0000000..e38ac87 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/Hello.g4 @@ -0,0 +1,4 @@ +grammar Hello; +r : 'hello' ID ; +ID : [a-z]+ ; +WS : [ \r\t\n]+ -> skip ;
\ No newline at end of file diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestLexer.g4 new file mode 100644 index 0000000..668b764 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestLexer.g4 @@ -0,0 +1,6 @@ +lexer grammar TestLexer; + +import TestBaseLexer; + +WS : Whitespace+ -> skip; +TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
\ No newline at end of file diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestParser.g4 b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestParser.g4 new file mode 100644 index 0000000..5c25961 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/TestParser.g4 @@ -0,0 +1,5 @@ +parser grammar TestParser; + +options { tokenVocab=TestLexer; } + +document : (Comment | Name) EOF ;
\ No newline at end of file diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/imports/TestBaseLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/imports/TestBaseLexer.g4 new file mode 100644 index 0000000..5fcc6d3 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsCustom/src/main/antlr4/imports/TestBaseLexer.g4 @@ -0,0 +1,16 @@ +lexer grammar TestBaseLexer; + +tokens { Name } + +// Default "mode": Everything OUTSIDE of a tag +Comment : '<!--' .*? '-->' ; +CDSect : '<![CDATA[' .*? ']]>' ; + +fragment +Whitespace : ' ' | '\n' | '\t' | '\r' ; + +fragment +Hexdigit : [a-fA-F0-9] ; + +fragment +Digit : [0-9] ; diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml b/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml new file mode 100644 index 0000000..77f63a2 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml @@ -0,0 +1,33 @@ +<!-- + ~ Copyright (c) 2012-2016 The ANTLR Project. All rights reserved. + ~ Use of this file is governed by the BSD 3-clause license that + ~ can be found in the LICENSE.txt file in the project root. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>imports.standard</groupId> + <artifactId>importsStandard</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + <name>Test importing, standard layout</name> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>antlr4-maven-plugin</artifactId> + <configuration> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4 new file mode 100644 index 0000000..5fcc6d3 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4 @@ -0,0 +1,16 @@ +lexer grammar TestBaseLexer; + +tokens { Name } + +// Default "mode": Everything OUTSIDE of a tag +Comment : '<!--' .*? '-->' ; +CDSect : '<![CDATA[' .*? ']]>' ; + +fragment +Whitespace : ' ' | '\n' | '\t' | '\r' ; + +fragment +Hexdigit : [a-fA-F0-9] ; + +fragment +Digit : [0-9] ; diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/Hello.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/Hello.g4 new file mode 100644 index 0000000..e38ac87 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/Hello.g4 @@ -0,0 +1,4 @@ +grammar Hello; +r : 'hello' ID ; +ID : [a-z]+ ; +WS : [ \r\t\n]+ -> skip ;
\ No newline at end of file diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4 new file mode 100644 index 0000000..668b764 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4 @@ -0,0 +1,6 @@ +lexer grammar TestLexer; + +import TestBaseLexer; + +WS : Whitespace+ -> skip; +TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
\ No newline at end of file diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestParser.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestParser.g4 new file mode 100644 index 0000000..5c25961 --- /dev/null +++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestParser.g4 @@ -0,0 +1,5 @@ +parser grammar TestParser; + +options { tokenVocab=TestLexer; } + +document : (Comment | Name) EOF ;
\ No newline at end of file |