Skip to content

Commit

Permalink
refactor: execute IndexAwareLanguageClient.runAsBackground in read ac…
Browse files Browse the repository at this point in the history
…tion by default

Signed-off-by: Fred Bricon <[email protected]>
  • Loading branch information
fbricon authored and angelozerr committed Jun 22, 2023
1 parent 0db1d02 commit b6b4b8d
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 165 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
******************************************************************************/
package com.redhat.devtools.intellij.lsp4ij;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -30,13 +32,32 @@ public IndexAwareLanguageClient(Project project) {
super(project);
}

/**
* Run the given function as a background task, wrapped in a read action
* @param title the title of the action being run
* @param function the function to execute in the background
* @return the output of the function
* @param <R> the return type
*/
protected <R> CompletableFuture<R> runAsBackground(String title, Function<ProgressIndicator, R> function) {
return runAsBackground(title, function, true);
}

/**
* Run the given function as a background task, which can be wrapped in a read action
* @param title the title of the action being run
* @param function the function to execute in the background
* @param inReadAction whether to wrap the function call in a read action or not
* @return the output of the function
* @param <R> the return type
*/
protected <R> CompletableFuture<R> runAsBackground(String title, Function<ProgressIndicator, R> function, boolean inReadAction) {
CompletableFuture<R> future = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
Runnable task = () -> ProgressManager.getInstance().run(new Task.Backgroundable(getProject(), title) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
runTask(indicator, future, function);
runTask(indicator, future, function, inReadAction);
}

@Override
Expand All @@ -53,20 +74,26 @@ public boolean isHeadless() {
return future;
}

private <R> void runTask(@NotNull ProgressIndicator indicator, CompletableFuture<R> future, Function<ProgressIndicator, R> function) {
private <R> void runTask(@NotNull ProgressIndicator indicator, CompletableFuture<R> future, Function<ProgressIndicator, R> function, boolean inReadAction) {
boolean done = false;
for(int i=0; !done && i < 10;++i) {
try {
future.complete(function.apply(indicator));
R result;
if (inReadAction) {
result = ApplicationManager.getApplication().runReadAction((Computable<R>)() -> function.apply(indicator));
} else {
result = function.apply(indicator);
}
future.complete(result);
done = true;
} catch (IndexNotReadyException e) {
} catch (IndexNotReadyException ignored) {
} catch (Throwable t) {
future.completeExceptionally(t);
done = true;
}
}
if (!done) {
DumbService.getInstance(getProject()).runWhenSmart(() -> runTask(indicator, future, function));
DumbService.getInstance(getProject()).runWhenSmart(() -> runTask(indicator, future, function, inReadAction));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@ public ProjectLabelInfoEntry getProjectLabelInfo(MicroProfileJavaProjectLabelsPa
// The uri doesn't belong to an Eclipse project
return ProjectLabelInfoEntry.EMPTY_PROJECT_INFO;
}
Module module = ApplicationManager.getApplication().runReadAction((Computable<Module>) () -> {
return utils.getModule(file);
});
Module module = utils.getModule(file);
if (module == null) {
return ProjectLabelInfoEntry.EMPTY_PROJECT_INFO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public MicroProfileProjectInfo getMicroProfileProjectInfo(MicroProfileProjectInf
}

public MicroProfileProjectInfo getMicroProfileProjectInfo(VirtualFile file, List<MicroProfilePropertiesScope> scopes, IPsiUtils utils, DocumentFormat documentFormat) {
Module module = ApplicationManager.getApplication().runReadAction((Computable<Module>) () -> utils.getModule(file));
Module module = utils.getModule(file);
ClasspathKind classpathKind = PsiUtilsLSImpl.getClasspathKind(file, module);
return getMicroProfileProjectInfo(module, scopes, classpathKind, utils, documentFormat);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,15 @@ private PropertiesManagerForJava() {
* and null otherwise.
*/
public JavaFileInfo fileInfo(MicroProfileJavaFileInfoParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<JavaFileInfo>) () -> {
String uri = params.getUri();
final PsiFile unit = utils.resolveCompilationUnit(uri);
if (unit != null && unit.isValid() && unit instanceof PsiJavaFile) {
JavaFileInfo fileInfo = new JavaFileInfo();
String packageName = ((PsiJavaFile) unit).getPackageName();
fileInfo.setPackageName(packageName);
return fileInfo;
}
return null;
});
String uri = params.getUri();
final PsiFile unit = utils.resolveCompilationUnit(uri);
if (unit != null && unit.isValid() && unit instanceof PsiJavaFile) {
JavaFileInfo fileInfo = new JavaFileInfo();
String packageName = ((PsiJavaFile) unit).getPackageName();
fileInfo.setPackageName(packageName);
return fileInfo;
}
return null;
}

/**
Expand All @@ -106,16 +104,14 @@ public JavaFileInfo fileInfo(MicroProfileJavaFileInfoParams params, IPsiUtils ut
* @return the codelens list according the given codelens parameters.
*/
public List<? extends CodeLens> codeLens(MicroProfileJavaCodeLensParams params, IPsiUtils utils, ProgressIndicator monitor) {
return ApplicationManager.getApplication().runReadAction((Computable<List<? extends CodeLens>>) () -> {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return Collections.emptyList();
}
List<CodeLens> lenses = new ArrayList<>();
collectCodeLens(uri, typeRoot, utils, params, lenses, monitor);
return lenses;
});
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return Collections.emptyList();
}
List<CodeLens> lenses = new ArrayList<>();
collectCodeLens(uri, typeRoot, utils, params, lenses, monitor);
return lenses;
}

private void collectCodeLens(String uri, PsiFile typeRoot, IPsiUtils utils, MicroProfileJavaCodeLensParams params,
Expand Down Expand Up @@ -156,49 +152,47 @@ private void collectCodeLens(String uri, PsiFile typeRoot, IPsiUtils utils, Micr
* @return the CompletionItems for the given the completion item params
*/
public CompletionList completion(MicroProfileJavaCompletionParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<CompletionList>) () -> {
try {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return null;
}

Module module = utils.getModule(uri);
if (module == null) {
return null;
}

Position completionPosition = params.getPosition();
int completionOffset = utils.toOffset(typeRoot, completionPosition.getLine(),
completionPosition.getCharacter());
try {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return null;
}

List<CompletionItem> completionItems = new ArrayList<>();
JavaCompletionContext completionContext = new JavaCompletionContext(uri, typeRoot, utils, module, completionOffset);
Module module = utils.getModule(uri);
if (module == null) {
return null;
}

List<IJavaCompletionParticipant> completions = IJavaCompletionParticipant.EP_NAME.extensions()
.filter(completion -> completion.isAdaptedForCompletion(completionContext))
.collect(Collectors.toList());
Position completionPosition = params.getPosition();
int completionOffset = utils.toOffset(typeRoot, completionPosition.getLine(),
completionPosition.getCharacter());

if (completions.isEmpty()) {
return null;
}
List<CompletionItem> completionItems = new ArrayList<>();
JavaCompletionContext completionContext = new JavaCompletionContext(uri, typeRoot, utils, module, completionOffset);

completions.forEach(completion -> {
List<? extends CompletionItem> collectedCompletionItems = completion.collectCompletionItems(completionContext);
if (collectedCompletionItems != null) {
completionItems.addAll(collectedCompletionItems);
}
});
List<IJavaCompletionParticipant> completions = IJavaCompletionParticipant.EP_NAME.extensions()
.filter(completion -> completion.isAdaptedForCompletion(completionContext))
.collect(Collectors.toList());

CompletionList completionList = new CompletionList();
completionList.setItems(completionItems);
return completionList;
} catch (IOException e) {
LOGGER.warn(e.getLocalizedMessage(), e);
if (completions.isEmpty()) {
return null;
}
});

completions.forEach(completion -> {
List<? extends CompletionItem> collectedCompletionItems = completion.collectCompletionItems(completionContext);
if (collectedCompletionItems != null) {
completionItems.addAll(collectedCompletionItems);
}
});

CompletionList completionList = new CompletionList();
completionList.setItems(completionItems);
return completionList;
} catch (IOException e) {
LOGGER.warn(e.getLocalizedMessage(), e);
return null;
}
}

/**
Expand All @@ -209,22 +203,20 @@ public CompletionList completion(MicroProfileJavaCompletionParams params, IPsiUt
* @return the definition list according the given definition parameters.
*/
public List<MicroProfileDefinition> definition(MicroProfileJavaDefinitionParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<List<MicroProfileDefinition>>)() -> {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return Collections.emptyList();
}
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return Collections.emptyList();
}

Position hyperlinkedPosition = params.getPosition();
int definitionOffset = utils.toOffset(typeRoot, hyperlinkedPosition.getLine(),
hyperlinkedPosition.getCharacter());
PsiElement hyperlinkedElement = getHoveredElement(typeRoot, definitionOffset);
Position hyperlinkedPosition = params.getPosition();
int definitionOffset = utils.toOffset(typeRoot, hyperlinkedPosition.getLine(),
hyperlinkedPosition.getCharacter());
PsiElement hyperlinkedElement = getHoveredElement(typeRoot, definitionOffset);

List<MicroProfileDefinition> locations = new ArrayList<>();
collectDefinition(uri, typeRoot, hyperlinkedElement, utils, hyperlinkedPosition, locations);
return locations;
});
List<MicroProfileDefinition> locations = new ArrayList<>();
collectDefinition(uri, typeRoot, hyperlinkedElement, utils, hyperlinkedPosition, locations);
return locations;
}

