Skip to content

Commit 1521749

Browse files
committed
#2017 fix [Twig] Go to function definition does not work when using the first-class callable syntax
1 parent 7b53ead commit 1521749

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java

+23-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.util;
22

33
import com.intellij.openapi.project.Project;
4-
import com.intellij.openapi.util.Condition;
54
import com.intellij.openapi.util.Key;
65
import com.intellij.patterns.PlatformPatterns;
76
import com.intellij.psi.PsiElement;
@@ -153,29 +152,45 @@ private static String getCallableSignature(PsiElement psiElement, Method method)
153152
// array($this, 'getUrl')
154153
if(psiElement instanceof ArrayCreationExpression) {
155154
List<PsiElement> arrayValues = (List<PsiElement>) PsiElementUtils.getChildrenOfTypeAsList(psiElement, PlatformPatterns.psiElement(PhpElementTypes.ARRAY_VALUE));
156-
if(arrayValues.size() > 1) {
155+
if (arrayValues.size() > 1) {
157156
PsiElement firstChild = arrayValues.get(0).getFirstChild();
158-
if(firstChild instanceof Variable && "this".equals(((Variable) firstChild).getName())) {
157+
if (firstChild instanceof Variable && "this".equals(((Variable) firstChild).getName())) {
159158
String methodName = PhpElementsUtil.getStringValue(arrayValues.get(1).getFirstChild());
160-
if(StringUtils.isNotBlank(methodName)) {
159+
if (StringUtils.isNotBlank(methodName)) {
161160
PhpClass phpClass = method.getContainingClass();
162-
if(phpClass != null) {
161+
if (phpClass != null) {
163162
return String.format("#M#C\\%s.%s", phpClass.getPresentableFQN(), methodName);
164163
}
165164
}
166165
} else if (firstChild instanceof ClassConstantReference) {
167166
String classConstantPhpFqn = PhpElementsUtil.getClassConstantPhpFqn((ClassConstantReference) firstChild);
168167
if (StringUtils.isNotEmpty(classConstantPhpFqn)) {
169168
String methodName = PhpElementsUtil.getStringValue(arrayValues.get(1).getFirstChild());
170-
if(StringUtils.isNotBlank(methodName)) {
169+
if (StringUtils.isNotBlank(methodName)) {
171170
PhpClass phpClass = method.getContainingClass();
172-
if(phpClass != null) {
171+
if (phpClass != null) {
173172
return String.format("#M#C\\%s.%s", classConstantPhpFqn, methodName);
174173
}
175174
}
176175
}
177176
}
178177
}
178+
} else if(psiElement instanceof PhpCallableMethod) {
179+
// we need to resolve the type, no api support
180+
// $this->foobar(...)
181+
PsiElement firstChild = ((PhpCallableMethod) psiElement).getFirstPsiChild();
182+
if (firstChild instanceof Variable && "this".equals(((Variable) firstChild).getName())) {
183+
PhpClass phpClass = method.getContainingClass();
184+
if (phpClass != null) {
185+
return String.format("#M#C\\%s.%s", phpClass.getPresentableFQN(), ((PhpCallableMethod) psiElement).getName());
186+
}
187+
}
188+
} else if(psiElement instanceof PhpCallableFunction) {
189+
// foobar(...)
190+
String name = ((PhpCallableFunction) psiElement).getName();
191+
if (StringUtils.isNotBlank(name)) {
192+
return "#F" + name;
193+
}
179194
} else {
180195
String funcTargetName = PhpElementsUtil.getStringValue(psiElement);
181196
if(funcTargetName != null) {
@@ -470,7 +485,7 @@ private void visitNewExpression(@NotNull NewExpression element) {
470485
}
471486

472487
// creation options like: needs_environment
473-
Map<String, String> options;
488+
Map<String, String> options = new HashMap<>();
474489
if(psiElement.length > 2 && psiElement[2] instanceof ArrayCreationExpression) {
475490
options = getOptions((ArrayCreationExpression) psiElement[2]);
476491
} else {

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigExtensionParserTest.java

+10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ public void testExtensionAreCollected() {
5858
"#M#C\\ClassInstance.getFoobar",
5959
TwigExtensionParser.getFunctions(getProject()).get("class_instance_foobar").getSignature()
6060
);
61+
62+
assertEquals(
63+
"#M#C\\Twig\\Extensions.getFoobar",
64+
TwigExtensionParser.getFunctions(getProject()).get("class_php_callable_method_foobar").getSignature()
65+
);
66+
67+
assertEquals(
68+
"#Fmax",
69+
TwigExtensionParser.getFunctions(getProject()).get("class_php_callable_function_foobar").getSignature()
70+
);
6171
}
6272

6373
public void testExtensionAreCollectedForDeprecated() {

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/fixtures/twig_extensions.php

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ public function getFunctions()
109109
new \Twig_Function('max_2', 'max'),
110110
new TwigFunction('max_3', 'max'),
111111
new TwigFunction('class_instance_foobar', [\ClassInstance::class, 'getFoobar']),
112+
new TwigFunction('class_php_callable_method_foobar', $this->getFoobar(...)),
113+
new TwigFunction('class_php_callable_function_foobar', max(...)),
112114
];
113115
}
114116

0 commit comments

Comments
 (0)