Skip to content

Commit 1cbfa3c

Browse files
committed
fix "Cannot resolve symbol" for factory service regression #791
1 parent a701f48 commit 1cbfa3c

File tree

9 files changed

+262
-62
lines changed

9 files changed

+262
-62
lines changed

src/fr/adrienbrault/idea/symfony2plugin/completion/xml/XmlGotoCompletionRegistrar.java

+56
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,34 @@
55
import com.intellij.patterns.XmlPatterns;
66
import com.intellij.psi.PsiElement;
77
import com.intellij.psi.PsiFile;
8+
import com.intellij.psi.PsiReference;
9+
import com.intellij.psi.util.PsiTreeUtil;
810
import com.intellij.psi.xml.XmlAttribute;
911
import com.intellij.psi.xml.XmlAttributeValue;
1012
import com.intellij.psi.xml.XmlTag;
1113
import com.intellij.psi.xml.XmlToken;
14+
import com.intellij.util.containers.ContainerUtil;
15+
import com.jetbrains.php.completion.PhpLookupElement;
16+
import com.jetbrains.php.lang.psi.elements.Method;
17+
import com.jetbrains.php.lang.psi.elements.PhpClass;
1218
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
19+
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
1320
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionProvider;
1421
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionRegistrar;
1522
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionRegistrarParameter;
1623
import fr.adrienbrault.idea.symfony2plugin.codeInsight.utils.GotoCompletionUtil;
1724
import fr.adrienbrault.idea.symfony2plugin.config.xml.XmlHelper;
25+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
1826
import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil;
1927
import fr.adrienbrault.idea.symfony2plugin.util.resource.FileResourceUtil;
2028
import org.apache.commons.lang.StringUtils;
2129
import org.jetbrains.annotations.NotNull;
30+
import org.jetbrains.annotations.Nullable;
2231

2332
import java.util.ArrayList;
2433
import java.util.Collection;
2534
import java.util.Collections;
35+
import java.util.stream.Collectors;
2636

2737
public class XmlGotoCompletionRegistrar implements GotoCompletionRegistrar {
2838

@@ -39,6 +49,15 @@ public void register(GotoCompletionRegistrarParameter registrar) {
3949
XmlPatterns.psiElement().withParent(XmlHelper.getServiceIdNamePattern()),
4050
ServiceIdCompletionProvider::new
4151
);
52+
53+
// <factory class="AppBundle\Trivago\ConfigFactory" method="create"/>
54+
// <factory service="foo" method="create"/>
55+
registrar.register(
56+
XmlPatterns.psiElement().withParent(XmlHelper.getTagAttributePattern("factory", "method")
57+
.inside(XmlHelper.getInsideTagPattern("services"))
58+
.inFile(XmlHelper.getXmlFilePattern())),
59+
ServiceFactoryMethodCompletionProvider::new
60+
);
4261
}
4362

4463
private static class ImportResourceGotoCompletionProvider extends GotoCompletionProvider {
@@ -114,4 +133,41 @@ public Collection<PsiElement> getPsiTargets(PsiElement element) {
114133
return Collections.emptyList();
115134
}
116135
}
136+
137+
private static class ServiceFactoryMethodCompletionProvider extends GotoCompletionProvider {
138+
ServiceFactoryMethodCompletionProvider(PsiElement element) {
139+
super(element);
140+
}
141+
142+
@NotNull
143+
@Override
144+
public Collection<LookupElement> getLookupElements() {
145+
PsiElement parent = getElement().getParent();
146+
if(!(parent instanceof XmlAttributeValue)) {
147+
return Collections.emptyList();
148+
}
149+
150+
Collection<PhpClass> phpClasses = new ArrayList<>();
151+
152+
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForClassFactory((XmlAttributeValue) parent));
153+
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForServiceFactory((XmlAttributeValue) parent));
154+
155+
Collection<LookupElement> lookupElements = new ArrayList<>();
156+
157+
for (PhpClass phpClass : phpClasses) {
158+
lookupElements.addAll(PhpElementsUtil.getClassPublicMethod(phpClass).stream()
159+
.map(PhpLookupElement::new)
160+
.collect(Collectors.toList())
161+
);
162+
}
163+
164+
return lookupElements;
165+
}
166+
167+
@NotNull
168+
@Override
169+
public Collection<PsiElement> getPsiTargets(PsiElement element) {
170+
return Collections.emptyList();
171+
}
172+
}
117173
}

