diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/JavaEEImplicitUsageProvider.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/JavaEEImplicitUsageProvider.java index 094028891..e9c41e592 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/JavaEEImplicitUsageProvider.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/JavaEEImplicitUsageProvider.java @@ -14,18 +14,25 @@ package com.redhat.devtools.intellij.lsp4mp4ij.psi.core; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; -import com.intellij.psi.PsiElement; +import com.intellij.psi.*; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.JaxRsConstants; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils; import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.restclient.MicroProfileRestClientConstants; import org.jetbrains.annotations.NotNull; /** - * Automatically declares as used, methods annotated with jakarta.ws.rs.* or javax.ws.rs.* HTTP annotations, - * or {@link org.eclipse.microprofile.rest.client.inject.RestClient} + * Automatically declares the following as used: + * */ public class JavaEEImplicitUsageProvider implements ImplicitUsageProvider { + private static final String JAKARTA_OBSERVES = "jakarta.enterprise.event.Observes"; + private static final String JAVAX_OBSERVES = "javax.enterprise.event.Observes"; + + @Override public boolean isImplicitUsage(@NotNull PsiElement element) { return isImplicitRead(element) || isImplicitWrite(element); @@ -33,6 +40,44 @@ public boolean isImplicitUsage(@NotNull PsiElement element) { @Override public boolean isImplicitRead(@NotNull PsiElement element) { + return isHttpOrRestClient(element) || isObserverMethod(element); + } + + private boolean isObserverMethod(@NotNull PsiElement element) { + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod) element; + return isPublicNonAbstract(method) && observesOneParameter(method); + } + return false; + } + + private boolean observesOneParameter(PsiMethod method) { + //XXX ideally we might want to check if the parent class is a managed bean class or session bean class (or of an extension) + //But that might prove a bit complex, so let's skip this part for now. + + PsiParameter[] parameters = method.getParameterList().getParameters(); + + int observesAnnotationCount = 0; + + for (PsiParameter parameter : parameters) { + if (AnnotationUtils.hasAnyAnnotation(parameter, JAKARTA_OBSERVES, JAVAX_OBSERVES)) { + observesAnnotationCount++; + if (observesAnnotationCount > 1) { + return false; + } + } + } + + return observesAnnotationCount == 1; + } + + private boolean isPublicNonAbstract(@NotNull PsiMethod method) { + return !method.isConstructor() && + method.hasModifierProperty(PsiModifier.PUBLIC) && + !method.hasModifierProperty(PsiModifier.ABSTRACT); + } + + private boolean isHttpOrRestClient(@NotNull PsiElement element) { return AnnotationUtils.hasAnyAnnotation(element, JaxRsConstants.HTTP_METHOD_ANNOTATIONS) || AnnotationUtils.hasAnnotation(element, MicroProfileRestClientConstants.REST_CLIENT_ANNOTATION); }