private void collectDefinition(String uri, PsiFile typeRoot, PsiElement hyperlinkedElement, IPsiUtils utils,
Expand Down Expand Up @@ -327,32 +319,30 @@ private void collectDiagnostics(String uri, IPsiUtils utils, DocumentFormat docu
* @return the hover information according to the given <code>params</code>
*/
public Hover hover(MicroProfileJavaHoverParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<Hover>) () -> {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return null;
}
Document document = PsiDocumentManager.getInstance(typeRoot.getProject()).getDocument(typeRoot);
if (document == null) {
return null;
}
Position hoverPosition = params.getPosition();
int hoveredOffset = utils.toOffset(document, hoverPosition.getLine(), hoverPosition.getCharacter());
PsiElement hoverElement = getHoveredElement(typeRoot, hoveredOffset);
if (hoverElement == null) return null;

DocumentFormat documentFormat = params.getDocumentFormat();
boolean surroundEqualsWithSpaces = params.isSurroundEqualsWithSpaces();
List<Hover> hovers = new ArrayList<>();
collectHover(uri, typeRoot, hoverElement, utils, hoverPosition, documentFormat, surroundEqualsWithSpaces,
hovers);
if (hovers.isEmpty()) {
return null;
}
// TODO : aggregate the hover
return hovers.get(0);
});
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (typeRoot == null) {
return null;
}
Document document = PsiDocumentManager.getInstance(typeRoot.getProject()).getDocument(typeRoot);
if (document == null) {
return null;
}
Position hoverPosition = params.getPosition();
int hoveredOffset = utils.toOffset(document, hoverPosition.getLine(), hoverPosition.getCharacter());
PsiElement hoverElement = getHoveredElement(typeRoot, hoveredOffset);
if (hoverElement == null) return null;

