Skip to content

Commit

Permalink
Merge pull request #22 from gilcesarf/master
Browse files Browse the repository at this point in the history
Fix for issues #20 and #21
  • Loading branch information
teverett authored Apr 23, 2020
2 parents 2bef8a4 + 7f5c529 commit 3615984
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 51 deletions.
90 changes: 71 additions & 19 deletions src/main/java/com/khubla/antlr/antlr4test/GrammarTestMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,19 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
*/
package com.khubla.antlr.antlr4test;

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.charset.*;
import java.util.*;

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import org.apache.maven.plugin.*;
import org.apache.maven.plugins.annotations.*;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.bitbucket.cowwoc.diffmatchpatch.*;
import org.codehaus.plexus.util.*;

/**
* @author Tom Everett
Expand Down Expand Up @@ -89,7 +88,7 @@ public class GrammarTestMojo extends AbstractMojo {
* example files
*/
@Parameter(defaultValue = "/src/test/resources/examples")
private String exampleFiles;
private String exampleFiles = "/src/test/resources/examples";
/**
* packageName
*/
Expand All @@ -108,7 +107,7 @@ public class GrammarTestMojo extends AbstractMojo {
* file encoding
*/
@Parameter(defaultValue = "UTF-8")
private String fileEncoding;
private String fileEncoding = "UTF-8";

/**
* Full qualified class name to initialize grammar (Lexer and/or Parser) before
Expand All @@ -123,6 +122,14 @@ public class GrammarTestMojo extends AbstractMojo {
@Parameter
private List<Scenario> scenarios = null;

/* read outputDirectory from pom project.build.outputDirectory */
@Parameter(defaultValue = "${project.build.outputDirectory}", readonly = true)
private String outputDirectory = "/target/classes";

/* read testOutputDirectory from pom project.build.testOutputDirectory */
@Parameter(defaultValue = "${project.build.testOutputDirectory}", readonly = true)
private String testOutputDirectory = "/target/test-classes";

/**
* ctor
*
Expand Down Expand Up @@ -269,15 +276,60 @@ public void setScenarios(List<Scenario> scenarios) {
this.scenarios = scenarios;
}

public String getGrammarInitializer() {
return grammarInitializer;
}

public void setGrammarInitializer(String grammarInitializer) {
this.grammarInitializer = grammarInitializer;
}

public String getOutputDirectory() {
return outputDirectory;
}

public void setOutputDirectory(String outputDirectory) {
this.outputDirectory = outputDirectory;
}

public String getTestOutputDirectory() {
return testOutputDirectory;
}

public void setTestOutputDirectory(String testOutputDirectory) {
this.testOutputDirectory = testOutputDirectory;
}

private void testScenarios() throws Exception {
Log mojoLogger = getLog();
// check if baseDir has been set with some value.
// fix for issue #21
if (baseDir == null) {
// If not, set to the current directory
baseDir = new File(".");
}
for (Scenario scenario : scenarios) {
/*
* drop message
*/
System.out.println("Evaluating Scenario: " + scenario.getScenarioName());
mojoLogger.info("Evaluating Scenario: " + scenario.getScenarioName());
// fix for issue #21
if (scenario.getBaseDir() == null) {
// The base dir does not get its default value
// in Scenario class under certain unknown conditions
// if it is the case, inject the default value from Mojo
scenario.setBaseDir(baseDir);
}
// fix for issue #21
if (scenario.getExampleFiles() == null) {
// The examples dir does not get its default value
// in Scenario class under certain unknown conditions
// if it is the case, inject the default value from Mojo
scenario.setExampleFiles(exampleFiles);
}
if (scenario.isVerbose()) {
System.out.println("baseDir: " + scenario.getBaseDir());
System.out.println("exampleFiles: " + scenario.getExampleFiles());
mojoLogger.info("baseDir: " + scenario.getBaseDir());
mojoLogger.info("exampleFiles: " + scenario.getExampleFiles());
// only check errors if scenario is enabled
// so other scenarios are not prevented of being executed.
if (scenario.isEnabled()) {
Expand All @@ -290,11 +342,11 @@ private void testScenarios() throws Exception {
}
}
if (scenario.isEnabled()) {
ScenarioExecutor executor = new ScenarioExecutor(scenario);
ScenarioExecutor executor = new ScenarioExecutor(this, scenario, mojoLogger);
executor.testGrammars();
executor = null;
} else {
System.out.println("Scenario " + scenario.getScenarioName() + " is disabled. Skipping.");
mojoLogger.warn("Scenario " + scenario.getScenarioName() + " is disabled. Skipping.");
}
}
}
Expand Down
25 changes: 9 additions & 16 deletions src/main/java/com/khubla/antlr/antlr4test/Scenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public class Scenario {
* example files
*/
@Parameter(defaultValue = "/src/test/resources/examples")
private String exampleFiles;
private String exampleFiles = "/src/test/resources/examples";
/**
* packageName
*/
Expand All @@ -95,10 +95,11 @@ public class Scenario {
* file encoding
*/
@Parameter(defaultValue = "UTF-8")
private String fileEncoding;
private String fileEncoding = "UTF-8";

/**
* Full qualified class name to initialize grammar (Lexer and/or Parser) before test starts
* Full qualified class name to initialize grammar (Lexer and/or Parser) before
* test starts
*/
@Parameter
private String grammarInitializer = null;
Expand All @@ -110,7 +111,7 @@ public String getScenarioName() {
public void setScenarioName(String scenarioName) {
this.scenarioName = scenarioName;
}

public String getGrammarName() {
return grammarName;
}
Expand All @@ -126,7 +127,7 @@ public CaseInsensitiveType getCaseInsensitiveType() {
public void setCaseInsensitiveType(CaseInsensitiveType caseInsensitiveType) {
this.caseInsensitiveType = caseInsensitiveType;
}

public String getEntryPoint() {
return entryPoint;
}
Expand Down Expand Up @@ -206,22 +207,14 @@ public String getGrammarInitializer() {
public void setGrammarInitializer(String grammarInitializer) {
this.grammarInitializer = grammarInitializer;
}

/**
* Returns the File pointing to the directory where example files can be found.
*
* @return
*/
public File getExampleFilesDir() {
return new File(getBaseDir() + "/" + getExampleFiles());
}

/**
* get a classloader that can find the files we need
*/
public ClassLoader getClassLoader() throws MalformedURLException, ClassNotFoundException {
final URL antlrGeneratedURL = new File(baseDir + "/target/classes").toURI().toURL();
final URL[] urls = new URL[] { antlrGeneratedURL };
return new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
}


}
64 changes: 51 additions & 13 deletions src/main/java/com/khubla/antlr/antlr4test/ScenarioExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;

import org.antlr.v4.runtime.CharStream;
Expand All @@ -41,15 +45,21 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.Trees;
import org.apache.maven.plugin.logging.Log;
import org.bitbucket.cowwoc.diffmatchpatch.DiffMatchPatch;
import org.codehaus.plexus.util.FileUtils;

public class ScenarioExecutor {

private Scenario scenario = null;
private Log log = null;
private GrammarTestMojo mojo = null;
private HashMap<URL, ClassLoader> classLoaderMap = new HashMap<>();

public ScenarioExecutor(Scenario scenario) {
public ScenarioExecutor(GrammarTestMojo mojo, Scenario scenario, Log log) {
this.mojo = mojo;
this.scenario = scenario;
this.log = log;
}

public void testGrammars() throws Exception {
Expand Down Expand Up @@ -94,29 +104,34 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
final String lexerClassName = nn + "Lexer";
final String parserClassName = nn + "Parser";
if (scenario.isVerbose()) {
System.out.println("Lexer classname is: " + lexerClassName);
System.out.println("Parser classname is: " + parserClassName);
log.info("Lexer classname is: " + lexerClassName);
log.info("Parser classname is: " + parserClassName);
}
/*
* classloader
*/
final ClassLoader classLoader = scenario.getClassLoader();
// create grammarClassLoader as child of current thread's context classloader
final ClassLoader grammarClassLoader = getClassLoader(mojo.getOutputDirectory());
// testClassLoader should be grammarClassLoader's child so test classes can find
// grammar classes
final ClassLoader testClassLoader = getClassLoader(mojo.getTestOutputDirectory(), grammarClassLoader);
/*
* get the classes we need
*/
final Class<? extends Lexer> lexerClass = classLoader.loadClass(lexerClassName).asSubclass(Lexer.class);
final Class<? extends Parser> parserClass = classLoader.loadClass(parserClassName).asSubclass(Parser.class);
final Class<? extends Lexer> lexerClass = grammarClassLoader.loadClass(lexerClassName).asSubclass(Lexer.class);
final Class<? extends Parser> parserClass = grammarClassLoader.loadClass(parserClassName)
.asSubclass(Parser.class);
Class<? extends GrammarInitializer> initializerClass = null;
String grammarInitializer = scenario.getGrammarInitializer();
if (grammarInitializer != null && !"".equals(grammarInitializer)) {
initializerClass = classLoader.loadClass(grammarInitializer).asSubclass(GrammarInitializer.class);
initializerClass = testClassLoader.loadClass(grammarInitializer).asSubclass(GrammarInitializer.class);
}
/*
* get ctors
*/
final Constructor<?> lexerConstructor = lexerClass.getConstructor(CharStream.class);
final Constructor<?> parserConstructor = parserClass.getConstructor(TokenStream.class);
System.out.println("Parsing :" + grammarFile.getAbsolutePath());
log.info("Parsing :" + grammarFile.getAbsolutePath());
CharStream antlrFileStream;
if (scenario.getCaseInsensitiveType() == CaseInsensitiveType.None) {
antlrFileStream = CharStreams.fromPath(grammarFile.toPath(), Charset.forName(scenario.getFileEncoding()));
Expand Down Expand Up @@ -144,7 +159,7 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
* initializer lexer and parser
*/
if (initializerClass != null) {
System.out.println(initializerClass.getName());
log.info(initializerClass.getName());
GrammarInitializer initializer = (GrammarInitializer) initializerClass.newInstance();
initializer.initialize(lexer, parser);
}
Expand All @@ -154,8 +169,9 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
*/
if (scenario.isVerbose()) {
tokens.fill();
log.info("Token List: ");
for (final Object tok : tokens.getTokens()) {
System.out.println(tok);
log.info(tok.toString());
}
}

Expand All @@ -168,7 +184,8 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
*/
if (scenario.isShowTree()) {
final String lispTree = Trees.toStringTree(parserRuleContext, parser);
System.out.println(lispTree);
log.info("Parsed Tree: ");
log.info(lispTree);
}
/*
* check syntax
Expand All @@ -188,8 +205,7 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
}
throw new Exception(sb.toString());
} else {
System.out.println(
"Parse tree for '" + grammarFile.getName() + "' matches '" + treeFile.getName() + "'");
log.info("Parse tree for '" + grammarFile.getName() + "' matches '" + treeFile.getName() + "'");
}
}
}
Expand All @@ -203,4 +219,26 @@ private void testGrammar(Scenario scenario, File grammarFile) throws Exception {
antlrFileStream = null;
}

/**
* build a classloader that can find the files we need
*/
private ClassLoader getClassLoader(String path, ClassLoader parent)
throws MalformedURLException, ClassNotFoundException {
final URL antlrGeneratedURL = new File(path).toURI().toURL();
// check if classloader for this URL was already created.
ClassLoader ret = classLoaderMap.get(antlrGeneratedURL);
if (ret == null) {
// if not, create a new one and cache it to avoid recreating.
final URL[] urls = new URL[] { antlrGeneratedURL };
ret = new URLClassLoader(urls, parent);
classLoaderMap.put(antlrGeneratedURL, ret);
}
return ret;
}

private ClassLoader getClassLoader(String path)
throws MalformedURLException, ClassNotFoundException {
// create a classloader child of Thread.currentThread().getContextClassLoader().
return getClassLoader(path, Thread.currentThread().getContextClassLoader());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,7 @@ public void testGrammarInitializer() throws Exception {
grammarTestMojo.setBaseDir(new File(getAbsolutePath("../..")).getCanonicalFile());
grammarTestMojo.setFileEncoding("UTF-8");
grammarTestMojo.execute();



} catch (final Exception e) {
e.printStackTrace();
Assert.fail("Unexpected exception " + e);
Expand Down Expand Up @@ -214,7 +213,9 @@ public void testScenarioConfiguration() throws Exception {
assertEquals(5, scenarios.size());
HashMap<String, Scenario> scenarioMap = new HashMap<>();
for (Scenario scenario : scenarios) {
scenario.setBaseDir(new File(getAbsolutePath("../..")).getCanonicalFile());
// commented to simulate conditions described in issue #21 to replicate the issue
// https://github.com/antlr/antlr4test-maven-plugin/issues/21
// scenario.setBaseDir(new File(getAbsolutePath("../..")).getCanonicalFile());
scenario.setFileEncoding("UTF-8");
scenarioMap.put(scenario.getScenarioName(), scenario);
}
Expand Down

0 comments on commit 3615984

Please sign in to comment.