diff --git a/.gitmodules b/.gitmodules index 0163ef86549d9ee0ba792961799f705881d1f893..58efd108e858ae06dde5f626286bd3d73f9dde4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,4 @@ [submodule "relast-preprocessor"] path = relast-preprocessor url = ../relast-preprocessor.git - branch = jastadd-fix-inc-param-debug -[submodule "ragconnect.base/src/main/jastadd/mustache"] - path = ragconnect.base/src/main/jastadd/mustache - url = ../mustache + branch = develop diff --git a/ragconnect.base/build.gradle b/ragconnect.base/build.gradle index e212a394a62cd29887daa30973dfc9ceb39af6be..77bafe579a620ca243e1061785fcf1ddef8a3108 100644 --- a/ragconnect.base/build.gradle +++ b/ragconnect.base/build.gradle @@ -78,7 +78,7 @@ jar { File preprocessorGrammar = file('../relast-preprocessor/src/main/jastadd/RelAst.relast') File ragConnectGrammar = file('./src/main/jastadd/RagConnect.relast') File intermediateGrammar = file('./src/main/jastadd/intermediate/MustacheNodes.relast') -File mustacheGrammar = file('./src/main/jastadd/mustache/Mustache.relast') +File mustacheGrammar = file('../relast-preprocessor/src/main/jastadd/mustache/Mustache.relast') task relast(type: JavaExec) { group = 'Build' main = "-jar" @@ -220,3 +220,4 @@ publishing { } publish.dependsOn jar +jar.dependsOn ":relast-preprocessor:jar" diff --git a/ragconnect.base/src/main/jastadd/Navigation.jrag b/ragconnect.base/src/main/jastadd/Navigation.jrag index 6ab782f07256aa39b97099ce6d0b982b5f02c1c8..d3890f7d22a195127e7688435f9168aa64a37eac 100644 --- a/ragconnect.base/src/main/jastadd/Navigation.jrag +++ b/ragconnect.base/src/main/jastadd/Navigation.jrag @@ -1,7 +1,7 @@ import java.util.List; import java.util.ArrayList; -aspect Navigation { +aspect RagConnectNavigation { // --- program --- eq RagConnect.getChild().program() = getProgram(); @@ -12,16 +12,27 @@ aspect Navigation { eq RagConnect.getChild().ragconnect() = this; eq MRagConnect.getChild().ragconnect() = getRagConnect(); + // --- containedConnectSpecification --- + inh ConnectSpecification ASTNode.containedConnectSpecification(); + eq RagConnect.getChild().containedConnectSpecification() = null; + eq MRagConnect.getChild().containedConnectSpecification() = null; + eq Document.getChild().containedConnectSpecification() = null; + eq Program.getChild().containedConnectSpecification() = null; + eq ConnectSpecification.getChild().containedConnectSpecification() = this; + // --- containedFile - eq Grammar.getChild().containedFile() = null; eq RagConnect.getChild().containedFile() = null; eq MRagConnect.getChild().containedFile() = null; // --- containedFileName --- - eq Grammar.getChild().containedFileName() = null; // should be in PP - eq RagConnect.getChild().containedFileName() = null; - eq ConnectSpecificationFile.getChild().containedFileName() = getFileName(); - eq MRagConnect.getChild().containedFileName() = null; + eq ConnectSpecificationFile.containedFileName() = getFileName(); + refine Navigation eq ASTNode.containedFileName() { + if (containedFile() == null) { + return containedConnectSpecification().containedFileName(); + } + return refined(); +// return containedFile().getFileName(); + } //--- allEndpointDefinitionList --- syn List<EndpointDefinition> RagConnect.allEndpointDefinitionList() { @@ -128,8 +139,6 @@ aspect Navigation { // --- rootTypeComponents --- syn JastAddList<MTypeComponent> MHandler.rootTypeComponents() = mragconnect().getRootTypeComponents(); - // === for preprocessor === - // --- isOptComponent --- - syn boolean TypeComponent.isOptComponent() = false; - eq OptComponent.isOptComponent() = true; + // --- isListComponent --- (defined in PP, but only on TypeComponent) + syn boolean Component.isListComponent() = false; } diff --git a/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag b/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag index 9de1c1e6ecf3e2f05580b3c324316708e353ad40..ef54a74e6fd57f11f17530e53524c63446277ca3 100644 --- a/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag +++ b/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag @@ -206,5 +206,5 @@ aspect Navigation { eq Document.getChild().program() = null; eq Document.getChild().ragconnect() = null; eq Document.getChild().containedFile() = null; - eq Document.getChild().containedFileName() = getFileName(); + eq Document.containedFileName() = getFileName(); } diff --git a/ragconnect.base/src/main/jastadd/mustache b/ragconnect.base/src/main/jastadd/mustache deleted file mode 160000 index c10bed0d03e3fa18b8133ce1de48de7646899615..0000000000000000000000000000000000000000 --- a/ragconnect.base/src/main/jastadd/mustache +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c10bed0d03e3fa18b8133ce1de48de7646899615 diff --git a/ragconnect.tests/src/test/01-input/regression-tests/issue27/.gitignore b/ragconnect.tests/src/test/01-input/regression-tests/issue27/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..607b7610731b1ddf9dc05e605bd374a4b59ea360 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/regression-tests/issue27/.gitignore @@ -0,0 +1 @@ +/*.noNewLine.* diff --git a/ragconnect.tests/src/test/01-input/regression-tests/issue27/README.md b/ragconnect.tests/src/test/01-input/regression-tests/issue27/README.md new file mode 100644 index 0000000000000000000000000000000000000000..96595af1b32ba8487f2e8e663a944b0be52dff28 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/regression-tests/issue27/README.md @@ -0,0 +1,3 @@ +# Issue27 + +Regression test for failing parser when missing newline at end of specification. diff --git a/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.connect b/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.connect new file mode 100644 index 0000000000000000000000000000000000000000..28827bb62d7b801cf2f8bc605afc90c122f0cb6a --- /dev/null +++ b/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.connect @@ -0,0 +1 @@ +receive A.Name ; diff --git a/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.relast b/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.relast new file mode 100644 index 0000000000000000000000000000000000000000..4c479a5756a37e42c74459c22006912445baa9b3 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/regression-tests/issue27/Test.relast @@ -0,0 +1 @@ +A ::= <Name:String> ; diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java index 47fa7c7c60d24d934ff2a979461a041319bdb49b..4d32adff23abd12f2052f320466b79dc0f8673f5 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java @@ -2,7 +2,6 @@ package org.jastadd.ragconnect.tests; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jastadd.ragconnect.compiler.Compiler; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -10,14 +9,14 @@ import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; -import java.util.ArrayList; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; -import static org.jastadd.ragconnect.tests.TestUtils.exec; import static org.jastadd.ragconnect.tests.TestUtils.readFile; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -25,8 +24,8 @@ public class Errors { private static final Logger logger = LogManager.getLogger(Errors.class); private static final String FILENAME_PATTERN = "$FILENAME"; - private static final String INPUT_DIRECTORY = "./src/test/01-input/errors/"; - private static final String OUTPUT_DIRECTORY = "./src/test/02-after-ragconnect/errors/"; + private static final String ERROR_DIRECTORY = "errors/"; + private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + ERROR_DIRECTORY; private static final String DEFAULT_GRAMMAR_NAME = "Errors"; @@ -48,44 +47,21 @@ public class Errors { @SuppressWarnings("SameParameterValue") private void test(String expectedName, String rootNode, String... connectNames) throws IOException { - String grammarFile = INPUT_DIRECTORY + DEFAULT_GRAMMAR_NAME + ".relast"; -// String ragconnectFile = INPUT_DIRECTORY + name + ".connect"; - String outFile = OUTPUT_DIRECTORY + expectedName + ".out"; - String expectedFile = INPUT_DIRECTORY + expectedName + ".expected"; - - assertThat(connectNames).isNotEmpty(); - - try { - logger.debug("user.dir: {}", System.getProperty("user.dir")); - List<String> args = new ArrayList<>() {{ - add("--o=" + OUTPUT_DIRECTORY); - add("--rootNode=" + rootNode); - add("--verbose"); - add(grammarFile); - }}; - for (String connectName : connectNames) { - args.add(INPUT_DIRECTORY + connectName + ".connect"); - } - - int returnValue = exec(Compiler.class, args.toArray(new String[0]), new File(outFile)); - Assertions.assertEquals(1, returnValue, "RagConnect did not return with value 1"); - } catch (IOException | InterruptedException e) { - e.printStackTrace(); - } + String grammarFile = ERROR_DIRECTORY + DEFAULT_GRAMMAR_NAME + ".relast"; + List<String> connectFiles = Arrays.stream(connectNames) + .map(connectName -> ERROR_DIRECTORY + connectName + ".connect") + .collect(Collectors.toList()); + Path outPath = TestUtils.runCompiler(grammarFile, connectFiles, rootNode, ERROR_DIRECTORY, 1); final String startOfErrorsPattern = "SEVERE: Errors:"; - String out = readFile(outFile, Charset.defaultCharset()); + String out = readFile(outPath, Charset.defaultCharset()); assertThat(out).contains(startOfErrorsPattern); out = out.substring(out.indexOf(startOfErrorsPattern) + 16); - String expected = readFile(expectedFile, Charset.defaultCharset()); -// if (inFiles.size() == 1) { -// expected = expected.replace(FILENAME_PATTERN, name + ".connect"); -// } else { -// for (int i = 0; i < inFiles.size(); i++) { -// expected = expected.replace(FILENAME_PATTERN + (i + 1), inFiles.get(i)); -// } -// } + Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX) + .resolve(ERROR_DIRECTORY) + .resolve(expectedName + ".expected"); + String expected = readFile(expectedPath, Charset.defaultCharset()); List<String> outList = Arrays.asList(out.split("\n")); Collections.sort(outList); List<String> expectedList = Arrays.stream(expected.split("\n")) diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java new file mode 100644 index 0000000000000000000000000000000000000000..d4d7389dafd0b3e7ff8f96ccd9bb67bca8977cd9 --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java @@ -0,0 +1,38 @@ +package org.jastadd.ragconnect.tests; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.*; +import java.util.Collections; + +/** + * Regression tests for fixed issues. + * + * @author rschoene - Initial contribution + */ +public class RegressionTests { + + private static final String REGRESSION_TEST_OUTPUT_DIRECTORY = "regression-test/"; + + @Test + public void issue27() throws IOException { + String grammarFile = "regression-tests/issue27/Test.relast"; + String connectFile = "regression-tests/issue27/Test.connect"; + grammarFile = ensureNoTrailingNewLine(grammarFile); + connectFile = ensureNoTrailingNewLine(connectFile); + TestUtils.runCompiler(grammarFile, Collections.singletonList(connectFile), "A", REGRESSION_TEST_OUTPUT_DIRECTORY, 0); + } + + private String ensureNoTrailingNewLine(String inputFileSuffix) throws IOException { + int dotIndex = inputFileSuffix.lastIndexOf('.'); + String outFileSuffix = inputFileSuffix.substring(0, dotIndex) + ".noNewLine" + inputFileSuffix.substring(dotIndex); + Path inputPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX).resolve(inputFileSuffix); + Path outputPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX).resolve(outFileSuffix); + + String content = Files.readString(inputPath); + Files.writeString(outputPath, content.stripTrailing(), StandardOpenOption.CREATE); + + return outFileSuffix; + } +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java index 2d08ccb376a6abaadf6643b32182c1ed5c10acda..c09059c8a66ca1cba262843ce30d4ce8ad0bc663 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java @@ -1,13 +1,22 @@ package org.jastadd.ragconnect.tests; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jastadd.ragconnect.compiler.Compiler; +import org.junit.jupiter.api.Assertions; + import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; /** @@ -17,7 +26,10 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class TestUtils { + private static final Logger logger = LogManager.getLogger(TestUtils.class); public static final double DELTA = 0.001d; + public static final String INPUT_DIRECTORY_PREFIX = "./src/test/01-input/"; + public static final String OUTPUT_DIRECTORY_PREFIX = "./src/test/02-after-ragconnect/"; public static String getMqttHost() { if (System.getenv("GITLAB_CI") != null) { @@ -41,6 +53,41 @@ public class TestUtils { return 1883; } + public static Path runCompiler(String grammarFile, Iterable<String> connectFiles, String rootNode, String outputDirectory, int expectedReturnValue) { + + assertThat(connectFiles).isNotEmpty(); + + Path outPath = Paths.get(OUTPUT_DIRECTORY_PREFIX) + .resolve(outputDirectory) + .resolve("Compiler.out"); + ensureCreated(outPath.getParent()); + + try { + logger.debug("user.dir: {}", System.getProperty("user.dir")); + List<String> args = new ArrayList<>() {{ + add("--o=" + OUTPUT_DIRECTORY_PREFIX + outputDirectory); + add("--rootNode=" + rootNode); + add("--verbose"); + add(INPUT_DIRECTORY_PREFIX + grammarFile); + }}; + connectFiles.forEach(connectFile -> args.add(INPUT_DIRECTORY_PREFIX + connectFile)); + + int returnValue = exec(Compiler.class, args.toArray(new String[0]), outPath.toFile()); + Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue); + } catch (IOException | InterruptedException e) { + fail(e); + } + return outPath; + } + + private static void ensureCreated(Path directory) { + File directoryFile = directory.toFile(); + if (directoryFile.exists() && directoryFile.isDirectory()) { + return; + } + assertTrue(directoryFile.mkdirs()); + } + public static int exec(Class<?> klass, String[] args, File err) throws IOException, InterruptedException { String javaHome = System.getProperty("java.home"); @@ -79,9 +126,9 @@ public class TestUtils { } } - public static String readFile(String path, Charset encoding) + public static String readFile(Path path, Charset encoding) throws IOException { - byte[] encoded = Files.readAllBytes(Paths.get(path)); + byte[] encoded = Files.readAllBytes(path); return new String(encoded, encoding); } diff --git a/relast-preprocessor b/relast-preprocessor index b538a7f709167c5f56fe65e6d9e9f02179cacaef..02f8e35993dc3f62ab49e94f69a6dc27170660da 160000 --- a/relast-preprocessor +++ b/relast-preprocessor @@ -1 +1 @@ -Subproject commit b538a7f709167c5f56fe65e6d9e9f02179cacaef +Subproject commit 02f8e35993dc3f62ab49e94f69a6dc27170660da diff --git a/settings.gradle b/settings.gradle index e7769874a5f3186274ceecbcd445feeb656cf9a4..8a597cfa491920744bb8b5e1d3f103fb4fc95bb1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,9 @@ +pluginManagement { + plugins { + id 'org.jastadd' version '1.13.3' + } +} + rootProject.name = 'ragconnect' include 'relast-preprocessor'