Search for usage of an Annotation in Java class files from libraries?

I've been working on a plugin for a while, and some users of the plugin want the ability to autocomplete Java methods annotated with a particular annotation (@RobotKeyword) that are in a project's libraries.

None of the indexes seem to work for .class files.

I've tried code like this:

final PsiSearchHelper PSI_SEARCH_HELPER = PsiSearchHelper.SERVICE.getInstance(project);
GlobalSearchScope librariesScope = ProjectScope.getLibrariesScope(project);
GlobalSearchScope javaClassesFromLibrariesScope = GlobalSearchScope.getScopeRestrictedByFileTypes(librariesScope, JavaClassFileType.INSTANCE);
PSI_SEARCH_HELPER.processAllFilesWithWord("RobotKeyword", javaClassesFromLibrariesScope, new FindJavaKeywordFileProcessor(), true);

But, the processor never processes any files, even though there are class files containing this annotation in the libraries of the project.

I also tried using the fully qualified name of the annotation, still 0 results.
I also tried using the JavaStubIndexKeys.ANNOTATIONS index, also 0 results.

I would be grateful for any advice about how to search in Java class files using either a Word index, or an Annotations index.

Comment actions Permalink

Why do you need the getScopeRestrictedByFileTypes() call? Such a scope will not include any library files that have source attached to them.

By the way, the correct way to find methods or classes annotated with a particular annotation is to use the AnnotatedElementsSearch class. It's easier and more efficient than searching for raw text as you're doing.

Comment actions Permalink

I was using the getScopeRestrictedByFileTypes() just to verify if I can find annotations in Java .class files.

I already have working code for finding the annotations in Java files from libraries.

As to your suggestion, thanks for pointing out the AnnotatedElementsSearch class.
However, I'm not sure how to use it in this case, because I don't have a PsiClass for the Annotation in question. The annotation class (RobotKeyword) isn't even a dependency of my plugin project.

I basically have the fully qualified class name of the Annotation class as input: "org.robotframework.javalib.annotation.RobotKeyword".

As output, I want to find all the methods in library class files that are annotated with this.

Do you know an easy way to create a PsiClass element that I can then plug in to, ...) ?


Comment actions Permalink

I figured it out.

I'm using the following code:

PsiClass robotKeywordAnnotation = JavaPsiFacade.findClass("org.robotframework.javalib.annotation.RobotKeyword", ProjectScope.getLibraryScope(project));
ProjectScope allScope = ProjectScope.getAllScope();
Query<PsiMethod> query = AnnotatedElementsSearch.searchPsiMethods(robotKeywordAnnotation, allScope);

The only problem is this requires me to add the RobotKeyword class as a dependency of the plugin.
I tried using PsiElementFactory.createAnnotation(...) instead of using the real class, but this didn't work in a search.

So, problem solved, sort of? if you know how to get this to work without adding RobotKeyword to the plugin's classpath, I would be very grateful!
Seems non-ideal to make all the users download a bunch of code for a single class definition.



Please sign in to leave a comment.