DocumentFormat documentFormat = params.getDocumentFormat();
boolean surroundEqualsWithSpaces = params.isSurroundEqualsWithSpaces();
List<Hover> hovers = new ArrayList<>();
collectHover(uri, typeRoot, hoverElement, utils, hoverPosition, documentFormat, surroundEqualsWithSpaces,
hovers);
if (hovers.isEmpty()) {
return null;
}
// TODO : aggregate the hover
return hovers.get(0);
}

/**
Expand All @@ -364,24 +354,22 @@ public Hover hover(MicroProfileJavaHoverParams params, IPsiUtils utils) {
* @return the cursor context for the given file and cursor position
*/
public JavaCursorContextResult javaCursorContext(MicroProfileJavaCompletionParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<JavaCursorContextResult>) () -> {
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (!(typeRoot instanceof PsiJavaFile)) {
return new JavaCursorContextResult(JavaCursorContextKind.IN_EMPTY_FILE, "");
}
Document document = PsiDocumentManager.getInstance(typeRoot.getProject()).getDocument(typeRoot);
if (document == null) {
return new JavaCursorContextResult(JavaCursorContextKind.IN_EMPTY_FILE, "");
}
Position completionPosition = params.getPosition();
int completionOffset = utils.toOffset(document, completionPosition.getLine(), completionPosition.getCharacter());
String uri = params.getUri();
PsiFile typeRoot = resolveTypeRoot(uri, utils);
if (!(typeRoot instanceof PsiJavaFile)) {
return new JavaCursorContextResult(JavaCursorContextKind.IN_EMPTY_FILE, "");
}
Document document = PsiDocumentManager.getInstance(typeRoot.getProject()).getDocument(typeRoot);
if (document == null) {
return new JavaCursorContextResult(JavaCursorContextKind.IN_EMPTY_FILE, "");
}
Position completionPosition = params.getPosition();
int completionOffset = utils.toOffset(document, completionPosition.getLine(), completionPosition.getCharacter());

JavaCursorContextKind kind = getJavaCursorContextKind((PsiJavaFile) typeRoot, completionOffset);
String prefix = getJavaCursorPrefix(document, completionOffset);
JavaCursorContextKind kind = getJavaCursorContextKind((PsiJavaFile) typeRoot, completionOffset);
String prefix = getJavaCursorPrefix(document, completionOffset);

return new JavaCursorContextResult(kind, prefix);
});
return new JavaCursorContextResult(kind, prefix);
}

private static @NotNull JavaCursorContextKind getJavaCursorContextKind(PsiJavaFile javaFile, int completionOffset) {
Expand Down Expand Up @@ -581,7 +569,6 @@ private PsiElement getHoveredMethodParameter(PsiMethod method, int offset) {
}
}
return method;

}

private void collectHover(String uri, PsiFile typeRoot, PsiElement hoverElement, IPsiUtils utils,
Expand Down Expand Up @@ -638,9 +625,7 @@ private static PsiFile resolveTypeRoot(String uri, IPsiUtils utils) {
* @return the codeAction list according the given codeAction parameters.
*/
public List<? extends CodeAction> codeAction(MicroProfileJavaCodeActionParams params, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<List<? extends CodeAction>>) () -> {
return codeActionHandler.codeAction(params, utils);
});
return codeActionHandler.codeAction(params, utils);
}

/**
Expand All @@ -651,9 +636,7 @@ public List<? extends CodeAction> codeAction(MicroProfileJavaCodeActionParams pa
* @return the codeAction list according the given codeAction parameters.
*/
public CodeAction resolveCodeAction(CodeAction unresolved, IPsiUtils utils) {
return ApplicationManager.getApplication().runReadAction((Computable<CodeAction>) () -> {
return codeActionHandler.resolveCodeAction(unresolved, utils);
});
return codeActionHandler.resolveCodeAction(unresolved, utils);
}

}
Loading

0 comments on commit b6b4b8d

Please sign in to comment.