Index: src/org/python/indexer/Diagnostic.java =================================================================== --- src/org/python/indexer/Diagnostic.java (revision 6429:ba74f5e6dcd8) +++ src/org/python/indexer/Diagnostic.java (revision 6429+:ba74f5e6dcd8+) @@ -15,6 +15,7 @@ public int end; public int line; public int column; + public int length; public String msg; public Diagnostic(String file, Type type, int start, int end, String msg) { @@ -25,10 +26,19 @@ this.msg = msg; } - // XXX: support line/column + public Diagnostic(String file, Type type, int line, int column, int length, String msg) { + this.type = type; + this.file = file; + this.line = line; + this.column = column; + this.length = length; + this.msg = msg; + } @Override public String toString() { - return ""; + return ""; } } Index: src/org/python/indexer/AstCache.java =================================================================== --- src/org/python/indexer/AstCache.java (revision 6429:ba74f5e6dcd8) +++ src/org/python/indexer/AstCache.java (revision 6429+:ba74f5e6dcd8+) @@ -224,9 +224,16 @@ List diags = Indexer.idx.getParseErrs(path); for (RecognitionException rx : errs) { String msg = rx.line + ":" + rx.charPositionInLine + ":" + rx; - diags.add(new Diagnostic(path, Diagnostic.Type.ERROR, -1, -1, msg)); + if (rx.token != null) { + int errorLength = rx.token.getText() != null ? rx.token.getText().length() : 1; + diags.add(new Diagnostic(path, Diagnostic.Type.ERROR, rx.token.getLine(), + rx.token.getCharPositionInLine(), errorLength, msg)); + } else { + diags.add(new Diagnostic(path, Diagnostic.Type.ERROR, rx.line, rx.charPositionInLine, + 1 /* error length */, msg)); - } - } + } + } + } /** * Each source file's AST is saved in an object file named for the MD5 Index: tests/java/org/python/indexer/IndexerTest.java =================================================================== --- tests/java/org/python/indexer/IndexerTest.java (revision 6429:ba74f5e6dcd8) +++ tests/java/org/python/indexer/IndexerTest.java (revision 6429+:ba74f5e6dcd8+) @@ -1189,4 +1189,17 @@ assertFunctionBinding("deco.foo"); assertCall("deco.deco1", nthIndexOf(src, "deco1", 2)); } + + public void testIndexerDiagnostics() throws Exception { + index( + "broken.py", + "def a main():", + " pass"); + List diagnostics = idx.parseErrs.get("broken.py"); + assertEquals(1, diagnostics.size()); + Diagnostic error = diagnostics.get(0); + assertEquals(1, error.line); + assertEquals(6, error.column); + assertEquals(4, error.length); -} + } +}