src/fr/adrienbrault/idea/symfony2plugin/config/ClassPublicMethodReference.java

+2-12
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,15 @@ public class ClassPublicMethodReference extends PsiPolyVariantReferenceBase<PsiE
2222
private String className;
2323
private String method;
2424

25-
public ClassPublicMethodReference(@NotNull PsiElement element, String className) {
25+
public ClassPublicMethodReference(@NotNull PsiElement element, @NotNull String className) {
2626
super(element);
2727
this.className = className;
2828
this.method = PsiElementUtils.trimQuote(element.getText());
2929
}
3030

31-
public ClassPublicMethodReference(@NotNull StringLiteralExpression element, String className) {
32-
super(element);
33-
this.className = className;
34-
this.method = element.getContents();
35-
}
36-
3731
@NotNull
3832
@Override
3933
public ResolveResult[] multiResolve(boolean incompleteCode) {
40-
4134
PhpClass phpClass = ServiceUtil.getResolvedClassDefinition(getElement().getProject(), this.className);
4235
if(phpClass == null) {
4336
return new ResolveResult[0];
@@ -48,10 +41,7 @@ public ResolveResult[] multiResolve(boolean incompleteCode) {
4841
return new ResolveResult[0];
4942
}
5043

51-
return new ResolveResult[] {
52-
new PsiElementResolveResult(targetMethod)
53-
};
54-
44+
return PsiElementResolveResult.createResults(targetMethod);
5545
}
5646

5747
@NotNull

src/fr/adrienbrault/idea/symfony2plugin/config/xml/XmlHelper.java

+44
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
import com.intellij.psi.impl.source.xml.XmlDocumentImpl;
77
import com.intellij.psi.util.PsiTreeUtil;
88
import com.intellij.psi.xml.*;
9+
import com.jetbrains.php.lang.psi.elements.PhpClass;
10+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
11+
import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil;
912
import org.apache.commons.lang.StringUtils;
13+
import org.jetbrains.annotations.NotNull;
1014
import org.jetbrains.annotations.Nullable;
1115

1216
import java.util.HashMap;
@@ -426,4 +430,44 @@ public static String getServiceDefinitionClass(PsiElement psiInsideService) {
426430
return null;
427431
}
428432

433+
434+
@Nullable
435+
public static PhpClass getPhpClassForClassFactory(@NotNull XmlAttributeValue xmlAttributeValue) {
436+
String method = xmlAttributeValue.getValue();
437+
if(StringUtils.isBlank(method)) {
438+
return null;
439+
}
440+
441+
XmlTag parentOfType = PsiTreeUtil.getParentOfType(xmlAttributeValue, XmlTag.class);
442+
if(parentOfType == null) {
443+
return null;
444+
}
445+
446+
String aClass = parentOfType.getAttributeValue("class");
447+
if(aClass == null || StringUtils.isBlank(aClass)) {
448+
return null;
449+
}
450+
451+
return PhpElementsUtil.getClass(xmlAttributeValue.getProject(), aClass);
452+
}
453+
454+
@Nullable
455+
public static PhpClass getPhpClassForServiceFactory(@NotNull XmlAttributeValue xmlAttributeValue) {
456+
String method = xmlAttributeValue.getValue();
457+
if(StringUtils.isBlank(method)) {
458+
return null;
459+
}
460+
461+
XmlTag callXmlTag = PsiTreeUtil.getParentOfType(xmlAttributeValue, XmlTag.class);
462+
if(callXmlTag == null) {
463+
return null;
464+
}
465+
466+
String service = callXmlTag.getAttributeValue("service");
467+
if(StringUtils.isBlank(service)) {
468+
return null;
469+
}
470+
471+
return ServiceUtil.getResolvedClassDefinition(xmlAttributeValue.getProject(), service);
472+
}
429473
}

0 commit comments

Comments
 (0)