22
33import com .intellij .openapi .project .Project ;
44import com .intellij .openapi .util .text .StringUtil ;
5- import com .intellij .patterns .PlatformPatterns ;
65import com .intellij .psi .PsiElement ;
76import com .jetbrains .php .PhpIndex ;
8- import com .jetbrains .php .lang .parser .PhpElementTypes ;
97import com .jetbrains .php .lang .psi .elements .Method ;
108import com .jetbrains .php .lang .psi .elements .MethodReference ;
119import com .jetbrains .php .lang .psi .elements .PhpClass ;
1210import com .jetbrains .php .lang .psi .elements .PhpNamedElement ;
1311import com .jetbrains .php .lang .psi .resolve .types .PhpType ;
14- import com .jetbrains .php .lang .psi .resolve .types .PhpTypeProvider3 ;
12+ import com .jetbrains .php .lang .psi .resolve .types .PhpTypeProvider4 ;
1513import fr .adrienbrault .idea .symfony2plugin .Settings ;
1614import fr .adrienbrault .idea .symfony2plugin .util .MethodMatcher ;
1715import fr .adrienbrault .idea .symfony2plugin .util .PhpElementsUtil ;
1816import fr .adrienbrault .idea .symfony2plugin .util .PhpTypeProviderUtil ;
17+ import org .jetbrains .annotations .NotNull ;
1918import org .jetbrains .annotations .Nullable ;
20-
2119import java .util .Arrays ;
2220import java .util .Collection ;
23- import java .util .Collections ;
21+ import java .util .HashSet ;
2422import java .util .Set ;
23+ import java .util .stream .Collectors ;
2524
2625/**
26+ * Resolve "find*" at attach the entity
27+ *
28+ * "$om->getRepository('\Foo\Bar')->find('foobar')->get<caret>Id()"
29+ *
2730 * @author Daniel Espendiller <daniel@espendiller.net>
2831 */
29- public class ObjectRepositoryResultTypeProvider implements PhpTypeProvider3 {
30- private static MethodMatcher .CallToSignature [] FIND_SIGNATURES = new MethodMatcher .CallToSignature [] {
32+ public class ObjectRepositoryResultTypeProvider implements PhpTypeProvider4 {
33+ private static final MethodMatcher .CallToSignature [] FIND_SIGNATURES = new MethodMatcher .CallToSignature [] {
3134 new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "find" ),
3235 new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "findOneBy" ),
3336 new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "findAll" ),
@@ -48,18 +51,7 @@ public char getKey() {
4851 @ Nullable
4952 @ Override
5053 public PhpType getType (PsiElement e ) {
51- if (!Settings .getInstance (e .getProject ()).pluginEnabled ) {
52- return null ;
53- }
54-
55- // filter out method calls without parameter
56- // $this->get('service_name')
57- if (!PlatformPatterns
58- .psiElement (PhpElementTypes .METHOD_REFERENCE )
59- .withChild (PlatformPatterns
60- .psiElement (PhpElementTypes .PARAMETER_LIST )
61- ).accepts (e )) {
62-
54+ if (!(e instanceof MethodReference ) || !Settings .getInstance (e .getProject ()).pluginEnabled ) {
6355 return null ;
6456 }
6557
@@ -105,57 +97,64 @@ public PhpType getType(PsiElement e) {
10597 return new PhpType ().add ("#" + this .getKey () + refSignature + TRIM_KEY + repositorySignature );
10698 }
10799
100+ @ Nullable
108101 @ Override
109- public Collection <? extends PhpNamedElement > getBySignature (String expression , Set <String > visited , int depth , Project project ) {
110- // get back our original call
111- int endIndex = expression .lastIndexOf (TRIM_KEY );
102+ public PhpType complete (String s , Project project ) {
103+ int endIndex = s .lastIndexOf (TRIM_KEY );
112104 if (endIndex == -1 ) {
113- return Collections .emptySet ();
114- }
115-
116- String originalSignature = expression .substring (0 , endIndex );
117- String parameter = expression .substring (endIndex + 1 );
118-
119- // search for called method
120- PhpIndex phpIndex = PhpIndex .getInstance (project );
121- Collection <? extends PhpNamedElement > phpNamedElementCollections = PhpTypeProviderUtil .getTypeSignature (phpIndex , originalSignature );
122- if (phpNamedElementCollections .size () == 0 ) {
123- return Collections .emptySet ();
124- }
125-
126- Method method = getObjectRepositoryCall (phpNamedElementCollections );
127- if (method == null ) {
128- return Collections .emptySet ();
105+ return null ;
129106 }
130107
131- // we can also pipe php references signatures and resolve them here
132- // overwrite parameter to get string value
133- parameter = PhpTypeProviderUtil .getResolvedParameter (phpIndex , parameter );
108+ String originalSignature = s . substring ( 0 , endIndex );
109+ String parameter = s . substring ( endIndex + 1 );
110+ parameter = PhpTypeProviderUtil .getResolvedParameter (PhpIndex . getInstance ( project ) , parameter );
134111 if (parameter == null ) {
135- return Collections . emptySet () ;
112+ return null ;
136113 }
137114
138115 PhpClass phpClass = EntityHelper .resolveShortcutName (project , parameter );
139116 if (phpClass == null ) {
140- return Collections . emptySet () ;
117+ return null ;
141118 }
142119
143- String name = method .getName ();
144- if (name .equals ("findAll" ) || name .equals ("findBy" )) {
145- method .getType ().add (phpClass .getFQN () + "[]" );
146- return phpNamedElementCollections ;
120+ PhpIndex phpIndex = PhpIndex .getInstance (project );
121+
122+ Collection <? extends PhpNamedElement > typeSignature = PhpTypeProviderUtil .getTypeSignature (phpIndex , originalSignature );
123+
124+ // ->getRepository(SecondaryMarket::class)->findAll() => "findAll", but only if its a instance of this method;
125+ // so non Doctrine method are already filtered
126+ Set <String > resolveMethods = getObjectRepositoryCall (typeSignature ).stream ()
127+ .map (PhpNamedElement ::getName )
128+ .collect (Collectors .toSet ());
129+
130+ if (resolveMethods .isEmpty ()) {
131+ return null ;
147132 }
148133
149- return PhpTypeProviderUtil .mergeSignatureResults (phpNamedElementCollections , phpClass );
134+ PhpType phpType = new PhpType ();
135+
136+ resolveMethods .stream ()
137+ .map (name -> name .equals ("findAll" ) || name .equals ("findBy" ) ? phpClass .getFQN () + "[]" : phpClass .getFQN ())
138+ .collect (Collectors .toSet ())
139+ .forEach (phpType ::add );
140+
141+ return phpType ;
150142 }
151143
152- private Method getObjectRepositoryCall (Collection <? extends PhpNamedElement > phpNamedElements ) {
144+ @ Override
145+ public Collection <? extends PhpNamedElement > getBySignature (String expression , Set <String > visited , int depth , Project project ) {
146+ return null ;
147+ }
148+
149+ @ NotNull
150+ private Collection <Method > getObjectRepositoryCall (Collection <? extends PhpNamedElement > phpNamedElements ) {
151+ Collection <Method > methods = new HashSet <>();
153152 for (PhpNamedElement phpNamedElement : phpNamedElements ) {
154153 if (phpNamedElement instanceof Method && PhpElementsUtil .isMethodInstanceOf ((Method ) phpNamedElement , FIND_SIGNATURES )) {
155- return ( Method ) phpNamedElement ;
154+ methods . add (( Method ) phpNamedElement ) ;
156155 }
157156 }
158157
159- return null ;
158+ return methods ;
160159 }
161160}
0 commit comments