]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / errors / CompilationErrorFormatter.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java
new file mode 100644 (file)
index 0000000..bd29b32
--- /dev/null
@@ -0,0 +1,93 @@
+package org.simantics.scl.compiler.errors;
+
+import gnu.trove.list.array.TIntArrayList;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+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);
+    }
+}