Skip to content

Commit 2b5d96a

Browse files
Merge pull request #139 from NipunaRanasinghe/master
Revamp code action implementation
2 parents fe7b5f1 + 756d051 commit 2b5d96a

File tree

4 files changed

+327
-160
lines changed

4 files changed

+327
-160
lines changed

src/main/java/org/wso2/lsp4intellij/client/languageserver/ServerOptions.java

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,19 @@
2121
import org.eclipse.lsp4j.DocumentOnTypeFormattingOptions;
2222
import org.eclipse.lsp4j.ExecuteCommandOptions;
2323
import org.eclipse.lsp4j.SemanticHighlightingServerCapabilities;
24+
import org.eclipse.lsp4j.ServerCapabilities;
2425
import org.eclipse.lsp4j.SignatureHelpOptions;
2526
import org.eclipse.lsp4j.TextDocumentSyncKind;
2627

2728
/**
28-
* Class containing the options of the language server
29-
* <p>
30-
* syncKind The type of synchronization
31-
* completionOptions The completion options
32-
* signatureHelpOptions The signatureHelp options
33-
* codeLensOptions The codeLens options
34-
* documentOnTypeFormattingOptions The onTypeFormatting options
35-
* documentLinkOptions The link options
36-
* executeCommandOptions The execute options
29+
* Class containing the options of the language server.
3730
*/
31+
3832
public class ServerOptions {
3933

4034
//Todo - Revisit and implement with accessors
4135
public TextDocumentSyncKind syncKind;
36+
public ServerCapabilities capabilities;
4237
public CompletionOptions completionOptions;
4338
public SignatureHelpOptions signatureHelpOptions;
4439
public CodeLensOptions codeLensOptions;
@@ -47,19 +42,22 @@ public class ServerOptions {
4742
public ExecuteCommandOptions executeCommandOptions;
4843
public SemanticHighlightingServerCapabilities semanticHighlightingOptions;
4944

50-
public ServerOptions(TextDocumentSyncKind syncKind, CompletionOptions completionOptions,
51-
SignatureHelpOptions signatureHelpOptions, CodeLensOptions codeLensOptions,
52-
DocumentOnTypeFormattingOptions documentOnTypeFormattingOptions, DocumentLinkOptions documentLinkOptions,
53-
ExecuteCommandOptions executeCommandOptions,
54-
SemanticHighlightingServerCapabilities semanticHighlightingOptions) {
45+
public ServerOptions(ServerCapabilities serverCapabilities) {
46+
47+
this.capabilities = serverCapabilities;
48+
49+
if (capabilities.getTextDocumentSync().isRight()) {
50+
this.syncKind = capabilities.getTextDocumentSync().getRight().getChange();
51+
} else if (capabilities.getTextDocumentSync().isLeft()) {
52+
this.syncKind = capabilities.getTextDocumentSync().getLeft();
53+
}
5554

56-
this.syncKind = syncKind;
57-
this.completionOptions = completionOptions;
58-
this.signatureHelpOptions = signatureHelpOptions;
59-
this.codeLensOptions = codeLensOptions;
60-
this.documentOnTypeFormattingOptions = documentOnTypeFormattingOptions;
61-
this.documentLinkOptions = documentLinkOptions;
62-
this.executeCommandOptions = executeCommandOptions;
63-
this.semanticHighlightingOptions = semanticHighlightingOptions;
55+
this.completionOptions = capabilities.getCompletionProvider();
56+
this.signatureHelpOptions = capabilities.getSignatureHelpProvider();
57+
this.codeLensOptions = capabilities.getCodeLensProvider();
58+
this.documentOnTypeFormattingOptions = capabilities.getDocumentOnTypeFormattingProvider();
59+
this.documentLinkOptions = capabilities.getDocumentLinkProvider();
60+
this.executeCommandOptions = capabilities.getExecuteCommandProvider();
61+
this.semanticHighlightingOptions = capabilities.getSemanticHighlighting();
6462
}
6563
}

src/main/java/org/wso2/lsp4intellij/client/languageserver/wrapper/LanguageServerWrapper.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -314,34 +314,19 @@ public void connect(Editor editor) {
314314
return;
315315
}
316316
try {
317-
Either<TextDocumentSyncKind, TextDocumentSyncOptions> syncOptions = capabilities
318-
.getTextDocumentSync();
319-
TextDocumentSyncKind syncKind = null;
317+
Either<TextDocumentSyncKind, TextDocumentSyncOptions> syncOptions = capabilities.getTextDocumentSync();
320318
if (syncOptions != null) {
321-
if (syncOptions.isRight()) {
322-
syncKind = syncOptions.getRight().getChange();
323-
} else if (syncOptions.isLeft()) {
324-
syncKind = syncOptions.getLeft();
325-
}
326319
//Todo - Implement
327320
// SelectionListenerImpl selectionListener = new SelectionListenerImpl();
328321
DocumentListenerImpl documentListener = new DocumentListenerImpl();
329322
EditorMouseListenerImpl mouseListener = new EditorMouseListenerImpl();
330323
EditorMouseMotionListenerImpl mouseMotionListener = new EditorMouseMotionListenerImpl();
331324

332-
ServerOptions serverOptions = new ServerOptions(syncKind,
333-
capabilities.getCompletionProvider(), capabilities.getSignatureHelpProvider(),
334-
capabilities.getCodeLensProvider(),
335-
capabilities.getDocumentOnTypeFormattingProvider(),
336-
capabilities.getDocumentLinkProvider(),
337-
capabilities.getExecuteCommandProvider(),
338-
capabilities.getSemanticHighlighting());
339-
325+
ServerOptions serverOptions = new ServerOptions(capabilities);
340326
EditorEventManager manager;
341327
if (extManager != null) {
342-
manager = extManager
343-
.getExtendedEditorEventManagerFor(editor, documentListener, mouseListener,
344-
mouseMotionListener, requestManager, serverOptions, this);
328+
manager = extManager.getExtendedEditorEventManagerFor(editor, documentListener,
329+
mouseListener, mouseMotionListener, requestManager, serverOptions, this);
345330
if (manager == null) {
346331
manager = new EditorEventManager(editor, documentListener, mouseListener,
347332
mouseMotionListener, requestManager, serverOptions, this);

src/main/java/org/wso2/lsp4intellij/contributors/annotator/LSPAnnotator.java

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,27 @@
1818
import com.intellij.lang.annotation.Annotation;
1919
import com.intellij.lang.annotation.AnnotationHolder;
2020
import com.intellij.lang.annotation.ExternalAnnotator;
21+
import com.intellij.openapi.diagnostic.Logger;
2122
import com.intellij.openapi.editor.Editor;
2223
import com.intellij.openapi.util.TextRange;
2324
import com.intellij.openapi.vfs.VirtualFile;
2425
import com.intellij.psi.PsiFile;
25-
import org.eclipse.lsp4j.CodeAction;
26-
import org.eclipse.lsp4j.Command;
2726
import org.eclipse.lsp4j.Diagnostic;
28-
import org.eclipse.lsp4j.jsonrpc.messages.Either;
2927
import org.jetbrains.annotations.NotNull;
3028
import org.jetbrains.annotations.Nullable;
3129
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;
3530
import org.wso2.lsp4intellij.editor.EditorEventManager;
3631
import org.wso2.lsp4intellij.editor.EditorEventManagerBase;
3732
import org.wso2.lsp4intellij.utils.DocumentUtils;
3833
import org.wso2.lsp4intellij.utils.FileUtils;
3934

35+
import java.util.ArrayList;
4036
import java.util.ConcurrentModificationException;
4137
import java.util.List;
42-
import java.util.Objects;
4338

4439
public class LSPAnnotator extends ExternalAnnotator {
40+
41+
private static final Logger LOG = Logger.getInstance(LSPAnnotator.class);
4542
private static final Object RESULT = new Object();
4643

4744
@Nullable
@@ -59,7 +56,7 @@ public Object collectInformation(@NotNull PsiFile file, @NotNull Editor editor,
5956
EditorEventManager eventManager = EditorEventManagerBase.forUri(uri);
6057

6158
// 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())) {
6360
return null;
6461
}
6562
return RESULT;
@@ -81,23 +78,53 @@ public void apply(@NotNull PsiFile file, Object annotationResult, @NotNull Annot
8178
if (FileUtils.isFileSupported(virtualFile) && IntellijLanguageClient.isExtensionSupported(virtualFile)) {
8279
String uri = FileUtils.VFSToURI(virtualFile);
8380
EditorEventManager eventManager = EditorEventManagerBase.forUri(uri);
84-
85-
if (eventManager == null || eventManager.isDiagnosticsLocked()) {
81+
if (eventManager == null) {
8682
return;
8783
}
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+
}
92103
}
93104
}
94105
}
95106

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) {
97124
final List<Diagnostic> diagnostics = eventManager.getDiagnostics();
98125
final Editor editor = eventManager.editor;
99-
final String uri = FileUtils.VFSToURI(file.getVirtualFile());
100126

127+
List<Annotation> annotations = new ArrayList<>();
101128
diagnostics.forEach(d -> {
102129
final int start = DocumentUtils.LSPPosToOffset(editor, d.getRange().getStart());
103130
final int end = DocumentUtils.LSPPosToOffset(editor, d.getRange().getEnd());
@@ -123,18 +150,10 @@ private void createAnnotations(PsiFile file, AnnotationHolder holder, EditorEven
123150
break;
124151
}
125152

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);
138154
});
155+
156+
eventManager.setAnnotations(annotations);
157+
eventManager.setAnonHolder(holder);
139158
}
140159
}

0 commit comments

Comments
 (0)