a3253a43bc2b6f352e61e0b0117d62df35b364b5
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / asm / editor / AsmReconcilerStrategy.java
1 package net.mograsim.plugin.asm.editor;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.jface.text.BadLocationException;
10 import org.eclipse.jface.text.IDocument;
11 import org.eclipse.jface.text.IRegion;
12 import org.eclipse.jface.text.Position;
13 import org.eclipse.jface.text.reconciler.DirtyRegion;
14 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
15 import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
16 import org.eclipse.jface.text.source.Annotation;
17 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
18 import org.eclipse.jface.text.source.projection.ProjectionViewer;
19
20 public class AsmReconcilerStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension
21 {
22         private IDocument document;
23         private String oldDocument;
24         private ProjectionViewer projectionViewer;
25         private List<Annotation> oldAnnotations = new ArrayList<>();
26         private List<Position> oldPositions = new ArrayList<>();
27
28         @Override
29         public void setDocument(IDocument document)
30         {
31                 this.document = document;
32         }
33
34         public void setProjectionViewer(ProjectionViewer projectionViewer)
35         {
36                 this.projectionViewer = projectionViewer;
37         }
38
39         @Override
40         public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion)
41         {
42                 initialReconcile();
43         }
44
45         @Override
46         public void reconcile(IRegion partition)
47         {
48                 initialReconcile();
49         }
50
51         @Override
52         public void initialReconcile()
53         {
54                 if (document.get().equals(oldDocument))
55                         return;
56                 oldDocument = document.get();
57
58                 List<Position> positions = getNewPositionsOfAnnotations();
59
60                 List<Position> positionsToRemove = new ArrayList<>();
61                 List<Annotation> annotationToRemove = new ArrayList<>();
62
63                 for (Position position : oldPositions)
64                 {
65                         if (!positions.contains(position))
66                         {
67                                 projectionViewer.getProjectionAnnotationModel().removeAnnotation(oldAnnotations.get(oldPositions.indexOf(position)));
68                                 positionsToRemove.add(position);
69                                 annotationToRemove.add(oldAnnotations.get(oldPositions.indexOf(position)));
70                         } else
71                         {
72                                 positions.remove(position);
73                         }
74                 }
75                 oldPositions.removeAll(positionsToRemove);
76                 oldAnnotations.removeAll(annotationToRemove);
77
78                 for (Position position : positions)
79                 {
80                         Annotation annotation = new ProjectionAnnotation();
81                         projectionViewer.getProjectionAnnotationModel().addAnnotation(annotation, position);
82                         oldPositions.add(position);
83                         oldAnnotations.add(annotation);
84                 }
85         }
86
87         private static enum SearchingFor
88         {
89                 START_OF_TAG, START_OF_WORD, END_OF_WORD, END_OF_LINE
90         }
91
92         private List<Position> getNewPositionsOfAnnotations()
93         {
94                 List<Position> positions = new ArrayList<>();
95                 Map<String, Integer> startOfAnnotation = new HashMap<>();
96                 SearchingFor searchingFor = SearchingFor.START_OF_TAG;
97
98                 int characters = document.getLength();
99                 int currentCharIndex = 0;
100
101                 int wordStartIndex = 0;
102                 int sectionStartIndex = 0;
103                 String word = "";
104
105                 try
106                 {
107                         while (currentCharIndex < characters)
108                         {
109                                 char currentChar = document.getChar(currentCharIndex);
110                                 switch (searchingFor)
111                                 {
112                                 case START_OF_TAG:
113                                         if (currentChar == '<')
114                                         {
115                                                 char nextChar = document.getChar(currentCharIndex + 1);
116                                                 if (nextChar != '?')
117                                                 {
118                                                         sectionStartIndex = currentCharIndex;
119                                                         searchingFor = SearchingFor.START_OF_WORD;
120                                                 }
121                                         }
122                                         break;
123                                 case START_OF_WORD:
124                                         if (Character.isLetter(currentChar))
125                                         {
126                                                 wordStartIndex = currentCharIndex;
127                                                 searchingFor = SearchingFor.END_OF_WORD;
128                                         }
129                                         break;
130                                 case END_OF_WORD:
131                                         if (!Character.isLetter(currentChar))
132                                         {
133                                                 word = document.get(wordStartIndex, currentCharIndex - wordStartIndex);
134                                                 if (startOfAnnotation.containsKey(word))
135                                                 {
136                                                         searchingFor = SearchingFor.END_OF_LINE;
137                                                 } else
138                                                 {
139                                                         startOfAnnotation.put(word, sectionStartIndex);
140                                                         searchingFor = SearchingFor.START_OF_TAG;
141                                                 }
142                                         }
143                                         break;
144                                 case END_OF_LINE:
145                                         if (currentChar == '\n')
146                                         {
147                                                 int start = startOfAnnotation.get(word);
148                                                 if (document.getLineOfOffset(start) != document.getLineOfOffset(currentCharIndex))
149                                                 {
150                                                         positions.add(new Position(start, currentCharIndex + 1 - start));
151                                                 }
152                                                 startOfAnnotation.remove(word);
153                                                 searchingFor = SearchingFor.START_OF_TAG;
154                                         }
155                                         break;
156                                 }
157                                 currentCharIndex++;
158                         }
159                 }
160                 catch (BadLocationException e)
161                 {
162                         // skip the remainder of file due to error
163                 }
164                 return positions;
165         }
166
167         @Override
168         public void setProgressMonitor(IProgressMonitor monitor)
169         {
170                 // no progress monitor used
171         }
172
173 }