(refs #7284) Fixed SCLAnnotationModel to cope invalid error ranges
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / editor2 / SCLAnnotationModel.java
1 package org.simantics.scl.ui.editor2;
2
3 import java.util.Arrays;
4 import java.util.Collections;
5 import java.util.List;
6
7 import org.eclipse.jface.text.IDocument;
8 import org.eclipse.jface.text.Position;
9 import org.eclipse.jface.text.source.Annotation;
10 import org.eclipse.jface.text.source.AnnotationModel;
11 import org.simantics.scl.compiler.errors.CompilationError;
12 import org.simantics.scl.compiler.errors.DoesNotExist;
13 import org.simantics.scl.compiler.errors.ErrorSeverity;
14 import org.simantics.scl.compiler.errors.Failable;
15 import org.simantics.scl.compiler.errors.Failure;
16 import org.simantics.scl.compiler.errors.Locations;
17 import org.simantics.scl.compiler.module.Module;
18 import org.simantics.scl.compiler.module.repository.ModuleRepository;
19 import org.simantics.scl.compiler.module.repository.UpdateListener;
20
21 public class SCLAnnotationModel extends AnnotationModel {
22     private final SCLModuleEditorInput input;
23     private final ModuleRepository repository;
24     private volatile boolean connected = false;
25     
26     public SCLAnnotationModel(SCLModuleEditorInput input,
27             ModuleRepository repository) {
28         this.input = input;
29         this.repository = repository;
30     }
31     
32     UpdateListener updateListener = new UpdateListener() {
33         @Override
34         public void notifyAboutUpdate() {
35             if(connected)
36                 updateAnnotations();
37         }
38     };
39     
40     private void updateAnnotations() {
41         Failable<Module> result = repository.getModule(input.getModuleName(), updateListener);
42         if(result instanceof Failure) {
43             Failure failure = (Failure)result;
44             setAnnotations(Arrays.asList(failure.errors));
45         }
46         else if(result == DoesNotExist.INSTANCE)
47             setAnnotations(Collections.<CompilationError>emptyList());
48         else
49             setAnnotations(Arrays.asList(result.getResult().getWarnings()));
50     }
51     
52     protected void setAnnotations(List<CompilationError> errors) {
53         synchronized(getLockObject()) {
54             removeAllAnnotations();
55             for(CompilationError error : errors) {
56                 Annotation annotation = new Annotation(
57                         error.severity == ErrorSeverity.ERROR ?
58                                 "org.eclipse.ui.workbench.texteditor.error" :
59                                     "org.eclipse.ui.workbench.texteditor.warning",
60                                     true, error.description);
61                 int begin = Locations.beginOf(error.location);
62                 int end = Locations.endOf(error.location);
63                 if(begin < 0 || end < begin) {
64                     begin = 0;
65                     end = 1;
66                 }
67                 Position position = new Position(begin, end - begin);
68                 addAnnotation(annotation, position);
69             }
70         }
71     }
72
73     @Override
74     public void connect(IDocument document) {
75         super.connect(document);
76         connected = true;
77         updateAnnotations();
78     }
79     
80     @Override
81     public void disconnect(IDocument document) {
82         connected = false;
83         updateListener.stopListening();
84         super.disconnect(document);
85     }
86 }