Skip to content
Snippets Groups Projects
Commit c4a61a1e authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch 'error_filenames' into 'master'

Emit filenames for error messages.

See merge request johannes.mey/relast!2
parents 74ba289c fa37120c
Branches
No related tags found
1 merge request!2Emit filenames for error messages.
Pipeline #4245 passed
...@@ -50,17 +50,33 @@ aspect HelpAttributes { ...@@ -50,17 +50,33 @@ aspect HelpAttributes {
eq OptionalRelationComponent.multiplicityOpt() = true; eq OptionalRelationComponent.multiplicityOpt() = true;
syn boolean RelationComponent.multiplicityMany() = false; syn boolean RelationComponent.multiplicityMany() = false;
eq ManyRelationComponent.multiplicityMany() = true; eq ManyRelationComponent.multiplicityMany() = true;
inh ContainedInFile Component.enclosingFileContainer();
eq TypeDecl.getComponent().enclosingFileContainer() = this;
eq Relation.getChild().enclosingFileContainer() = this;
inh ContainedInFile TypeUse.enclosingFileContainer();
eq SimpleTypeComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
eq TokenComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
eq TypeDecl.getSuper().enclosingFileContainer() = this;
syn String ASTNode.containedFile() = "Unknown";
eq Component.containedFile() = enclosingFileContainer() == null ? "Unknown2" : enclosingFileContainer().containedFile();
eq TypeUse.containedFile() = enclosingFileContainer() == null ? "Unknown3" : enclosingFileContainer().containedFile();
eq TypeDecl.containedFile() = getFileName();
eq Relation.containedFile() = getFileName();
} }
aspect ErrorMessage { aspect ErrorMessage {
public class ErrorMessage implements Comparable<ErrorMessage> { public class ErrorMessage implements Comparable<ErrorMessage> {
private final ASTNode node; private final ASTNode node;
private final String filename;
private final int line; private final int line;
private final int col; private final int col;
private final String message; private final String message;
public ErrorMessage(ASTNode node, String message) { public ErrorMessage(ASTNode node, String message) {
this.node = node; this.node = node;
this.filename = node.containedFile();
this.line = node.getStartLine(); this.line = node.getStartLine();
this.col = node.getStartColumn(); this.col = node.getStartColumn();
this.message = message; this.message = message;
...@@ -80,12 +96,17 @@ aspect ErrorMessage { ...@@ -80,12 +96,17 @@ aspect ErrorMessage {
} }
public String toString() { public String toString() {
return "Line " + line + ", column " + col + ": " + message; return filename + " Line " + line + ", column " + col + ": " + message;
} }
@Override @Override
public int compareTo(ErrorMessage err) { public int compareTo(ErrorMessage err) {
int n = line - err.line; int n = filename.compareTo(err.filename);
if (n != 0) {
return n;
}
n = line - err.line;
if (n != 0) { if (n != 0) {
return n; return n;
} }
......
Program ::= TypeDecl* Relation*; Program ::= TypeDecl* Relation*;
TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*; abstract ContainedInFile ::= <FileName> ;
TypeDecl : ContainedInFile ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
abstract Component ::= <ID>; abstract Component ::= <ID>;
abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse; abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse;
...@@ -13,7 +14,7 @@ abstract TypeUse ::= <ID>; ...@@ -13,7 +14,7 @@ abstract TypeUse ::= <ID>;
SimpleTypeUse : TypeUse; SimpleTypeUse : TypeUse;
ParameterizedTypeUse : TypeUse ::= TypeUse*; ParameterizedTypeUse : TypeUse ::= TypeUse*;
Relation ::= Left:RelationComponent Direction Right:RelationComponent; Relation : ContainedInFile ::= Left:RelationComponent Direction Right:RelationComponent;
abstract RelationComponent : SimpleTypeComponent; abstract RelationComponent : SimpleTypeComponent;
OneRelationComponent : RelationComponent; OneRelationComponent : RelationComponent;
OptionalRelationComponent : RelationComponent; OptionalRelationComponent : RelationComponent;
......
...@@ -6,9 +6,23 @@ Program goal = ...@@ -6,9 +6,23 @@ Program goal =
TypeDecl type_decl = TypeDecl type_decl =
ID type_decl_super.s components_opt.c SCOL ID type_decl_super.s components_opt.c SCOL
{: return new TypeDecl(ID, false, s, c); :} {:
TypeDecl result = new TypeDecl();
result.setID(ID);
result.setAbstract(false);
result.setSuperOpt(s);
result.setComponentList(c);
return result;
:}
| ABSTRACT ID type_decl_super.s components_opt.c SCOL | ABSTRACT ID type_decl_super.s components_opt.c SCOL
{: return new TypeDecl(ID, true, s, c); :} {:
TypeDecl result = new TypeDecl();
result.setID(ID);
result.setAbstract(true);
result.setSuperOpt(s);
result.setComponentList(c);
return result;
:}
; ;
Opt type_decl_super = Opt type_decl_super =
...@@ -38,7 +52,7 @@ List components_opt = ...@@ -38,7 +52,7 @@ List components_opt =
; ;
List components = List components =
{: return new List(); :} /* empty */ {: return new List(); :}
| components.l component.c {: return l.add(c); :} | components.l component.c {: return l.add(c); :}
; ;
...@@ -64,7 +78,13 @@ Component component = ...@@ -64,7 +78,13 @@ Component component =
Relation relation = Relation relation =
RELATION relation_comp.l direction relation_comp.r SCOL RELATION relation_comp.l direction relation_comp.r SCOL
{: return new Relation(l, direction, r); :} {:
Relation result = new Relation();
result.setLeft(l);
result.setDirection(direction);
result.setRight(r);
return result;
:}
; ;
RelationComponent relation_comp = RelationComponent relation_comp =
......
...@@ -14,7 +14,7 @@ import java.util.List; ...@@ -14,7 +14,7 @@ import java.util.List;
public class Compiler { public class Compiler {
private static final String VERSION = "0.2.1"; private static final String VERSION = "0.2.2";
private ArrayList<Option<?>> options; private ArrayList<Option<?>> options;
private FlagOption optionWriteToFile; private FlagOption optionWriteToFile;
...@@ -177,9 +177,11 @@ public class Compiler { ...@@ -177,9 +177,11 @@ public class Compiler {
try { try {
Program newProgram = (Program) parser.parse(scanner); Program newProgram = (Program) parser.parse(scanner);
for (TypeDecl typeDecl : newProgram.getTypeDeclList()) { for (TypeDecl typeDecl : newProgram.getTypeDeclList()) {
typeDecl.setFileName(file);
program.addTypeDecl(typeDecl); program.addTypeDecl(typeDecl);
} }
for (Relation relation : newProgram.getRelationList()) { for (Relation relation : newProgram.getRelationList()) {
relation.setFileName(file);
program.addRelation(relation); program.addRelation(relation);
} }
} catch (IOException e) { } catch (IOException e) {
......
Errors: Errors:
Line 5, column 5: Role name missing for type 'A' $FILENAME Line 5, column 5: Role name missing for type 'A'
Line 6, column 15: Role name missing for type 'B' $FILENAME Line 6, column 15: Role name missing for type 'B'
Line 7, column 12: The target of a directed relation cannot have a role name $FILENAME Line 7, column 12: The target of a directed relation cannot have a role name
Line 8, column 13: The target of a directed relation may only have multiplicity 1 $FILENAME Line 8, column 13: The target of a directed relation may only have multiplicity 1
Errors: Errors:
Line 2, column 12: Component 'X' is already declared for type 'B1' $FILENAME Line 2, column 12: Component 'X' is already declared for type 'B1'
Line 6, column 5: Component 'X' is already declared for type 'B2' $FILENAME Line 6, column 5: Component 'X' is already declared for type 'B2'
Errors:
$FILENAME1 Line 5, column 5: Role name missing for type 'A'
$FILENAME1 Line 6, column 15: Role name missing for type 'B'
$FILENAME2 Line 1, column 12: The target of a directed relation cannot have a role name
$FILENAME2 Line 2, column 13: The target of a directed relation may only have multiplicity 1
Program ::= A* B*;
A;
B;
rel A -> B;
rel A.bs* <-> B*;
rel A.b -> B.b;
rel A.b2 -> B*;
...@@ -9,6 +9,9 @@ import org.junit.jupiter.api.Test; ...@@ -9,6 +9,9 @@ import org.junit.jupiter.api.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.jastadd.relast.tests.TestHelpers.exec; import static org.jastadd.relast.tests.TestHelpers.exec;
import static org.jastadd.relast.tests.TestHelpers.readFile; import static org.jastadd.relast.tests.TestHelpers.readFile;
...@@ -17,39 +20,33 @@ import static org.jastadd.relast.tests.TestHelpers.readFile; ...@@ -17,39 +20,33 @@ import static org.jastadd.relast.tests.TestHelpers.readFile;
class Errors { class Errors {
private static final Logger logger = LogManager.getLogger(Errors.class); private static final Logger logger = LogManager.getLogger(Errors.class);
private static final String FILENAME_PATTERN = "$FILENAME";
@Test @Test
void test1() throws IOException { void test1() throws IOException {
test("Errors");
String inFile = "./src/test/jastadd/errors/Errors.relast";
String outFile = "./src/test/jastadd/errors/Errors.out";
String expectedFile = "./src/test/jastadd/errors/Errors.expected";
try {
System.out.println(System.getProperty("user.dir"));
int returnValue = exec(Compiler.class, new String[]{inFile}, new File(outFile));
Assertions.assertEquals(1, returnValue, "Relast did not return with value 1");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} }
String out = readFile(outFile, Charset.defaultCharset()); @Test
String expected = readFile(expectedFile, Charset.defaultCharset()); void test2() throws IOException {
test("Inheritance");
Assertions.assertEquals(out, expected);
logger.info("'relast Errors.relast' returned \n{}", out);
} }
@Test @Test
void test2() throws IOException { void test3() throws IOException {
test("Multiple", "Multiple_1", "Multiple_2");
}
String inFile = "./src/test/jastadd/errors/Inheritance.relast"; private void test(String name, String... inFilenames) throws IOException {
String outFile = "./src/test/jastadd/errors/Inheritance.out"; List<String> inFiles = Arrays.stream(inFilenames.length > 0 ? inFilenames : new String[]{name})
String expectedFile = "./src/test/jastadd/errors/Inheritance.expected"; .map(f -> "./src/test/jastadd/errors/" + f + ".relast")
.collect(Collectors.toList());
String outFile = "./src/test/jastadd/errors/" + name + ".out";
String expectedFile = "./src/test/jastadd/errors/" + name + ".expected";
try { try {
System.out.println(System.getProperty("user.dir")); System.out.println(System.getProperty("user.dir"));
int returnValue = exec(Compiler.class, new String[]{inFile}, new File(outFile)); int returnValue = exec(Compiler.class, inFiles.toArray(new String[0]), new File(outFile));
Assertions.assertEquals(1, returnValue, "Relast did not return with value 1"); Assertions.assertEquals(1, returnValue, "Relast did not return with value 1");
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -57,10 +54,16 @@ class Errors { ...@@ -57,10 +54,16 @@ class Errors {
String out = readFile(outFile, Charset.defaultCharset()); String out = readFile(outFile, Charset.defaultCharset());
String expected = readFile(expectedFile, Charset.defaultCharset()); String expected = readFile(expectedFile, Charset.defaultCharset());
if (inFiles.size() == 1) {
expected = expected.replace(FILENAME_PATTERN, inFiles.get(0));
} else {
for (int i = 0; i < inFiles.size(); i++) {
expected = expected.replace(FILENAME_PATTERN + (i + 1), inFiles.get(i));
}
}
Assertions.assertEquals(expected, out);
Assertions.assertEquals(out, expected); logger.info("relast for " + name + " returned \n{}", out);
logger.info("'relast Inheritance.relast' returned \n{}", out);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment