From 9074eeb877c8098953f3ff000bf5395362b3cbbe Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Tue, 5 May 2020 09:01:26 +0200 Subject: [PATCH] add the option to make the compiler JastAdd-compliant (i.e., support all JastAdd arguments) --- build.gradle | 4 +- .../org/jastadd/JastAddConfiguration.java | 147 ++++++++++++++++++ .../relast/compiler/AbstractCompiler.java | 68 ++++++++ .../relast/compiler/CompilerException.java | 11 ++ ...java => RelastSourceToSourceCompiler.java} | 62 ++------ .../org/jastadd/ros2rag/tests/RelAstTest.java | 12 +- 6 files changed, 249 insertions(+), 55 deletions(-) create mode 100644 src/main/java/org/jastadd/JastAddConfiguration.java create mode 100644 src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java create mode 100644 src/main/java/org/jastadd/relast/compiler/CompilerException.java rename src/main/java/org/jastadd/relast/compiler/{Compiler.java => RelastSourceToSourceCompiler.java} (72%) diff --git a/build.gradle b/build.gradle index aff97ea..86a6d5b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ apply plugin: "idea" sourceCompatibility = 1.8 -mainClassName = 'org.jastadd.relast.compiler.Compiler' +mainClassName = 'org.jastadd.relast.compiler.JastAddExtensionCompiler' repositories { jcenter() @@ -45,7 +45,7 @@ test { jar { manifest { - attributes "Main-Class": 'org.jastadd.relast.compiler.Compiler' + attributes "Main-Class": 'org.jastadd.relast.compiler.JastAddExtensionCompiler' } from { diff --git a/src/main/java/org/jastadd/JastAddConfiguration.java b/src/main/java/org/jastadd/JastAddConfiguration.java new file mode 100644 index 0000000..0620a16 --- /dev/null +++ b/src/main/java/org/jastadd/JastAddConfiguration.java @@ -0,0 +1,147 @@ +/* Copyright (c) 2013-2015, Jesper Öqvist <jesper.oqvist@cs.lth.se> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Lund University nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. + */ +package org.jastadd; + +import org.jastadd.option.ArgumentParser; +import org.jastadd.option.Option; + +import java.io.PrintStream; +import java.util.Collection; +import java.util.LinkedList; + +/** + * Tracks JastAdd configuration options. + * + * @author Jesper Öqvist <jesper.oqvist@cs.lth.se> + */ +public class JastAddConfiguration extends org.jastadd.Configuration { + + /** + * Indicates if there were unknown command-line options + */ + final boolean unknownOptions; + + /** + * Parse options from an argument list. + * + * @param args Command-line arguments to build configuration from + * @param err output stream to print configuration warnings to + */ + public JastAddConfiguration(String[] args, PrintStream err, Collection<Option<?>> extraOptions) { + ArgumentParser argParser = new ArgumentParser(); + argParser.addOptions(allJastAddOptions()); + argParser.addOptions(extraOptions); + unknownOptions = !argParser.parseArgs(args, err); + filenames = argParser.getFilenames(); + } + + private Collection<Option<?>> allJastAddOptions() { + Collection<Option<?>> allOptions = new LinkedList<Option<?>>(); + allOptions.add(ASTNodeOption); + allOptions.add(ListOption); + allOptions.add(OptOption); + allOptions.add(jjtreeOption); + allOptions.add(grammarOption); + allOptions.add(generateAnnotations); + allOptions.add(defaultMapOption); + allOptions.add(defaultSetOption); + allOptions.add(lazyMapsOption); + allOptions.add(privateOption); + allOptions.add(rewriteOption); + allOptions.add(beaverOption); + allOptions.add(lineColumnNumbersOption); + allOptions.add(visitCheckOption); + allOptions.add(traceVisitCheckOption); + allOptions.add(cacheCycleOption); + allOptions.add(componentCheckOption); + allOptions.add(inhEqCheckOption); + allOptions.add(suppressWarningsOption); + allOptions.add(refineLegacyOption); + allOptions.add(licenseOption); + allOptions.add(debugOption); + allOptions.add(outputDirOption); + allOptions.add(staticStateOption); + allOptions.add(tracingOption); + allOptions.add(flushOption); + allOptions.add(packageNameOption); + allOptions.add(versionOption); + allOptions.add(helpOption); + allOptions.add(printNonStandardOptionsOption); + allOptions.add(indentOption); + allOptions.add(minListSizeOption); + allOptions.add(cacheOption); + allOptions.add(incrementalOption); + + // New since 2.1.11. + allOptions.add(dotOption); + allOptions.add(ASTNodeSuperOption); + allOptions.add(generateImplicitsOption); + + // New since 2.1.12. + allOptions.add(stateClassNameOption); + + // New since 2.2.1: + allOptions.add(safeLazyOption); + + // New since 2.2.3: + allOptions.add(statisticsOption); + + // New since 2.2.4: + allOptions.add(emptyContainerSingletons); + allOptions.add(concurrentOption); + allOptions.add(numThreadsOption); + allOptions.add(concurrentMap); + + // New since 2.3.4 + allOptions.add(optimizeImports); + + // Deprecated in 2.1.5. + allOptions.add(doxygenOption); + allOptions.add(cacheAllOption); + allOptions.add(noCachingOption); + allOptions.add(cacheNoneOption); + allOptions.add(cacheImplicitOption); + allOptions.add(ignoreLazyOption); + allOptions.add(fullFlushOption); + + // Deprecated in 2.1.9. + allOptions.add(docOption); + allOptions.add(java1_4Option); // Disabled in 2.1.10. + allOptions.add(noLazyMapsOption); + allOptions.add(noVisitCheckOption); + allOptions.add(noCacheCycleOption); + allOptions.add(noRefineLegacyOption); + allOptions.add(noComponentCheckOption); + allOptions.add(noInhEqCheckOption); + allOptions.add(noStaticOption); + allOptions.add(deterministicOption); + + return allOptions; + } + +} diff --git a/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java b/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java new file mode 100644 index 0000000..cb4a839 --- /dev/null +++ b/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java @@ -0,0 +1,68 @@ +package org.jastadd.relast.compiler; + +import org.jastadd.JastAddConfiguration; +import org.jastadd.option.ArgumentParser; +import org.jastadd.option.Option; + +import java.util.ArrayList; + +public abstract class AbstractCompiler { + + private final boolean jastAddCompliant; + protected ArrayList<Option<?>> options; + private String name; + private ArgumentParser commandLine; + + private JastAddConfiguration configuration; + + public AbstractCompiler(String name, boolean jastaddCompliant) { + this.name = name; + this.jastAddCompliant = jastaddCompliant; + } + + public JastAddConfiguration getConfiguration() throws CompilerException { + if (configuration == null) { + throw new CompilerException("Configuration only supported for JastAdd-compliant compilers!"); + } + return configuration; + } + + public int run(String[] args) throws CompilerException { + + options = new ArrayList<>(); + initOptions(); + if (jastAddCompliant) { + configuration = new JastAddConfiguration(args, System.err, options); + } else { + commandLine = new ArgumentParser(); + commandLine.addOptions(options); + commandLine.parseArgs(args, System.err); + } + return compile(); + } + + abstract int compile() throws CompilerException; + + protected void initOptions() { + // there are no options by default + } + + protected <OptionType extends Option<?>> OptionType addOption(OptionType option) { + options.add(option); + return option; + } + + protected int error(String message) { + System.err.println("Error: " + message); + System.err.println(); + System.err.println("Usage: java -jar " + name + ".jar [--option1] [--option2=value] ... <filename1> <filename2> ... "); + System.err.println("Options:"); + commandLine.printHelp(System.err); + return 1; + } + + public String getName() { + return name; + } +} + diff --git a/src/main/java/org/jastadd/relast/compiler/CompilerException.java b/src/main/java/org/jastadd/relast/compiler/CompilerException.java new file mode 100644 index 0000000..6949c30 --- /dev/null +++ b/src/main/java/org/jastadd/relast/compiler/CompilerException.java @@ -0,0 +1,11 @@ +package org.jastadd.relast.compiler; + +public class CompilerException extends Exception { + public CompilerException(String message, Throwable cause) { + super(message, cause); + } + + public CompilerException(String message) { + super(message); + } +} diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java similarity index 72% rename from src/main/java/org/jastadd/relast/compiler/Compiler.java rename to src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java index 4f82148..e8f86a0 100644 --- a/src/main/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java @@ -1,8 +1,6 @@ package org.jastadd.relast.compiler; import beaver.Parser; -import org.jastadd.option.ArgumentParser; -import org.jastadd.option.Option; import org.jastadd.option.ValueOption; import org.jastadd.relast.ast.GrammarFile; import org.jastadd.relast.ast.Program; @@ -16,37 +14,34 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -public class Compiler { +public class RelastSourceToSourceCompiler extends AbstractCompiler { - private ValueOption optionOutputDir; - private ValueOption optionInputDir; - private ArrayList<Option<?>> options; - private ArgumentParser commandLine; + protected ValueOption optionOutputDir; + protected ValueOption optionInputDir; - public Compiler() { - options = new ArrayList<>(); - addOptions(); + public RelastSourceToSourceCompiler(String name, boolean jastAddCompliant) { + super(name, jastAddCompliant); } public static void main(String[] args) { try { - new Compiler().run(args); + new RelastSourceToSourceCompiler("relast-preprocessor", true).run(args); } catch (CompilerException e) { System.err.println(e.getMessage()); System.exit(-1); } } - public int run(String[] args) throws CompilerException { - options = new ArrayList<>(); - addOptions(); - commandLine = new ArgumentParser(); - commandLine.addOptions(options); - boolean unknownOptions = !commandLine.parseArgs(args, System.err); + @Override + protected void initOptions() { + optionOutputDir = addOption(new ValueOption("outputDir", "target directory for the generated files.")); + optionInputDir = addOption(new ValueOption("inputDir", "input directory.")); + } + @Override + protected int compile() throws CompilerException { Path inputPath; if (optionInputDir.isMatched()) { inputPath = Paths.get(optionInputDir.value()); @@ -63,7 +58,7 @@ public class Compiler { System.exit(-1); } - Path outputPath; // should not be used, but otherwise there is a compiler warning + Path outputPath; if (optionOutputDir.isMatched()) { outputPath = Paths.get(optionOutputDir.value()); } else { @@ -77,10 +72,6 @@ public class Compiler { printMessage("Running RelAST Preprocessor"); - if (unknownOptions) { - printMessage("Some options were unsupported!"); - } - Program program = parseProgram(inputPath); printMessage("Writing output files"); @@ -108,16 +99,6 @@ public class Compiler { } } - private void addOptions() { - optionOutputDir = addOption(new ValueOption("outputDir", "target directory for the generated files.")); - optionInputDir = addOption(new ValueOption("inputDir", "input directory.")); - } - - private <OptionType extends Option<?>> OptionType addOption(OptionType option) { - options.add(option); - return option; - } - private Program parseProgram(Path inputPath) throws CompilerException { Program program = new Program(); @@ -144,20 +125,5 @@ public class Compiler { return program; } - - protected int error(String message) { - System.err.println("Error: " + message); - System.err.println(); - System.err.println("Usage: java -jar relast.jar [--option1] [--option2=value] ... <filename1> <filename2> ... "); - System.err.println("Options:"); - commandLine.printHelp(System.err); - return 1; - } - - public static class CompilerException extends Exception { - CompilerException(String message, Throwable cause) { - super(message, cause); - } - } } diff --git a/src/test/java/org/jastadd/ros2rag/tests/RelAstTest.java b/src/test/java/org/jastadd/ros2rag/tests/RelAstTest.java index becda3f..fdc383d 100644 --- a/src/test/java/org/jastadd/ros2rag/tests/RelAstTest.java +++ b/src/test/java/org/jastadd/ros2rag/tests/RelAstTest.java @@ -1,6 +1,7 @@ package org.jastadd.ros2rag.tests; -import org.jastadd.relast.compiler.Compiler; +import org.jastadd.relast.compiler.CompilerException; +import org.jastadd.relast.compiler.RelastSourceToSourceCompiler; import org.junit.jupiter.api.Test; import java.io.File; @@ -11,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class RelAstTest { - void transform(String inputDir, String outputDir) throws Compiler.CompilerException { + void transform(boolean jastAddCompliant, String inputDir, String outputDir) throws CompilerException { System.out.println("Running test in directory '" + Paths.get(".").toAbsolutePath() + "'."); assertTrue(Paths.get(inputDir).toFile().exists(), "input directory does not exist"); @@ -32,11 +33,12 @@ public class RelAstTest { "--inputDir=" + inputDir }; - new Compiler().run(args); + new RelastSourceToSourceCompiler("testCompiler", jastAddCompliant).run(args); } @Test - void transformMinimalExample() throws Compiler.CompilerException { - transform("src/test/resources/in", "src/test/resources/out"); + void transformMinimalExample() throws CompilerException { + transform(false,"src/test/resources/in", "src/test/resources/out"); + transform(true,"src/test/resources/in", "src/test/resources/out"); } } -- GitLab