package org.simantics.scl.compiler.errors; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import gnu.trove.list.array.TIntArrayList; public class CompilationErrorFormatter { public static int[] rows(Reader reader) throws IOException { TIntArrayList rows = new TIntArrayList(); rows.add(0); int i=0; while(true) { ++i; int c = reader.read(); if(c < 0) break; if(c == '\n') rows.add(i); } reader.close(); return rows.toArray(); } public static int lineNumber(int[] rows, int location) { if(location < 0) return 1; if(location >= rows[rows.length-1]) return rows.length; int a = 0; int b = rows.length-1; while(b-a > 1) { int c = (a+b)/2; if(rows[c] <= location) a = c; else b = c; } return a+1; } private static String locationToString(int[] rows, int location) { if(location == -1) return "?"; if(location >= rows[rows.length-1]) return rows.length + ":" + (location - rows[rows.length-1] + 1); int a = 0; int b = rows.length-1; while(b-a > 1) { int c = (a+b)/2; if(rows[c] <= location) a = c; else b = c; } return (a+1) + ":" + (location - rows[a] + 1); } public static String toString(String source, CompilationError[] errors) { return toString(new StringReader(source), errors); } public static String toString(Reader source, CompilationError[] errors) { int[] rows; try { if(source != null) rows = rows(source); else rows = new int[] {0}; } catch(IOException e) { rows = new int[] {0}; } StringBuilder b = new StringBuilder(); boolean first = true; for(CompilationError error : errors) { if(first) first = false; else b.append('\n'); b.append(locationToString(rows, Locations.beginOf(error.location)) + "-" + locationToString(rows, Locations.endOf(error.location)) + ": " + error.description); } return b.toString(); } public static String toString(CompilationError[] errors) { return toString((Reader)null, errors); } }