/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.frontend.parser;
import abs.frontend.ast.ASTNode;
import abs.frontend.ast.List;
import abs.frontend.ast.Opt;
public class SourcePosition {
private final int line;
private final int column;
private final ASTNode<?> contextNode;
SourcePosition(ASTNode<?> node, int line, int column) {
this.line = line;
this.column = column;
contextNode = node;
}
public ASTNode<?> getContextNode() {
return contextNode;
}
public int getColumn() {
return column;
}
public int getLine() {
return line;
}
public static SourcePosition findPosition(ASTNode<?> node, int searchline, int searchcolumn) {
if (inNode(node, searchline, searchcolumn)) {
for (int i = 0; i < node.getNumChildNoTransform(); i++) {
SourcePosition pos = findPosition(node.getChildNoTransform(i), searchline, searchcolumn);
if (pos != null) {
return pos;
}
}
return new SourcePosition(node, searchline, searchcolumn);
}
return null;
}
private static boolean inNode(ASTNode<?> node, int line, int column) {
if (node instanceof Opt<?>) {
Opt<?> opt = (Opt<?>) node;
if (opt.hasChildren()) {
node = opt.getChildNoTransform(0);
} else {
return false;
}
} else if (node instanceof List<?>) {
if (node.getNumChildNoTransform() == 0) {
return false;
} else if (node.getEndLine() == 0 && node.getEndColumn() == 0) {
// if position is not set, check children
if (node.getNumChildNoTransform() == 0) {
return false;
}
if (smaller(line, column, node.getChildNoTransform(0).getStartLine(), node.getChildNoTransform(0).getStartColumn())
|| larger(line, column, node.getChildNoTransform(node.getNumChildNoTransform()-1).getEndLine(),
node.getChildNoTransform(node.getNumChildNoTransform()-1).getEndColumn())) {
return false;
}
return true;
}
}
if (smaller(line, column, node.getStartLine(), node.getStartColumn())
|| larger(line, column, node.getEndLine(), node.getEndColumn()))
return false;
return true;
}
public static boolean larger(int line1, int column1, int line2, int column2) {
return smaller(line2, column2, line1, column1);
}
public static boolean smaller(int line1, int column1, int line2, int column2) {
if (line1 < line2)
return true;
if (line1 > line2)
return false;
return column1 < column2;
}
}