88import com .intellij .psi .xml .XmlAttribute ;
99import com .intellij .psi .xml .XmlFile ;
1010import com .intellij .psi .xml .XmlTag ;
11+ import com .intellij .util .containers .ContainerUtil ;
1112import com .jetbrains .php .config .PhpLanguageLevel ;
13+ import com .jetbrains .php .lang .documentation .phpdoc .PhpDocUtil ;
1214import com .jetbrains .php .lang .documentation .phpdoc .parser .PhpDocElementTypes ;
1315import com .jetbrains .php .lang .documentation .phpdoc .psi .PhpDocComment ;
1416import com .jetbrains .php .lang .documentation .phpdoc .psi .tags .PhpDocTag ;
1517import com .jetbrains .php .lang .psi .PhpFile ;
18+ import com .jetbrains .php .lang .psi .PhpPsiUtil ;
19+ import com .jetbrains .php .lang .psi .elements .PhpAttribute ;
1620import com .jetbrains .php .lang .psi .elements .PhpClass ;
21+ import com .jetbrains .php .lang .psi .elements .PhpNamedElement ;
1722import com .jetbrains .php .lang .psi .elements .PhpPsiElement ;
1823import com .jetbrains .php .refactoring .PhpNameUtil ;
1924import de .espend .idea .php .annotation .util .AnnotationUtil ;
2025import fr .adrienbrault .idea .symfony2plugin .stubs .indexes .visitor .AnnotationElementWalkingVisitor ;
2126import fr .adrienbrault .idea .symfony2plugin .stubs .indexes .visitor .AttributeElementWalkingVisitor ;
27+ import fr .adrienbrault .idea .symfony2plugin .util .AnnotationBackportUtil ;
28+ import fr .adrienbrault .idea .symfony2plugin .util .PhpElementsUtil ;
2229import fr .adrienbrault .idea .symfony2plugin .util .PhpPsiAttributesUtil ;
2330import fr .adrienbrault .idea .symfony2plugin .util .PsiElementUtils ;
2431import fr .adrienbrault .idea .symfony2plugin .util .yaml .YamlHelper ;
2835import org .jetbrains .annotations .Nullable ;
2936import org .jetbrains .yaml .psi .*;
3037
31- import java .util .ArrayList ;
32- import java .util .Collection ;
33- import java .util .Set ;
38+ import java .util .*;
3439
3540/**
3641 * @author Daniel Espendiller <daniel@espendiller.net>
@@ -57,8 +62,8 @@ public static Collection<Pair<String, String>> getClassRepositoryPair(@NotNull P
5762 pairs = getClassRepositoryPair ((XmlFile ) psiFile );
5863 } else if (psiFile instanceof YAMLFile ) {
5964 pairs = getClassRepositoryPair ((YAMLFile ) psiFile );
60- } else if (psiFile instanceof PhpFile ) {
61- pairs = getClassRepositoryPair (( PsiElement ) psiFile );
65+ } else if (psiFile instanceof PhpFile phpFile ) {
66+ pairs = getClassRepositoryPair (phpFile );
6267 }
6368
6469 return pairs ;
@@ -114,44 +119,48 @@ private static Collection<Pair<String, String>> getClassRepositoryPair(@NotNull
114119 * We support multiple use case like orm an so on
115120 */
116121 @ NotNull
117- public static Collection <Pair <String , String >> getClassRepositoryPair (@ NotNull PsiElement phpFile ) {
122+ public static Collection <Pair <String , String >> getClassRepositoryPair (@ NotNull PhpFile phpFile ) {
118123 final Collection <Pair <String , String >> pairs = new ArrayList <>();
124+ Collection <PhpClass > classes = PhpPsiUtil .findAllClasses (phpFile );
119125
120- // Annotations:
121- // @ORM\Entity("repositoryClass": YYY)
122- phpFile .acceptChildren (new AnnotationElementWalkingVisitor (phpDocTag -> {
123- PhpDocComment phpDocComment = PsiTreeUtil .getParentOfType (phpDocTag , PhpDocComment .class );
124- if (phpDocComment == null ) {
125- return false ;
126+ for (PhpClass phpClass : classes ) {
127+ PhpDocComment docComment = phpClass .getDocComment ();
128+ if (docComment != null ) {
129+ pairs .addAll (extractAnnotations (phpClass , docComment ));
126130 }
127-
128- PhpPsiElement phpClass = phpDocComment .getNextPsiSibling ();
129- if (!(phpClass instanceof PhpClass phpClassScope )) {
130- return false ;
131+ for (PhpAttribute attribute : phpClass .getAttributes ()) {
132+ String attributeFQN = attribute .getFQN ();
133+ if (attributeFQN == null ) continue ;
134+ if (PhpElementsUtil .isEqualClassName (attributeFQN , MODEL_CLASS_ANNOTATION )) {
135+ String repositoryClass = PhpPsiAttributesUtil .getAttributeValueByNameAsString (attribute , "repositoryClass" );
136+ pairs .add (Pair .create (StringUtils .stripStart (phpClass .getFQN (), "\\ " ),
137+ repositoryClass != null ? StringUtils .stripStart (repositoryClass , "\\ " ) : null ));
138+ }
131139 }
140+ }
132141
133- pairs .add (Pair .create (
134- phpClassScope .getPresentableFQN (),
135- getAnnotationRepositoryClass (phpDocTag , phpClassScope ))
136- );
137-
138- return false ;
139- }, MODEL_CLASS_ANNOTATION ));
140-
141- // Attributes:
142- // #[Entity(repositoryClass: UserRepository::class)]
143- phpFile .acceptChildren (new AttributeElementWalkingVisitor (pair -> {
144- String repositoryClass = PhpPsiAttributesUtil .getAttributeValueByNameAsString (pair .getFirst (), "repositoryClass" );
142+ return pairs ;
143+ }
145144
146- pairs .add (Pair .create (
147- StringUtils .stripStart (pair .getSecond ().getFQN (), "\\ " ),
148- repositoryClass != null ? StringUtils .stripStart (repositoryClass , "\\ " ) : null
149- ));
145+ public static Collection <Pair <String , String >> extractAnnotations (@ NotNull PhpClass phpClass , @ NotNull PhpDocComment docComment ) {
146+ Collection <Pair <String , String >> result = new ArrayList <>();
147+ PhpDocUtil .processTagElementsByName (docComment , null , phpDocTag -> {
148+ if (AnnotationBackportUtil .NON_ANNOTATION_TAGS .contains (phpDocTag .getName ())) {
149+ return true ;
150+ }
150151
151- return false ;
152- }, MODEL_CLASS_ANNOTATION ));
152+ Map <String , String > fileImports = AnnotationBackportUtil .getUseImportMap (phpDocTag );
153+ if (fileImports .isEmpty ()) {
154+ return true ;
155+ }
153156
154- return pairs ;
157+ String annotationFqnName = AnnotationBackportUtil .getClassNameReference (phpDocTag , fileImports );
158+ if (ContainerUtil .exists (MODEL_CLASS_ANNOTATION , c -> c .equals (annotationFqnName ))) {
159+ result .add (Pair .create (phpClass .getPresentableFQN (), getAnnotationRepositoryClass (phpDocTag , phpClass )));
160+ }
161+ return true ;
162+ });
163+ return result ;
155164 }
156165
157166 /**
0 commit comments