22
33import com .intellij .codeInsight .daemon .ImplicitUsageProvider ;
44import com .intellij .psi .PsiElement ;
5- import com .jetbrains .php .lang .psi .elements .Method ;
6- import com .jetbrains .php .lang .psi .elements .PhpAttribute ;
7- import com .jetbrains .php .lang .psi .elements .PhpClass ;
8- import com .jetbrains .php .lang .psi .elements .PhpModifier ;
5+ import com .intellij .psi .util .PsiTreeUtil ;
6+ import com .jetbrains .php .lang .parser .PhpElementTypes ;
7+ import com .jetbrains .php .lang .psi .elements .*;
98import de .espend .idea .php .annotation .dict .PhpDocCommentAnnotation ;
109import de .espend .idea .php .annotation .util .AnnotationUtil ;
1110import fr .adrienbrault .idea .symfony2plugin .routing .RouteHelper ;
1211import fr .adrienbrault .idea .symfony2plugin .util .PhpElementsUtil ;
1312import fr .adrienbrault .idea .symfony2plugin .util .dict .ServiceUtil ;
13+ import org .apache .commons .lang .StringUtils ;
1414import org .jetbrains .annotations .NotNull ;
1515
1616import java .util .Collection ;
@@ -27,10 +27,12 @@ public class SymfonyImplicitUsageProvider implements ImplicitUsageProvider {
2727 @ Override
2828 public boolean isImplicitUsage (@ NotNull PsiElement element ) {
2929 if (element instanceof Method && ((Method ) element ).getAccess () == PhpModifier .Access .PUBLIC ) {
30- return isMethodARoute ((Method ) element );
30+ return isMethodARoute ((Method ) element )
31+ || isSubscribedEvent ((Method ) element );
3132 } else if (element instanceof PhpClass ) {
3233 return isRouteClass ((PhpClass ) element )
33- || isCommandAndService ((PhpClass ) element );
34+ || isCommandAndService ((PhpClass ) element )
35+ || isSubscribedEvent ((PhpClass ) element );
3436 }
3537
3638 return false ;
@@ -73,4 +75,45 @@ private boolean isMethodARoute(@NotNull Method method) {
7375
7476 return RouteHelper .isRouteExistingForMethod (method );
7577 }
78+
79+ private boolean isSubscribedEvent (@ NotNull PhpClass phpClass ) {
80+ return phpClass .getMethods ()
81+ .stream ()
82+ .filter (method -> method .getAccess () == PhpModifier .Access .PUBLIC )
83+ .anyMatch (this ::isSubscribedEvent );
84+ }
85+
86+ private boolean isSubscribedEvent (@ NotNull Method method ) {
87+ PhpClass containingClass = method .getContainingClass ();
88+ if (containingClass == null || !PhpElementsUtil .isInstanceOf (containingClass , "\\ Symfony\\ Component\\ EventDispatcher\\ EventSubscriberInterface" )) {
89+ return false ;
90+ }
91+
92+ Method subscribedEvents = containingClass .findMethodByName ("getSubscribedEvents" );
93+ if (subscribedEvents == null ) {
94+ return false ;
95+ }
96+
97+ for (PhpReturn aReturn : PsiTreeUtil .collectElementsOfType (subscribedEvents , PhpReturn .class )) {
98+ PsiElement [] psiElements = PsiTreeUtil .collectElements (aReturn , element -> {
99+ if (!(element instanceof StringLiteralExpression )) {
100+ return false ;
101+ }
102+
103+ PsiElement parent = element .getParent ();
104+ return parent != null && parent .getNode ().getElementType () == PhpElementTypes .ARRAY_VALUE && parent .getChildren ().length == 1 ;
105+ });
106+
107+ for (PsiElement psiElement : psiElements ) {
108+ if (psiElement instanceof StringLiteralExpression ) {
109+ String contents = ((StringLiteralExpression ) psiElement ).getContents ();
110+ if (StringUtils .isNotBlank (contents ) && contents .equalsIgnoreCase (method .getName ())) {
111+ return true ;
112+ }
113+ }
114+ }
115+ }
116+
117+ return false ;
118+ }
76119}
0 commit comments