private static void checkFilePositionInvariants(ParseTreeNode root) {
checkFilePositionInvariants(AncestorChain.instance(root));
}
private static void checkFilePositionInvariants(AncestorChain<?> nChain) {
ParseTreeNode n = nChain.node;
String msg = n + " : " + n.getFilePosition();
try {
// require that n start on or after its previous sibling
int indexInParent = nChain.parent != null
? nChain.parent.node.children().indexOf(nChain.node) : -1;
ParseTreeNode prev = indexInParent > 0
? nChain.parent.node.children().get(indexInParent - 1) : null;
if (prev != null) {
if (prev instanceof Identifier && n instanceof FunctionConstructor
&& nChain.parent != null
&& nChain.parent.node instanceof FunctionDeclaration) {
// Special case for FunctionDeclarations which look like this
// FunctionDeclaration
// Identifier
// FunctionConstructor
// Identifier
// with the FunctionConstructor having the same position as the
// declaration which makes the identifier overlap with its sibling.
assertEquals(msg, prev.getFilePosition(),
nChain.parent.cast(FunctionDeclaration.class).node
.getIdentifier().getFilePosition());
} else {
assertTrue(msg, (prev.getFilePosition().endCharInFile()
<= n.getFilePosition().startCharInFile()));
}
}
// require that n encompass its children
List<? extends ParseTreeNode> children = n.children();
if (!children.isEmpty()) {
ParseTreeNode first = children.get(0),
last = children.get(children.size() - 1);
assertTrue(msg + " > " + first + " : " + first.getFilePosition(),
(first.getFilePosition().startCharInFile()
>= n.getFilePosition().startCharInFile()));
assertTrue(msg + " < " + last + " : " + last.getFilePosition(),
(last.getFilePosition().endCharInFile()
<= n.getFilePosition().endCharInFile()));
}