Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
3 merge requests!39Version 1.1.0,!35Version 1.0.0,!28Resolve "Do not generate dependency methods if incremental is active"
Pipeline #12817 passed
Showing
with 229 additions and 83 deletions
aspect Errors { aspect Errors {
coll Set<ErrorMessage> RagConnect.errors() coll Set<CompilerMessage> RagConnect.errors()
[new TreeSet<ErrorMessage>()] [new TreeSet<CompilerMessage>()]
root RagConnect; root RagConnect;
EndpointDefinition contributes error("Endpoint definition already defined for " + parentTypeName() + "." + entityName()) EndpointDefinition contributes error("Endpoint definition already defined for " + parentTypeName() + "." + entityName())
...@@ -74,66 +74,8 @@ aspect ErrorHelpers { ...@@ -74,66 +74,8 @@ aspect ErrorHelpers {
} }
return null; 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) { protected CompilerMessage ASTNode.error(String message) {
return new ErrorMessage(this, message); return new CompilerMessage(this, message);
} }
} }
...@@ -39,5 +39,6 @@ Configuration ::= ...@@ -39,5 +39,6 @@ Configuration ::=
<JastAddList:String> <JastAddList:String>
<JastAddOpt:String> <JastAddOpt:String>
<IncrementalOptionActive:boolean> <IncrementalOptionActive:boolean>
<CacheAllOptionActive:boolean>
<ExperimentalJastAdd329:boolean>; <ExperimentalJastAdd329:boolean>;
rel Configuration.RootNode -> TypeDecl ; rel Configuration.RootNode -> TypeDecl ;
...@@ -6,4 +6,60 @@ aspect Util { ...@@ -6,4 +6,60 @@ aspect Util {
} }
protected T JastAddList.firstChild() { return getChild(0); } protected T JastAddList.firstChild() { return getChild(0); }
protected T JastAddList.lastChild() { return getChild(getNumChild() - 1); } 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 { ...@@ -83,10 +83,18 @@ public class Compiler extends AbstractCompiler {
throw new CompilerException("Failed to parse all files", re); 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()) { if (!ragConnect.errors().isEmpty()) {
StringBuilder sb = new StringBuilder("Errors:\n"); StringBuilder sb = new StringBuilder("Errors:\n");
for (ErrorMessage e : ragConnect.errors()) { for (CompilerMessage message : ragConnect.errors()) {
sb.append(e).append("\n"); sb.append(message).append("\n");
} }
System.err.println(sb); System.err.println(sb);
System.exit(1); System.exit(1);
...@@ -306,6 +314,9 @@ public class Compiler extends AbstractCompiler { ...@@ -306,6 +314,9 @@ public class Compiler extends AbstractCompiler {
System.out.println("ragConnect.getConfiguration().IncrementalOptionActive = " + incrementalOptionActive); 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 // reuse "--List" and "--Opt" options of JastAdd
ragConnect.getConfiguration().setJastAddList(this.getConfiguration().listType()); ragConnect.getConfiguration().setJastAddList(this.getConfiguration().listType());
ragConnect.getConfiguration().setJastAddOpt(this.getConfiguration().optType()); 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";
}
Root ::= <Input> /<Output>/ ;
send Root.Output ;
send Root.Output ;
Root.Output canDependOn Root.Input as AttributeDependency;
package org.jastadd.ragconnect.tests; package org.jastadd.ragconnect.tests;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -10,9 +9,7 @@ import java.io.File; ...@@ -10,9 +9,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -20,10 +17,14 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -20,10 +17,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.jastadd.ragconnect.tests.TestUtils.readFile; import static org.jastadd.ragconnect.tests.TestUtils.readFile;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test error messages.
*
* @author rschoene - Initial contribution
*/
public class Errors { public class Errors {
private static final Logger logger = LoggerFactory.getLogger(Errors.class); 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 ERROR_DIRECTORY = "errors/";
private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + ERROR_DIRECTORY; private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + ERROR_DIRECTORY;
...@@ -37,12 +38,12 @@ public class Errors { ...@@ -37,12 +38,12 @@ public class Errors {
@Test @Test
void testStandardErrors() throws IOException { void testStandardErrors() throws IOException {
test("Standard", "A","Standard"); test("Standard", "A", "Standard");
} }
@Test @Test
void testTwoPartsErrors() throws IOException { void testTwoPartsErrors() throws IOException {
test("Part", "A","Part1", "Part2"); test("Part", "A", "Part1", "Part2");
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
...@@ -58,18 +59,7 @@ public class Errors { ...@@ -58,18 +59,7 @@ public class Errors {
assertThat(out).contains(startOfErrorsPattern); assertThat(out).contains(startOfErrorsPattern);
out = out.substring(out.indexOf(startOfErrorsPattern) + startOfErrorsPattern.length()); out = out.substring(out.indexOf(startOfErrorsPattern) + startOfErrorsPattern.length());
Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX) TestUtils.assertLinesMatch(ERROR_DIRECTORY, expectedName, out);
.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);
logger.info("ragconnect for " + expectedName + " returned:\n{}", out); logger.info("ragconnect for " + expectedName + " returned:\n{}", out);
} }
......
...@@ -66,7 +66,7 @@ public class TestUtils { ...@@ -66,7 +66,7 @@ public class TestUtils {
return 1883; 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(); assertThat(connectFiles).isNotEmpty();
...@@ -84,6 +84,7 @@ public class TestUtils { ...@@ -84,6 +84,7 @@ public class TestUtils {
add(INPUT_DIRECTORY_PREFIX + grammarFile); add(INPUT_DIRECTORY_PREFIX + grammarFile);
}}; }};
connectFiles.forEach(connectFile -> args.add(INPUT_DIRECTORY_PREFIX + connectFile)); 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()); int returnValue = exec(Compiler.class, args.toArray(new String[0]), outPath.toFile());
Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue); Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue);
...@@ -93,6 +94,21 @@ public class TestUtils { ...@@ -93,6 +94,21 @@ public class TestUtils {
return outPath; 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) { private static void ensureCreated(Path directory) {
File directoryFile = directory.toFile(); File directoryFile = directory.toFile();
if (directoryFile.exists() && directoryFile.isDirectory()) { 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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment