Skip to content

Commit ea4e367

Browse files
committedNov 17, 2013
resolve php references in container type parameter to support "fields" like constants and properties #151
1 parent 3724f30 commit ea4e367

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed
 

‎src/fr/adrienbrault/idea/symfony2plugin/dic/SymfonyContainerTypeProvider.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public String getType(PsiElement e) {
3939
}
4040

4141
// container calls are only on "get" methods
42-
if(!(e instanceof MethodReference) || !PhpElementsUtil.isMethodWithFirstString(e, "get")) {
42+
if(!(e instanceof MethodReference) || !PhpElementsUtil.isMethodWithFirstStringOrFieldReference(e, "get")) {
4343
return null;
4444
}
4545

@@ -53,10 +53,19 @@ public String getType(PsiElement e) {
5353
PsiElement[] parameters = ((MethodReference)e).getParameters();
5454
if (parameters.length == 1) {
5555
PsiElement parameter = parameters[0];
56-
if ((parameter instanceof StringLiteralExpression)) {
56+
if (parameter instanceof StringLiteralExpression) {
5757
String param = ((StringLiteralExpression)parameter).getContents();
58-
if (StringUtil.isNotEmpty(param)) return refSignature + TRIM_KEY + param;
58+
if (StringUtil.isNotEmpty(param)) {
59+
return refSignature + TRIM_KEY + param;
60+
}
5961
}
62+
63+
// whitelist here; we can also provide some more but think of performance
64+
// Service::NAME and $this->name;
65+
if (parameter instanceof PhpReference && (parameter instanceof ClassConstantReference || parameter instanceof FieldReference)) {
66+
return refSignature + TRIM_KEY + ((PhpReference) parameter).getSignature();
67+
}
68+
6069
}
6170

6271
return null;
@@ -82,6 +91,20 @@ public Collection<? extends PhpNamedElement> getBySignature(String expression, P
8291
return Collections.emptySet();
8392
}
8493

94+
// we can also pipe php references signatures and resolve them here
95+
// overwrite parameter to get string value
96+
if(parameter.startsWith("#")) {
97+
Collection<? extends PhpNamedElement> signTypes = phpIndex.getBySignature(parameter, null, 0);
98+
if(signTypes.size() == 0) {
99+
return Arrays.asList(phpNamedElement);
100+
}
101+
102+
parameter = PhpElementsUtil.getStringValue(signTypes.iterator().next());
103+
if(parameter == null) {
104+
return Arrays.asList(phpNamedElement);
105+
}
106+
}
107+
85108
// finally search the classes
86109
if(new Symfony2InterfacesUtil().isContainerGetCall((Method) phpNamedElement)) {
87110
ServiceMap serviceMap = ServiceXmlParserFactory.getInstance(project, XmlServiceParser.class).getServiceMap();

‎src/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java

+40-9
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
import com.intellij.patterns.ElementPattern;
66
import com.intellij.patterns.PlatformPatterns;
77
import com.intellij.patterns.PsiElementPattern;
8-
import com.intellij.psi.PsiElement;
9-
import com.intellij.psi.PsiElementResolveResult;
10-
import com.intellij.psi.PsiWhiteSpace;
11-
import com.intellij.psi.ResolveResult;
8+
import com.intellij.psi.*;
129
import com.intellij.psi.util.PsiTreeUtil;
1310
import com.jetbrains.php.PhpIndex;
1411
import com.jetbrains.php.completion.PhpLookupElement;
@@ -190,6 +187,33 @@ static public boolean isMethodWithFirstString(PsiElement psiElement, String... m
190187
return null != methodRefName && Arrays.asList(methodName).contains(methodRefName);
191188
}
192189

190+
/**
191+
* $this->methodName('service_name')
192+
* $this->methodName(SERVICE::NAME)
193+
* $this->methodName($this->name)
194+
*/
195+
static public boolean isMethodWithFirstStringOrFieldReference(PsiElement psiElement, String... methodName) {
196+
197+
if(!PlatformPatterns
198+
.psiElement(PhpElementTypes.METHOD_REFERENCE)
199+
.withChild(PlatformPatterns
200+
.psiElement(PhpElementTypes.PARAMETER_LIST)
201+
.withFirstChild(PlatformPatterns.or(
202+
PlatformPatterns.psiElement(PhpElementTypes.STRING),
203+
PlatformPatterns.psiElement(PhpElementTypes.FIELD_REFERENCE),
204+
PlatformPatterns.psiElement(PhpElementTypes.CLASS_CONSTANT_REFERENCE)
205+
))
206+
).accepts(psiElement)) {
207+
208+
return false;
209+
}
210+
211+
// cant we move it up to PlatformPatterns? withName condition dont looks working
212+
String methodRefName = ((MethodReference) psiElement).getName();
213+
214+
return null != methodRefName && Arrays.asList(methodName).contains(methodRefName);
215+
}
216+
193217
static public PsiElementPattern.Capture<StringLiteralExpression> methodWithFirstStringPattern() {
194218
return PlatformPatterns
195219
.psiElement(StringLiteralExpression.class)
@@ -426,19 +450,28 @@ public static String getStringValue(PsiElement psiElement) {
426450
}
427451

428452
@Nullable
429-
private static String getStringValue(PsiElement psiElement, int depth) {
453+
private static String getStringValue(@Nullable PsiElement psiElement, int depth) {
430454

431-
if(++depth > 5) {
455+
if(psiElement == null || ++depth > 5) {
432456
return null;
433457
}
434458

435459
if(psiElement instanceof StringLiteralExpression) {
436460
return ((StringLiteralExpression) psiElement).getContents();
437461
}
438462

463+
if(psiElement instanceof Field) {
464+
return getStringValue(((Field) psiElement).getDefaultValue(), depth);
465+
}
466+
439467
if(psiElement instanceof PhpReference) {
440-
PsiElement ref = psiElement.getReference().resolve();
441468

469+
PsiReference psiReference = psiElement.getReference();
470+
if(psiReference == null) {
471+
return null;
472+
}
473+
474+
PsiElement ref = psiReference.resolve();
442475
if(ref instanceof PhpReference) {
443476
return getStringValue(psiElement, depth);
444477
}
@@ -451,8 +484,6 @@ private static String getStringValue(PsiElement psiElement, int depth) {
451484
}
452485
}
453486

454-
455-
456487
}
457488

458489
return null;

0 commit comments

Comments
 (0)
Please sign in to comment.