Commit 49777537 authored by René Schöne's avatar René Schöne
Browse files

working on warnings

- add warnings for dependency definitions, and some parameter combinations
parent 4f85119d
Pipeline #12817 passed with stages
in 11 minutes and 39 seconds
aspect Errors {
coll Set<ErrorMessage> RagConnect.errors()
[new TreeSet<ErrorMessage>()]
coll Set<CompilerMessage> RagConnect.errors()
[new TreeSet<CompilerMessage>()]
root RagConnect;
EndpointDefinition contributes error("Endpoint definition already defined for " + parentTypeName() + "." + entityName())
......@@ -74,66 +74,8 @@ aspect ErrorHelpers {
}
return null;
}
}
aspect ErrorMessage {
public class ErrorMessage implements Comparable<ErrorMessage> {
private final ASTNode node;
private final String filename;
private final int line;
private final int col;
private final String message;
public ErrorMessage(ASTNode node, String message) {
this.node = node;
this.filename = node.containedFileName();
this.line = node.getStartLine();
this.col = node.getStartColumn();
this.message = message;
}
public ASTNode getNode() {
return node;
}
public int getLine() {
return line;
}
public int getCol() {
return col;
}
public String getMessage() {
return message;
}
public String toString() {
return filename + " Line " + line + ", column " + col + ": " + message;
}
@Override
public int compareTo(ErrorMessage err) {
int n = filename.compareTo(err.filename);
if (n != 0) {
return n;
}
n = line - err.line;
if (n != 0) {
return n;
}
n = col - err.col;
if (n != 0) {
return n;
}
return message.compareTo(err.message);
}
}
protected ErrorMessage ASTNode.error(String message) {
return new ErrorMessage(this, message);
protected CompilerMessage ASTNode.error(String message) {
return new CompilerMessage(this, message);
}
}
......@@ -39,5 +39,6 @@ Configuration ::=
<JastAddList:String>
<JastAddOpt:String>
<IncrementalOptionActive:boolean>
<CacheAllOptionActive:boolean>
<ExperimentalJastAdd329:boolean>;
rel Configuration.RootNode -> TypeDecl ;
......@@ -6,4 +6,60 @@ aspect Util {
}
protected T JastAddList.firstChild() { return getChild(0); }
protected T JastAddList.lastChild() { return getChild(getNumChild() - 1); }
public class CompilerMessage implements Comparable<CompilerMessage> {
private final ASTNode node;
private final String filename;
private final int line;
private final int col;
private final String message;
public CompilerMessage(ASTNode node, String message) {
this.node = node;
this.filename = node.containedFileName();
this.line = node.getStartLine();
this.col = node.getStartColumn();
this.message = message;
}
public ASTNode getNode() {
return node;
}
public int getLine() {
return line;
}
public int getCol() {
return col;
}
public String getMessage() {
return message;
}
public String toString() {
return filename + " Line " + line + ", column " + col + ": " + message;
}
@Override
public int compareTo(CompilerMessage other) {
int n = filename.compareTo(other.filename);
if (n != 0) {
return n;
}
n = line - other.line;
if (n != 0) {
return n;
}
n = col - other.col;
if (n != 0) {
return n;
}
return message.compareTo(other.message);
}
}
}
aspect Warnings {
coll Set<CompilerMessage> RagConnect.warnings()
[new TreeSet<CompilerMessage>()]
root RagConnect;
DependencyDefinition contributes warning("Dependency definition should not be used if incremental evaluation is enabled!")
when ragconnect().configIncrementalOptionActive()
to RagConnect.warnings();
EndpointDefinition contributes warning("No dependency definitions are given, and incremental evaluation is disabled. No messages will be sent for this!")
when getSend() && ragconnect().allDependencyDefinitionList().isEmpty() && !ragconnect().configIncrementalOptionActive()
to RagConnect.warnings();
ConnectSpecificationFile contributes warning("Incremental evaluation is disabled, but cache=all is set. This might lead to no messages sent!")
when !ragconnect().configIncrementalOptionActive() && ragconnect().getConfiguration().getCacheAllOptionActive()
to RagConnect.warnings();
}
aspect WarningHelpers {
protected CompilerMessage ASTNode.warning(String message) {
return new CompilerMessage(this, message);
}
}
......@@ -83,10 +83,18 @@ public class Compiler extends AbstractCompiler {
throw new CompilerException("Failed to parse all files", re);
}
if (!ragConnect.warnings().isEmpty()) {
StringBuilder sb = new StringBuilder("Warnings:\n");
for (CompilerMessage message : ragConnect.warnings()) {
sb.append(message).append("\n");
}
System.err.println(sb);
}
if (!ragConnect.errors().isEmpty()) {
StringBuilder sb = new StringBuilder("Errors:\n");
for (ErrorMessage e : ragConnect.errors()) {
sb.append(e).append("\n");
for (CompilerMessage message : ragConnect.errors()) {
sb.append(message).append("\n");
}
System.err.println(sb);
System.exit(1);
......@@ -306,6 +314,9 @@ public class Compiler extends AbstractCompiler {
System.out.println("ragConnect.getConfiguration().IncrementalOptionActive = " + incrementalOptionActive);
}
// reuse "--cache=all" option of JastAdd
ragConnect.getConfiguration().setCacheAllOptionActive(this.getConfiguration().cacheAll());
// reuse "--List" and "--Opt" options of JastAdd
ragConnect.getConfiguration().setJastAddList(this.getConfiguration().listType());
ragConnect.getConfiguration().setJastAddOpt(this.getConfiguration().optType());
......
TestNoDependencies.connect Line 1, column 1: No dependency definitions are given, and incremental evaluation is disabled. No messages will be sent for this!
TestNoDependencies.connect Line 1, column 1: Incremental evaluation is disabled, but cache=all is set. This might lead to no messages sent!
TestNoDependencies.connect Line 1, column 1: No dependency definitions are given, and incremental evaluation is disabled. No messages will be sent for this!
TestSomeDependencies.connect Line 3, column 1: Dependency definition should not be used if incremental evaluation is enabled!
TestSomeDependencies.connect Line 1, column 1: Incremental evaluation is disabled, but cache=all is set. This might lead to no messages sent!
aspect Computation {
syn String Root.getOutput() = getInput() + "out";
}
send Root.Output ;
Root.Output canDependOn Root.Input as AttributeDependency;
package org.jastadd.ragconnect.tests;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
......@@ -10,9 +9,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
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;
......@@ -20,10 +17,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.jastadd.ragconnect.tests.TestUtils.readFile;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test error messages.
*
* @author rschoene - Initial contribution
*/
public class Errors {
private static final Logger logger = LoggerFactory.getLogger(Errors.class);
private static final String FILENAME_PATTERN = "$FILENAME";
private static final String ERROR_DIRECTORY = "errors/";
private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + ERROR_DIRECTORY;
......@@ -37,12 +38,12 @@ public class Errors {
@Test
void testStandardErrors() throws IOException {
test("Standard", "A","Standard");
test("Standard", "A", "Standard");
}
@Test
void testTwoPartsErrors() throws IOException {
test("Part", "A","Part1", "Part2");
test("Part", "A", "Part1", "Part2");
}
@SuppressWarnings("SameParameterValue")
......@@ -58,18 +59,7 @@ public class Errors {
assertThat(out).contains(startOfErrorsPattern);
out = out.substring(out.indexOf(startOfErrorsPattern) + startOfErrorsPattern.length());
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"))
.sorted()
.filter(s -> !s.isEmpty() && !s.startsWith("//"))
.collect(Collectors.toList());
Assertions.assertLinesMatch(expectedList, outList);
TestUtils.assertLinesMatch(ERROR_DIRECTORY, expectedName, out);
logger.info("ragconnect for " + expectedName + " returned:\n{}", out);
}
......
......@@ -66,7 +66,7 @@ public class TestUtils {
return 1883;
}
public static Path runCompiler(String grammarFile, Iterable<String> connectFiles, String rootNode, String outputDirectory, int expectedReturnValue) {
public static Path runCompiler(String grammarFile, Iterable<String> connectFiles, String rootNode, String outputDirectory, int expectedReturnValue, String... additionalArguments) {
assertThat(connectFiles).isNotEmpty();
......@@ -84,6 +84,7 @@ public class TestUtils {
add(INPUT_DIRECTORY_PREFIX + grammarFile);
}};
connectFiles.forEach(connectFile -> args.add(INPUT_DIRECTORY_PREFIX + connectFile));
args.addAll(Arrays.asList(additionalArguments));
int returnValue = exec(Compiler.class, args.toArray(new String[0]), outPath.toFile());
Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue);
......@@ -93,6 +94,21 @@ public class TestUtils {
return outPath;
}
public static void assertLinesMatch(String directory, String expectedName, String out) throws IOException {
Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX)
.resolve(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"))
.sorted()
.filter(s -> !s.isEmpty() && !s.startsWith("//"))
.collect(Collectors.toList());
Assertions.assertLinesMatch(expectedList, outList);
}
private static void ensureCreated(Path directory) {
File directoryFile = directory.toFile();
if (directoryFile.exists() && directoryFile.isDirectory()) {
......
package org.jastadd.ragconnect.tests;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.jastadd.ragconnect.tests.TestUtils.readFile;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test warning messages.
*
* @author rschoene - Initial contribution
*/
public class Warnings {
private static final Logger logger = LoggerFactory.getLogger(Warnings.class);
private static final String WARNING_DIRECTORY = "warnings/";
private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + WARNING_DIRECTORY;
private static final String DEFAULT_GRAMMAR_NAME = "Test";
private static final String OPTION_INCREMENTAL_PARAM = "--incremental=param";
private static final String OPTION_TRACE_FLUSH = "--tracing=flush";
private static final String OPTION_CACHE_ALL = "--cache=all";
@BeforeAll
public static void createOutputDirectory() {
File outputDirectory = new File(OUTPUT_DIRECTORY);
assertTrue((outputDirectory.exists() && outputDirectory.isDirectory()) || outputDirectory.mkdir());
}
@Test
public void testNoDependenciesAndInc() throws IOException {
// pass "null" as expectedName means that no warnings are expected
test(null, "TestNoDependencies", OPTION_INCREMENTAL_PARAM, OPTION_TRACE_FLUSH);
}
@Test
public void testSomeDependenciesAndInc() throws IOException {
test("SomeDependenciesAndInc", "TestSomeDependencies",
OPTION_INCREMENTAL_PARAM, OPTION_TRACE_FLUSH);
}
@Test
public void testNoDependenciesAndNoInc() throws IOException {
test("NoDependenciesAndNoInc", "TestNoDependencies");
}
@Test
public void testNoIncAndCacheAll() throws IOException {
test("NoDependenciesAndNoIncAndCacheAll", "TestNoDependencies", OPTION_CACHE_ALL);
test("SomeDependenciesAndNoIncAndCacheAll", "TestSomeDependencies", OPTION_CACHE_ALL);
}
private void test(String expectedName, String connectName, String... additionalArguments) throws IOException {
String grammarFile = WARNING_DIRECTORY + DEFAULT_GRAMMAR_NAME + ".relast";
List<String> connectFiles = Collections.singletonList(WARNING_DIRECTORY + connectName + ".connect");
Path outPath = TestUtils.runCompiler(
grammarFile, connectFiles, "Root", WARNING_DIRECTORY, 0, additionalArguments
);
String out = readFile(outPath, Charset.defaultCharset());
final boolean expectWarnings = expectedName != null;
final String startOfWarningsPattern = "Warnings:\n";
if (expectWarnings) {
assertThat(out).contains(startOfWarningsPattern);
} else {
assertThat(out).doesNotContain(startOfWarningsPattern);
}
final String startOfErrorsPattern = "Errors:\n";
assertThat(out).doesNotContain(startOfErrorsPattern);
if (!expectWarnings) {
return;
}
out = out.substring(out.indexOf(startOfWarningsPattern) + startOfWarningsPattern.length());
TestUtils.assertLinesMatch(WARNING_DIRECTORY, expectedName, out);
logger.info("ragconnect for " + expectedName + " returned:\n{}", out);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment