Skip to content

Commit d926ffa

Browse files
committed
feat: Mark observer methods as implicitly used
Signed-off-by: Fred Bricon <[email protected]>
1 parent 3fbeb41 commit d926ffa

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/JavaEEImplicitUsageProvider.java

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,73 @@
1414
package com.redhat.devtools.intellij.lsp4mp4ij.psi.core;
1515

1616
import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
17-
import com.intellij.psi.PsiElement;
17+
import com.intellij.psi.*;
1818
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.JaxRsConstants;
1919
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils;
2020
import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.restclient.MicroProfileRestClientConstants;
2121
import org.jetbrains.annotations.NotNull;
2222

2323
/**
24-
* Automatically declares as used, methods annotated with jakarta.ws.rs.* or javax.ws.rs.* HTTP annotations,
25-
* or {@link org.eclipse.microprofile.rest.client.inject.RestClient}
24+
* Automatically declares the following as used:
25+
* <ul>
26+
* <li>methods annotated with jakarta.ws.rs.* or javax.ws.rs.* HTTP annotations, or {@link org.eclipse.microprofile.rest.client.inject.RestClient}</li>
27+
* <li>non-abstract public observer methods, i.e. with a parameter annotated with <code>@jakarta.enterprise.event.Observes</code></li>
28+
* </ul>
29+
*
30+
*
31+
*
2632
*/
2733
public class JavaEEImplicitUsageProvider implements ImplicitUsageProvider {
2834

35+
private static final String JAKARTA_OBSERVES = "jakarta.enterprise.event.Observes";
36+
private static final String JAVAX_OBSERVES = "javax.enterprise.event.Observes";
37+
38+
2939
@Override
3040
public boolean isImplicitUsage(@NotNull PsiElement element) {
3141
return isImplicitRead(element) || isImplicitWrite(element);
3242
}
3343

3444
@Override
3545
public boolean isImplicitRead(@NotNull PsiElement element) {
46+
return isHttpOrRestClient(element) || isObserverMethod(element);
47+
}
48+
49+
private boolean isObserverMethod(@NotNull PsiElement element) {
50+
if (element instanceof PsiMethod) {
51+
PsiMethod method = (PsiMethod) element;
52+
return isPublicNonAbstract(method) && observesOneParameter(method);
53+
}
54+
return false;
55+
}
56+
57+
private boolean observesOneParameter(PsiMethod method) {
58+
//XXX ideally we might want to check if the parent class is a managed bean class or session bean class (or of an extension)
59+
//But that might prove a bit complex, so let's skip this part for now.
60+
61+
PsiParameter[] parameters = method.getParameterList().getParameters();
62+
63+
int observesAnnotationCount = 0;
64+
65+
for (PsiParameter parameter : parameters) {
66+
if (AnnotationUtils.hasAnyAnnotation(parameter, JAKARTA_OBSERVES, JAVAX_OBSERVES)) {
67+
observesAnnotationCount++;
68+
if (observesAnnotationCount > 1) {
69+
return false;
70+
}
71+
}
72+
}
73+
74+
return observesAnnotationCount == 1;
75+
}
76+
77+
private boolean isPublicNonAbstract(@NotNull PsiMethod method) {
78+
return !method.isConstructor() &&
79+
method.hasModifierProperty(PsiModifier.PUBLIC) &&
80+
!method.hasModifierProperty(PsiModifier.ABSTRACT);
81+
}
82+
83+
private boolean isHttpOrRestClient(@NotNull PsiElement element) {
3684
return AnnotationUtils.hasAnyAnnotation(element, JaxRsConstants.HTTP_METHOD_ANNOTATIONS) ||
3785
AnnotationUtils.hasAnnotation(element, MicroProfileRestClientConstants.REST_CLIENT_ANNOTATION);
3886
}

0 commit comments

Comments
 (0)