Skip to content

Commit

Permalink
Merge pull request #139 from NipunaRanasinghe/master
Browse files Browse the repository at this point in the history
Revamp code action implementation
  • Loading branch information
NipunaRanasinghe authored Sep 24, 2019
2 parents fe7b5f1 + 756d051 commit 2b5d96a
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,19 @@
import org.eclipse.lsp4j.DocumentOnTypeFormattingOptions;
import org.eclipse.lsp4j.ExecuteCommandOptions;
import org.eclipse.lsp4j.SemanticHighlightingServerCapabilities;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.SignatureHelpOptions;
import org.eclipse.lsp4j.TextDocumentSyncKind;

/**
* Class containing the options of the language server
* <p>
* syncKind The type of synchronization
* completionOptions The completion options
* signatureHelpOptions The signatureHelp options
* codeLensOptions The codeLens options
* documentOnTypeFormattingOptions The onTypeFormatting options
* documentLinkOptions The link options
* executeCommandOptions The execute options
* Class containing the options of the language server.
*/

public class ServerOptions {

//Todo - Revisit and implement with accessors
public TextDocumentSyncKind syncKind;
public ServerCapabilities capabilities;
public CompletionOptions completionOptions;
public SignatureHelpOptions signatureHelpOptions;
public CodeLensOptions codeLensOptions;
Expand All @@ -47,19 +42,22 @@ public class ServerOptions {
public ExecuteCommandOptions executeCommandOptions;
public SemanticHighlightingServerCapabilities semanticHighlightingOptions;

public ServerOptions(TextDocumentSyncKind syncKind, CompletionOptions completionOptions,
SignatureHelpOptions signatureHelpOptions, CodeLensOptions codeLensOptions,
DocumentOnTypeFormattingOptions documentOnTypeFormattingOptions, DocumentLinkOptions documentLinkOptions,
ExecuteCommandOptions executeCommandOptions,
SemanticHighlightingServerCapabilities semanticHighlightingOptions) {
public ServerOptions(ServerCapabilities serverCapabilities) {

this.capabilities = serverCapabilities;

if (capabilities.getTextDocumentSync().isRight()) {
this.syncKind = capabilities.getTextDocumentSync().getRight().getChange();
} else if (capabilities.getTextDocumentSync().isLeft()) {
this.syncKind = capabilities.getTextDocumentSync().getLeft();
}

this.syncKind = syncKind;
this.completionOptions = completionOptions;
this.signatureHelpOptions = signatureHelpOptions;
this.codeLensOptions = codeLensOptions;
this.documentOnTypeFormattingOptions = documentOnTypeFormattingOptions;
this.documentLinkOptions = documentLinkOptions;
this.executeCommandOptions = executeCommandOptions;
this.semanticHighlightingOptions = semanticHighlightingOptions;
this.completionOptions = capabilities.getCompletionProvider();
this.signatureHelpOptions = capabilities.getSignatureHelpProvider();
this.codeLensOptions = capabilities.getCodeLensProvider();
this.documentOnTypeFormattingOptions = capabilities.getDocumentOnTypeFormattingProvider();
this.documentLinkOptions = capabilities.getDocumentLinkProvider();
this.executeCommandOptions = capabilities.getExecuteCommandProvider();
this.semanticHighlightingOptions = capabilities.getSemanticHighlighting();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -314,34 +314,19 @@ public void connect(Editor editor) {
return;
}
try {
Either<TextDocumentSyncKind, TextDocumentSyncOptions> syncOptions = capabilities
.getTextDocumentSync();
TextDocumentSyncKind syncKind = null;
Either<TextDocumentSyncKind, TextDocumentSyncOptions> syncOptions = capabilities.getTextDocumentSync();
if (syncOptions != null) {
if (syncOptions.isRight()) {
syncKind = syncOptions.getRight().getChange();
} else if (syncOptions.isLeft()) {
syncKind = syncOptions.getLeft();
}
//Todo - Implement
// SelectionListenerImpl selectionListener = new SelectionListenerImpl();
DocumentListenerImpl documentListener = new DocumentListenerImpl();
EditorMouseListenerImpl mouseListener = new EditorMouseListenerImpl();
EditorMouseMotionListenerImpl mouseMotionListener = new EditorMouseMotionListenerImpl();

ServerOptions serverOptions = new ServerOptions(syncKind,
capabilities.getCompletionProvider(), capabilities.getSignatureHelpProvider(),
capabilities.getCodeLensProvider(),
capabilities.getDocumentOnTypeFormattingProvider(),
capabilities.getDocumentLinkProvider(),
capabilities.getExecuteCommandProvider(),
capabilities.getSemanticHighlighting());

ServerOptions serverOptions = new ServerOptions(capabilities);
EditorEventManager manager;
if (extManager != null) {
manager = extManager
.getExtendedEditorEventManagerFor(editor, documentListener, mouseListener,
mouseMotionListener, requestManager, serverOptions, this);
manager = extManager.getExtendedEditorEventManagerFor(editor, documentListener,
mouseListener, mouseMotionListener, requestManager, serverOptions, this);
if (manager == null) {
manager = new EditorEventManager(editor, documentListener, mouseListener,
mouseMotionListener, requestManager, serverOptions, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,27 @@
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.ExternalAnnotator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.wso2.lsp4intellij.IntellijLanguageClient;
import org.wso2.lsp4intellij.contributors.fixes.LSPCodeActionFix;
import org.wso2.lsp4intellij.contributors.fixes.LSPCommandFix;
import org.wso2.lsp4intellij.contributors.psi.LSPPsiElement;
import org.wso2.lsp4intellij.editor.EditorEventManager;
import org.wso2.lsp4intellij.editor.EditorEventManagerBase;
import org.wso2.lsp4intellij.utils.DocumentUtils;
import org.wso2.lsp4intellij.utils.FileUtils;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Objects;

public class LSPAnnotator extends ExternalAnnotator {

private static final Logger LOG = Logger.getInstance(LSPAnnotator.class);
private static final Object RESULT = new Object();

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

// If the diagnostics list is locked, we need to skip annotating the file.
if (eventManager == null || eventManager.isDiagnosticsLocked()) {
if (eventManager == null || !(eventManager.isDiagnosticSyncRequired() || eventManager.isCodeActionSyncRequired())) {
return null;
}
return RESULT;
Expand All @@ -81,23 +78,53 @@ public void apply(@NotNull PsiFile file, Object annotationResult, @NotNull Annot
if (FileUtils.isFileSupported(virtualFile) && IntellijLanguageClient.isExtensionSupported(virtualFile)) {
String uri = FileUtils.VFSToURI(virtualFile);
EditorEventManager eventManager = EditorEventManagerBase.forUri(uri);

if (eventManager == null || eventManager.isDiagnosticsLocked()) {
if (eventManager == null) {
return;
}
try {
createAnnotations(file, holder, eventManager);
} catch (ConcurrentModificationException e) {
// Todo

if (eventManager.isCodeActionSyncRequired()) {
try {
updateAnnotations(holder, eventManager);
} catch (ConcurrentModificationException e) {
// Todo - Add proper fix to handle concurrent modifications gracefully.
LOG.warn("Error occurred when updating LSP diagnostics due to concurrent modifications.", e);
} catch (Throwable t) {
LOG.warn("Error occurred when updating LSP diagnostics.", t);
}
} else if (eventManager.isDiagnosticSyncRequired()) {
try {
createAnnotations(holder, eventManager);
} catch (ConcurrentModificationException e) {
// Todo - Add proper fix to handle concurrent modifications gracefully.
LOG.warn("Error occurred when updating LSP code actions due to concurrent modifications.", e);
} catch (Throwable t) {
LOG.warn("Error occurred when updating LSP code actions.", t);
}
}
}
}

private void createAnnotations(PsiFile file, AnnotationHolder holder, EditorEventManager eventManager) {
private void updateAnnotations(AnnotationHolder holder, EditorEventManager eventManager) {
final List<Annotation> annotations = eventManager.getAnnotations();
if (annotations == null) {
return;
}
annotations.forEach(annotation -> {
Annotation anon = holder.createAnnotation(annotation.getSeverity(),
new TextRange(annotation.getStartOffset(), annotation.getEndOffset()), annotation.getMessage());

if (annotation.getQuickFixes() == null || annotation.getQuickFixes().isEmpty()) {
return;
}
annotation.getQuickFixes().forEach(quickFixInfo -> anon.registerFix(quickFixInfo.quickFix));
});
}

private void createAnnotations(AnnotationHolder holder, EditorEventManager eventManager) {
final List<Diagnostic> diagnostics = eventManager.getDiagnostics();
final Editor editor = eventManager.editor;
final String uri = FileUtils.VFSToURI(file.getVirtualFile());

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

final String name = editor.getDocument().getText(textRange);
final LSPPsiElement element = new LSPPsiElement(name, editor.getProject(), start, end, file);
final List<Either<Command, CodeAction>> codeAction = eventManager.codeAction(element);
if (codeAction != null) {
codeAction.stream().filter(Objects::nonNull).forEach(e -> {
if (e.isLeft()) {
annotation.registerFix(new LSPCommandFix(uri, e.getLeft()), textRange);
} else if (e.isRight()) {
annotation.registerFix(new LSPCodeActionFix(uri, e.getRight()), textRange);
}
});
}
annotations.add(annotation);
});

eventManager.setAnnotations(annotations);
eventManager.setAnonHolder(holder);
}
}
Loading

0 comments on commit 2b5d96a

Please sign in to comment.