2
2
3
3
import com .intellij .openapi .project .Project ;
4
4
import com .intellij .openapi .util .text .StringUtil ;
5
- import com .intellij .patterns .PlatformPatterns ;
6
5
import com .intellij .psi .PsiElement ;
7
6
import com .jetbrains .php .PhpIndex ;
8
- import com .jetbrains .php .lang .parser .PhpElementTypes ;
9
7
import com .jetbrains .php .lang .psi .elements .Method ;
10
8
import com .jetbrains .php .lang .psi .elements .MethodReference ;
11
9
import com .jetbrains .php .lang .psi .elements .PhpClass ;
12
10
import com .jetbrains .php .lang .psi .elements .PhpNamedElement ;
13
11
import 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 ;
15
13
import fr .adrienbrault .idea .symfony2plugin .Settings ;
16
14
import fr .adrienbrault .idea .symfony2plugin .util .MethodMatcher ;
17
15
import fr .adrienbrault .idea .symfony2plugin .util .PhpElementsUtil ;
18
16
import fr .adrienbrault .idea .symfony2plugin .util .PhpTypeProviderUtil ;
17
+ import org .jetbrains .annotations .NotNull ;
19
18
import org .jetbrains .annotations .Nullable ;
20
-
21
19
import java .util .Arrays ;
22
20
import java .util .Collection ;
23
- import java .util .Collections ;
21
+ import java .util .HashSet ;
24
22
import java .util .Set ;
23
+ import java .util .stream .Collectors ;
25
24
26
25
/**
26
+ * Resolve "find*" at attach the entity
27
+ *
28
+ * "$om->getRepository('\Foo\Bar')->find('foobar')->get<caret>Id()"
29
+ *
27
30
* @author Daniel Espendiller <[email protected] >
28
31
*/
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 [] {
31
34
new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "find" ),
32
35
new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "findOneBy" ),
33
36
new MethodMatcher .CallToSignature ("\\ Doctrine\\ Common\\ Persistence\\ ObjectRepository" , "findAll" ),
@@ -48,18 +51,7 @@ public char getKey() {
48
51
@ Nullable
49
52
@ Override
50
53
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 ) {
63
55
return null ;
64
56
}
65
57
@@ -105,57 +97,64 @@ public PhpType getType(PsiElement e) {
105
97
return new PhpType ().add ("#" + this .getKey () + refSignature + TRIM_KEY + repositorySignature );
106
98
}
107
99
100
+ @ Nullable
108
101
@ 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 );
112
104
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 ;
129
106
}
130
107
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 );
134
111
if (parameter == null ) {
135
- return Collections . emptySet () ;
112
+ return null ;
136
113
}
137
114
138
115
PhpClass phpClass = EntityHelper .resolveShortcutName (project , parameter );
139
116
if (phpClass == null ) {
140
- return Collections . emptySet () ;
117
+ return null ;
141
118
}
142
119
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 ;
147
132
}
148
133
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 ;
150
142
}
151
143
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 <>();
153
152
for (PhpNamedElement phpNamedElement : phpNamedElements ) {
154
153
if (phpNamedElement instanceof Method && PhpElementsUtil .isMethodInstanceOf ((Method ) phpNamedElement , FIND_SIGNATURES )) {
155
- return ( Method ) phpNamedElement ;
154
+ methods . add (( Method ) phpNamedElement ) ;
156
155
}
157
156
}
158
157
159
- return null ;
158
+ return methods ;
160
159
}
161
160
}
0 commit comments