package com.babel17.syntaxtree; import java.util.Comparator; public final class Location { public static class CascadingComparator implements Comparator<Location> { public int compare(Location a, Location b) { int c = a.source.compareTo(b.source); if (c != 0) return c; Location l = a.add(b); if (a.equals(l) || b.equals(l)) return 0; c = a.locate(b.line1, b.column1); if (c < 0) return 1; else return -1; } } private int line1, line2; private int column1, column2; private final Source source; public Location(Source s, int line, int column) { this(s, line, column, line, column); } public Source getSource() { return source; } private Location(Source s, int l1, int c1, int l2, int c2) { if (c1 < 1) c1 = 1; if (c2 < 1) c2 = 1; if (l1 < 1) l1 = 1; if (l2 < 1) l2 = 1; line1 = l1; column1 = c1; line2 = l2; column2 = c2; source = s; } public static boolean invalid(Location location) { if (location == null) return true; if (location.line1 <= 0 || location.line2 <= 0 || location.column1 <= 0 || location.column2 <= 0) return true; return false; } public Location normalize() { int l1 = line1; int c1 = column1; if (l1 <= 0) l1 = 1; if (c1 <= 0) c1 = 1; Location l = new Location(source, l1, c1); int w = l.locate(line2, column2); if (w < 0) return l; else return new Location(source, l1, c1, line2, column2 <= 0 ? 1 : column2); } public boolean isPoint() { return line1 == line2 && column1 == column2; } public int startLine() { return line1; } public int startColumn() { return column1; } public int endLine() { return line2; } public int endColumn() { return column2; } // -1 => before this location, 0 => in this location, 1 => after this location public int locate(int line, int column) { if (line < line1) return -1; if (line > line2) return 1; if (line == line1 && column < column1) return -1; if (line == line2 && column > column2) return 1; return 0; } public static Location merge(Location l1, Location l2) { if (l1 == null) return l2; else if (l2 == null) return l1; else return l1.add(l2); } public boolean equals(Object o) { if (!(o instanceof Location)) return false; Location l = (Location) o; if (l.line1 == line1 && l.line2 == line2 && l.column1 == column1 && l.column2 == column2 && l.source.compareTo(source) == 0) return true; else return false; } public Location add(Location loc) { int test1 = locate(loc.line1, loc.column1); int test2 = locate(loc.line2, loc.column2); if (test1 >= 0 && test2 <= 0) return this; if (test1 <= 0 && test2 >= 0) return loc; int l1, l2, c1, c2; if (test1 < 0) { l1 = loc.line1; c1 = loc.column1; } else { l1 = line1; c1 = column1; } if (test2 > 0) { l2 = loc.line2; c2 = loc.column2; } else { l2 = line2; c2 = column2; } return new Location(source, l1, c1, l2, c2); } public Location shift(int deltal, int deltac) { if (deltac + column1 < 1) deltac = 1-column1; if (deltal + line1 < 1) deltal = 1-line1; return new Location(source, line1+deltal, column1+deltac, line2+deltal, column2+deltac); } public String toString() { String s = source.toString(); return s+" ("+line1+":"+column1+"-"+line2+":"+column2+")"; } }