API for accessing parse errors

Tor Norbye <[email protected]>
Newsgroups gmane.comp.java.netbeans.modules.tasklist.devel
Organization Sun Microsystems, Inc
Message-ID <1039910120.8888.1764.camel@proto>
Hi java module developers,
in the tasklist module I now have a suggestions window which lists
the current parsing errors in the file. (It also tries to add suggestions
for fixing these; currently, this means providing import-class 
suggestions based on the code completion database).

To do this, I'm accessing the "ParseAnnotation" objects associated
with the java editor for each data object.  I had to change two things:
- Make a couple of fields in the ParseAnnotation public such that I
  could get to it: the line number, the column number, etc.
- Add a listener-notification of when the annotation-list for each
  editor changes

The tasklist module has a patch that users can apply, but I think
it would be really nice if the java module had a facility like this
such that no patch would be necessary, and users could get the
tasklist module from the Update Center and it would work (now they
have to build from sources, know how to patch, etc.)

Is there any chance that something like this could be added to
the java module? I'll gladly provide patches if yes.

I think making the getters in the ParseAnnotation class public should
be fairly uncontroversial.

What you may object to is providing access to the list of annotations
for the Java Editor.

My diffs were trying to make as few changes as possible - not just to
save time, but to make merging/patching conflicts as unlikely as
possible.

But if we create a new interface, say "ParseError", which has the
methods (list of relevant methods from ParseAnnotation here, e.g.
getDescription, getLine, getColumn, ...) and then ParseAnnotation
can implement that interface.

Then Java Editor can have
   List getErrors()   (returns annotations list containing ParseErrors)
   void addErrorListener(ErrorListener l)
   void removeErrorListener(ErrorListener l)
where ErrorListener is an interface with a single method
   errorsChanged()

My diff currently has the above methods, except for the ParseError
interface; clients cast to ParseAnnotation.  If you like defensive
copying, List getErrors() could be ParseError[] getErrors instead.

Does this sound okay? Any chance of getting this into the java
module? 

-- Tor

(Here's the patch in its current form; see tasklist/javaparser/patches
in CVS for the current version)

Index: src/org/netbeans/modules/java/JavaEditor.java
===================================================================
RCS file: /cvs/java/src/org/netbeans/modules/java/JavaEditor.java,v
retrieving revision 1.129
diff -u -r1.129 JavaEditor.java
--- src/org/netbeans/modules/java/JavaEditor.java	3 Sep 2002 14:04:41 -0000	1.129
+++ src/org/netbeans/modules/java/JavaEditor.java	6 Dec 2002 21:55:51 -0000
@@ -201,6 +201,49 @@
         }
     }
     
+    
+    List errorListeners = null;
+    
+    public interface ErrorListener {
+        /** List of ParseAnnotations. May be null. */
+        void errorsChanged(List errors);
+    }
+    
+    synchronized public void addErrorListener(ErrorListener l) {
+        if (errorListeners == null) {
+            errorListeners = new ArrayList(4); // not many listeners anticipated
+        }
+        // errorListeners.remove(l); // prevent duplicate registrations
+        errorListeners.add(l);
+    }
+    
+    
+    synchronized public void removeErrorListener(ErrorListener l) {
+        if (errorListeners != null) {
+            errorListeners.remove(l);
+        }
+    }
+    
+    void notifyErrorsChanged(List errors) {
+        if (errorListeners == null) {
+            return;
+        }
+        // TODO Consider cloning listener array if you think
+        // there's going to be contention -- but I highly
+        // doubt that int this case. DO IT if these methods
+        // are made public.
+        Iterator it = errorListeners.iterator();
+        while (it.hasNext()) {
+            ErrorListener l = (ErrorListener)it.next();
+            l.errorsChanged(errors);
+        }
+    }
+
+    public List getAnnotations() {
+        return annotations;
+    }
+        
+    
     private void parseSource(int priority,boolean ignoreClean) {
         JavaParser parser = findParser();
         Task t;
@@ -454,9 +497,10 @@
         }
         annotations=unchanged;
         annotations.addAll(added);
+        notifyErrorsChanged(annotations);
     }
     
-    private static void detachAnnotations(Collection anns) {
+    private void detachAnnotations(Collection anns) {
         Iterator i;
 
         for (i=anns.iterator();i.hasNext();) {
@@ -464,8 +508,9 @@
             
             ann.detach();
         }
+        notifyErrorsChanged(annotations);
     }
-        
+    
     // ==================== SourceCookie.Editor methods =================
 
     /** Returns a source element describing the hierarchy of the source.
Index: src/org/netbeans/modules/java/parser/ParserAnnotation.java
===================================================================
RCS file: /cvs/java/src/org/netbeans/modules/java/parser/ParserAnnotation.java,v
retrieving revision 1.7
diff -u -r1.7 ParserAnnotation.java
--- src/org/netbeans/modules/java/parser/ParserAnnotation.java	17 Jun 2002 16:40:11 -0000	1.7
+++ src/org/netbeans/modules/java/parser/ParserAnnotation.java	6 Dec 2002 21:55:51 -0000
@@ -61,15 +61,19 @@
         return error;
     }
     
-    int getLine() {
+    public int getLine() {
         return line;
     }
     
-    int getColumn() {
+    public int getColumn() {
         return column;
     }
     
-    String getError() {
+    public Line getDocLine() {
+        return docline;
+    }
+    
+    public String getError() {
         return error;
     }
     

-- 
Tor Norbye <[email protected]>
Sun Microsystems, Inc
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.