Skip to content

Commit

Permalink
added specs for testing asts and m3 models
Browse files Browse the repository at this point in the history
  • Loading branch information
jurgenvinju committed Apr 29, 2023
1 parent 032765a commit f52ea52
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 5 deletions.
44 changes: 39 additions & 5 deletions src/org/rascalmpl/library/analysis/m3/AST.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@ metrics or other analysis tools should still take semantic differences between p
module analysis::m3::AST

import Message;
import Node;
import analysis::m3::TypeSymbol;

public data \AST(loc file = |unknown:///|)
data \AST(loc file = |unknown:///|)
= declaration(Declaration declaration)
| lines(list[str] contents)
| noAST(Message msg)
;

public loc unknownSource = |unknown:///|;
public loc unresolvedDecl = |unresolved:///|;
public loc unresolvedType = |unresolved:///|;
loc unknownSource = |unknown:///|;
loc unresolvedDecl = |unresolved:///|;
loc unresolvedType = |unresolved:///|;

data Declaration(
loc src = |unknown:///|,
Expand Down Expand Up @@ -73,7 +74,40 @@ data Type(

data Modifier;


@synopsis{Test for the consistency characteristics of an M3 annotated abstract syntax tree}
bool astNodeSpecification(node n, str language = "java", bool checkNameResolution=false, bool checkSourceLocation=true) {
// get a loc from any node if there is any.
loc pos(node y) = (loc f := (y.src?|unknown:///|(0,0))) ? f : |unknown:///|(0,0);
loc decl(node y) = (loc d := y.decl?|unresolved:///|) ? d : |unresolved:///|;
int begin(node y) = begin(pos(y));
int end(node y) = end(pos(y));
int begin(loc l) = l.offset;
int end(loc l) = l.offset + l.length;
bool leftToRight(loc l, loc r) = end(l) <= begin(r);
bool leftToRight(node a, node b) = leftToRight(pos(a), pos(b));
if (checkSourceLocation) {
// all nodes have src annotations
assert all(/node x := n, x.src?);
// siblings are sorted in the input, even if some of them are lists
assert all(/node x := n, [*_, node a, node b, *_] := getChildren(x), leftToRight(a,b));
assert all(/node x := n, [*_, node a, [node b, *_], *_] := getChildren(x), leftToRight(a,b));
assert all(/node x := n, [*_, [*_, node a], node b, *_] := getChildren(x), leftToRight(a,b));
assert all(/node x := n, [*_, [*_, node a], [node b, *_], *_] := getChildren(x), leftToRight(a,b));
assert all(/[*_, node a, node b, *_] := n, leftToRight(a,b));
// children positions are included in the parent input scope
assert all(/node parent := n, /node child := parent, begin(parent) <= begin(child), end(child) <= end(parent));
}
if (checkNameResolution) {
// all resolved names have the language as schema prefix
assert all(/node m := n, m.decl?, /^<language>/ := decl(m).scheme);
}
return true;
}
Expand Down
25 changes: 25 additions & 0 deletions src/org/rascalmpl/library/analysis/m3/Core.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import analysis::graphs::Graph;
import Node;
import Map;
import List;
import Relation;
extend analysis::m3::TypeSymbol;

data Modifier;
Expand Down Expand Up @@ -200,3 +201,27 @@ list[Message] checkM3(M3 model) {
result += [error("non-root element is not contained anywhere", decl) | decl <- model.containment<from> - model.declarations<name> - top(model.containment)];
return result;
}
test bool testM3ModelConsistency(M3 m) {
decls = m.declarations<name>;
// nothing that is contained here does not not have a declaration, except the outermost translationUnit
assert m.declarations<name> - m.containment<to> - top(m.containment) == {};
// everything in the containment relation has been declared somewhere
assert carrier(m.containment) - decls == {};
// everything in the declarations relation is contained somewhere
assert decls - carrier(m.containment) == {};
// all uses point to actual declarations
assert m.uses<name> - m.declarations<name> == {};
// in this example, all declarations are used at least once
assert m.declarations<name> - m.uses<name> == {};
// m.declarations is one-to-one
assert size(m.declarations<name>) == size(m.declarations);
return true;
}

0 comments on commit f52ea52

Please sign in to comment.