Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Addressed issues with LSP Find Usages implementation (issue 708) #711

Closed
wants to merge 9 commits into from

Conversation

SCWells72
Copy link
Contributor

I'm unfortunately unable to reproduce the actual error seen by the reporting user in both 2023.2 or 2024.3, but wrapping the entire call in a read action should resolve all downstream requirements for the read lock.

…ead action. I'm unfortunately unable to reproduce the actual error seen by the reporting user in 2023.2 or 2024.3, but wrapping the entire call in a read action should resolve all downstream requirements for the read lock.
@SCWells72 SCWells72 marked this pull request as draft December 17, 2024 14:53
…cope of the read action, ensures that the search scope from the Find Usages dialog is used, and ensures that the LSP4IJ find usages handler is only used if there is at least one configured language server definition for the file that supports the usages capability.
*/
public static void processExternalReferences(@NotNull PsiFile file,
int offset,
@NotNull SearchScope searchScope,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Find Usages, we need the configured search scope.

*/
public static void processExternalReferences(@NotNull PsiFile file,
int offset,
@NotNull Processor<PsiReference> processor) {
processExternalReferences(file, offset, ReadAction.compute(file::getUseScope), processor);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the original signature that derives the search scope from the file.

VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
Document document = LSPIJUtils.getDocument(virtualFile);
TextRange wordTextRange = document != null ? LSPIJUtils.getWordRangeAt(document, file, offset) : null;
if (wordTextRange != null) {
LSPPsiElement wordElement = new LSPPsiElement(file, wordTextRange);
String wordText = wordElement.getText();
String wordText = ReadAction.compute(wordElement::getText);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical read actions where required.

@@ -95,7 +113,7 @@ private static void processExternalReferences(@NotNull PsiFile file,
}

Set<String> externalReferenceKeys = new HashSet<>();
PsiSearchHelper.getInstance(project).processElementsWithWord(
ReadAction.run(() -> PsiSearchHelper.getInstance(project).processElementsWithWord(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broader read action around the word search proper.

return;
}

Project project = element.getProject();
Copy link
Contributor Author

@SCWells72 SCWells72 Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't proceed if there are no configured language server definitions for this file that support usages. That really addresses Joachim's core issue where it was doing this work in a file that shouldn't have been considered by LSP4IJ at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

LSPExternalReferencesFinder.processExternalReferences(file, element.getTextOffset(), reference -> processor.process(new UsageInfo2UsageAdapter(new UsageInfo(reference))));
LSPExternalReferencesFinder.processExternalReferences(
file,
ReadAction.compute(element::getTextOffset),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the specific call that was causing the exception in Joachim's report. Now we get the text offset in a read action.

@SCWells72 SCWells72 changed the title fix: Wrapped the search for external references in a read action (issue 708) fix: Addressed issues with LSP Find Usages implementation (issue 708) Dec 17, 2024
file,
ReadAction.compute(element::getTextOffset),
options.searchScope,
reference -> processor.process(new UsageInfo2UsageAdapter(new UsageInfo(reference)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember you can have a ReadAction problem here. (See the first call process.process which compute a ReadAction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that new UsageInfo2UsageAdapter(new UsageInfo(reference)) should be enclosed in a ReadAction here like in the other similar constructor calls in the same method. I don't think that's necessary because the UsageInfo2UsageAdapter constructor already includes its own ReadAction, and the UsageInfo constructor also looks fine. Having said that, I'm totally fine wrapping that in a ReadAction both for consistency and out of a sense of caution if you'd like. Let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and added it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is that, I don't remember how to reproduce it, but I had to add ReadAction#compute to fix the problem. See

processor.process(ReadAction.compute(() -> new UsageInfo2UsageAdapter(new UsageInfo(psiElement))));

@angelozerr
Copy link
Contributor

@SCWells72 please fix conflicts.

@angelozerr
Copy link
Contributor

@SCWells72 instead of having ReadAction run/compute in several locations, perhaps it should better to have just one ReadAction, no?

@SCWells72
Copy link
Contributor Author

That's how I originally had it. However, read and write actions do take out locks, and it's best to limit the scope of those locks if possible. That's why I've added these in a more fine-grained manner.

…ead action. I'm unfortunately unable to reproduce the actual error seen by the reporting user in 2023.2 or 2024.3, but wrapping the entire call in a read action should resolve all downstream requirements for the read lock.
…cope of the read action, ensures that the search scope from the Find Usages dialog is used, and ensures that the LSP4IJ find usages handler is only used if there is at least one configured language server definition for the file that supports the usages capability.
# Conflicts:
#	src/main/java/com/redhat/devtools/lsp4ij/usages/LSPUsageSearcher.java
@SCWells72
Copy link
Contributor Author

Going to open a new PR for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants