18
18
import com .intellij .lang .annotation .Annotation ;
19
19
import com .intellij .lang .annotation .AnnotationHolder ;
20
20
import com .intellij .lang .annotation .ExternalAnnotator ;
21
+ import com .intellij .openapi .diagnostic .Logger ;
21
22
import com .intellij .openapi .editor .Editor ;
22
23
import com .intellij .openapi .util .TextRange ;
23
24
import com .intellij .openapi .vfs .VirtualFile ;
24
25
import com .intellij .psi .PsiFile ;
25
- import org .eclipse .lsp4j .CodeAction ;
26
- import org .eclipse .lsp4j .Command ;
27
26
import org .eclipse .lsp4j .Diagnostic ;
28
- import org .eclipse .lsp4j .jsonrpc .messages .Either ;
29
27
import org .jetbrains .annotations .NotNull ;
30
28
import org .jetbrains .annotations .Nullable ;
31
29
import org .wso2 .lsp4intellij .IntellijLanguageClient ;
32
- import org .wso2 .lsp4intellij .contributors .fixes .LSPCodeActionFix ;
33
- import org .wso2 .lsp4intellij .contributors .fixes .LSPCommandFix ;
34
- import org .wso2 .lsp4intellij .contributors .psi .LSPPsiElement ;
35
30
import org .wso2 .lsp4intellij .editor .EditorEventManager ;
36
31
import org .wso2 .lsp4intellij .editor .EditorEventManagerBase ;
37
32
import org .wso2 .lsp4intellij .utils .DocumentUtils ;
38
33
import org .wso2 .lsp4intellij .utils .FileUtils ;
39
34
35
+ import java .util .ArrayList ;
40
36
import java .util .ConcurrentModificationException ;
41
37
import java .util .List ;
42
- import java .util .Objects ;
43
38
44
39
public class LSPAnnotator extends ExternalAnnotator {
40
+
41
+ private static final Logger LOG = Logger .getInstance (LSPAnnotator .class );
45
42
private static final Object RESULT = new Object ();
46
43
47
44
@ Nullable
@@ -59,7 +56,7 @@ public Object collectInformation(@NotNull PsiFile file, @NotNull Editor editor,
59
56
EditorEventManager eventManager = EditorEventManagerBase .forUri (uri );
60
57
61
58
// If the diagnostics list is locked, we need to skip annotating the file.
62
- if (eventManager == null || eventManager .isDiagnosticsLocked ( )) {
59
+ if (eventManager == null || !( eventManager .isDiagnosticSyncRequired () || eventManager . isCodeActionSyncRequired () )) {
63
60
return null ;
64
61
}
65
62
return RESULT ;
@@ -81,23 +78,53 @@ public void apply(@NotNull PsiFile file, Object annotationResult, @NotNull Annot
81
78
if (FileUtils .isFileSupported (virtualFile ) && IntellijLanguageClient .isExtensionSupported (virtualFile )) {
82
79
String uri = FileUtils .VFSToURI (virtualFile );
83
80
EditorEventManager eventManager = EditorEventManagerBase .forUri (uri );
84
-
85
- if (eventManager == null || eventManager .isDiagnosticsLocked ()) {
81
+ if (eventManager == null ) {
86
82
return ;
87
83
}
88
- try {
89
- createAnnotations (file , holder , eventManager );
90
- } catch (ConcurrentModificationException e ) {
91
- // Todo
84
+
85
+ if (eventManager .isCodeActionSyncRequired ()) {
86
+ try {
87
+ updateAnnotations (holder , eventManager );
88
+ } catch (ConcurrentModificationException e ) {
89
+ // Todo - Add proper fix to handle concurrent modifications gracefully.
90
+ LOG .warn ("Error occurred when updating LSP diagnostics due to concurrent modifications." , e );
91
+ } catch (Throwable t ) {
92
+ LOG .warn ("Error occurred when updating LSP diagnostics." , t );
93
+ }
94
+ } else if (eventManager .isDiagnosticSyncRequired ()) {
95
+ try {
96
+ createAnnotations (holder , eventManager );
97
+ } catch (ConcurrentModificationException e ) {
98
+ // Todo - Add proper fix to handle concurrent modifications gracefully.
99
+ LOG .warn ("Error occurred when updating LSP code actions due to concurrent modifications." , e );
100
+ } catch (Throwable t ) {
101
+ LOG .warn ("Error occurred when updating LSP code actions." , t );
102
+ }
92
103
}
93
104
}
94
105
}
95
106
96
- private void createAnnotations (PsiFile file , AnnotationHolder holder , EditorEventManager eventManager ) {
107
+ private void updateAnnotations (AnnotationHolder holder , EditorEventManager eventManager ) {
108
+ final List <Annotation > annotations = eventManager .getAnnotations ();
109
+ if (annotations == null ) {
110
+ return ;
111
+ }
112
+ annotations .forEach (annotation -> {
113
+ Annotation anon = holder .createAnnotation (annotation .getSeverity (),
114
+ new TextRange (annotation .getStartOffset (), annotation .getEndOffset ()), annotation .getMessage ());
115
+
116
+ if (annotation .getQuickFixes () == null || annotation .getQuickFixes ().isEmpty ()) {
117
+ return ;
118
+ }
119
+ annotation .getQuickFixes ().forEach (quickFixInfo -> anon .registerFix (quickFixInfo .quickFix ));
120
+ });
121
+ }
122
+
123
+ private void createAnnotations (AnnotationHolder holder , EditorEventManager eventManager ) {
97
124
final List <Diagnostic > diagnostics = eventManager .getDiagnostics ();
98
125
final Editor editor = eventManager .editor ;
99
- final String uri = FileUtils .VFSToURI (file .getVirtualFile ());
100
126
127
+ List <Annotation > annotations = new ArrayList <>();
101
128
diagnostics .forEach (d -> {
102
129
final int start = DocumentUtils .LSPPosToOffset (editor , d .getRange ().getStart ());
103
130
final int end = DocumentUtils .LSPPosToOffset (editor , d .getRange ().getEnd ());
@@ -123,18 +150,10 @@ private void createAnnotations(PsiFile file, AnnotationHolder holder, EditorEven
123
150
break ;
124
151
}
125
152
126
- final String name = editor .getDocument ().getText (textRange );
127
- final LSPPsiElement element = new LSPPsiElement (name , editor .getProject (), start , end , file );
128
- final List <Either <Command , CodeAction >> codeAction = eventManager .codeAction (element );
129
- if (codeAction != null ) {
130
- codeAction .stream ().filter (Objects ::nonNull ).forEach (e -> {
131
- if (e .isLeft ()) {
132
- annotation .registerFix (new LSPCommandFix (uri , e .getLeft ()), textRange );
133
- } else if (e .isRight ()) {
134
- annotation .registerFix (new LSPCodeActionFix (uri , e .getRight ()), textRange );
135
- }
136
- });
137
- }
153
+ annotations .add (annotation );
138
154
});
155
+
156
+ eventManager .setAnnotations (annotations );
157
+ eventManager .setAnonHolder (holder );
139
158
}
140
159
}
0 commit comments