Skip to content

Commit 346ef00

Browse files
committed
respect needs_context and needs_environment options for twig extensions #314
1 parent 7910d61 commit 346ef00

6 files changed

+65
-48
lines changed

src/fr/adrienbrault/idea/symfony2plugin/TwigHelper.java

-31
Original file line numberDiff line numberDiff line change
@@ -1017,35 +1017,4 @@ public static Collection<LookupElement> getAllTemplateLookupElements(Project pro
10171017
return lookupElements;
10181018
}
10191019

1020-
/**
1021-
* Paramater formatter for twig extension to remove Twig_Environment parameter from completion display
1022-
* ported from com.jetbrains.php.PhpPresentationUtil#formatParameters
1023-
*
1024-
*/
1025-
public static StringBuilder formatParameters(@Nullable StringBuilder b, @NotNull Parameter[] parameters) {
1026-
if (b == null) b = new StringBuilder();
1027-
b.append('(');
1028-
for (int i = 0; i < parameters.length; i++) {
1029-
1030-
if(i == 0) {
1031-
PhpPsiElement classReference = parameters[i].getFirstPsiChild();
1032-
if(classReference instanceof ClassReference) {
1033-
String className = ((ClassReference) classReference).getFQN();
1034-
if(new Symfony2InterfacesUtil().isInstanceOf(parameters[i].getProject(), className, "Twig_Environment")) {
1035-
continue;
1036-
}
1037-
}
1038-
}
1039-
1040-
b.append(PhpPresentationUtil.getParameterPresentation(parameters[i]));
1041-
if (parameters.length - i > 1) {
1042-
b.append(", ");
1043-
}
1044-
1045-
}
1046-
1047-
b.append(')');
1048-
return b;
1049-
}
1050-
10511020
}

src/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ private PsiElement[] getTwigFiles(PsiElement psiElement) {
129129
}
130130

131131
private PsiElement[] getFilterGoTo(PsiElement psiElement) {
132-
HashMap<String, TwigExtension> filters = new TwigExtensionParser(psiElement.getProject()).getFilters();
132+
Map<String, TwigExtension> filters = new TwigExtensionParser(psiElement.getProject()).getFilters();
133133
if(!filters.containsKey(psiElement.getText())) {
134134
return new PsiElement[0];
135135
}

src/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToLocalDeclarationHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private PsiElement[] getTypeGoto(PsiElement psiElement) {
192192
}
193193

194194
private PsiElement[] getFunctions(PsiElement psiElement) {
195-
HashMap<String, TwigExtension> functions = new TwigExtensionParser(psiElement.getProject()).getFunctions();
195+
Map<String, TwigExtension> functions = new TwigExtensionParser(psiElement.getProject()).getFunctions();
196196

197197
String funcName = psiElement.getText();
198198
if(!functions.containsKey(funcName)) {

src/fr/adrienbrault/idea/symfony2plugin/templating/dict/TwigExtension.java

+14
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigExtensionParser;
44
import org.jetbrains.annotations.Nullable;
55

6+
import java.util.HashMap;
7+
import java.util.Map;
8+
69
public class TwigExtension {
710

811
private String signature = null;
912
private TwigExtensionParser.TwigExtensionType twigExtensionType = null;
13+
private Map<String, String> options = new HashMap<String, String>();
1014

1115
public TwigExtension(TwigExtensionParser.TwigExtensionType twigExtensionType) {
1216
this.twigExtensionType = twigExtensionType;
@@ -30,4 +34,14 @@ public String getSignature() {
3034
return signature;
3135
}
3236

37+
public TwigExtension putOption(String key , String value) {
38+
options.put(key, value);
39+
return this;
40+
}
41+
42+
@Nullable
43+
public String getOption(String key) {
44+
return options.containsKey(key) ? options.get(key) : null;
45+
}
46+
3347
}

src/fr/adrienbrault/idea/symfony2plugin/templating/dict/TwigExtensionLookupElement.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
import com.intellij.openapi.project.Project;
66
import com.jetbrains.php.PhpIndex;
77
import com.jetbrains.php.PhpPresentationUtil;
8+
import com.jetbrains.php.lang.psi.elements.Parameter;
89
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
910
import com.jetbrains.php.lang.psi.elements.impl.FunctionImpl;
10-
import fr.adrienbrault.idea.symfony2plugin.TwigHelper;
1111
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigExtensionParser;
1212
import fr.adrienbrault.idea.symfony2plugin.util.StringUtils;
1313
import org.jetbrains.annotations.NotNull;
1414

15-
import java.util.Collection;
15+
import java.util.*;
1616

1717
public class TwigExtensionLookupElement extends LookupElement {
1818

@@ -43,7 +43,14 @@ public void renderElement(LookupElementPresentation presentation) {
4343

4444
PhpNamedElement function = phpNamedElements.iterator().next();
4545
if(function instanceof FunctionImpl) {
46-
presentation.setTailText(TwigHelper.formatParameters(null, ((FunctionImpl) function).getParameters()).toString(), true);
46+
List<Parameter> parameters = new LinkedList<Parameter>(Arrays.asList(((FunctionImpl) function).getParameters()));
47+
if(this.twigExtension.getOption("needs_context") != null && parameters.size() > 0) {
48+
parameters.remove(0);
49+
}
50+
if(this.twigExtension.getOption("needs_environment") != null && parameters.size() > 0) {
51+
parameters.remove(0);
52+
}
53+
presentation.setTailText(PhpPresentationUtil.formatParameters(null, parameters.toArray(new Parameter[parameters.size()])).toString(), true);
4754
}
4855

4956
}

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

+39-12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
1515
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
1616
import org.apache.commons.lang.StringUtils;
17+
import org.jetbrains.annotations.NotNull;
1718
import org.jetbrains.annotations.Nullable;
1819

1920
import javax.swing.*;
@@ -23,21 +24,21 @@ public class TwigExtensionParser {
2324

2425
private Project project;
2526

26-
private HashMap<String, TwigExtension> functions;
27-
private HashMap<String, TwigExtension> filters;
27+
private Map<String, TwigExtension> functions;
28+
private Map<String, TwigExtension> filters;
2829

2930
public TwigExtensionParser(Project project) {
3031
this.project = project;
3132
}
3233

33-
public HashMap<String, TwigExtension> getFunctions() {
34+
public Map<String, TwigExtension> getFunctions() {
3435
if(functions == null) {
3536
this.parseElementType(TwigElementType.METHOD);
3637
}
3738
return functions;
3839
}
3940

40-
public HashMap<String, TwigExtension> getFilters() {
41+
public Map<String, TwigExtension> getFilters() {
4142
if(filters == null) {
4243
this.parseElementType(TwigElementType.FILTER);
4344
}
@@ -98,7 +99,7 @@ private void parseFunctions(Collection<String> classNames) {
9899
}
99100
}
100101

101-
protected Map<String, TwigExtension> parseFunctions(final Method method, final HashMap<String, TwigExtension> filters) {
102+
protected Map<String, TwigExtension> parseFunctions(final Method method, final Map<String, TwigExtension> filters) {
102103

103104
final PhpClass containingClass = method.getContainingClass();
104105
if(containingClass == null) {
@@ -152,7 +153,7 @@ private static String getCallableSignature(PsiElement psiElement, Method method)
152153
return null;
153154
}
154155

155-
protected HashMap<String, TwigExtension> parseFilter(Method method, HashMap<String, TwigExtension> filters) {
156+
protected Map<String, TwigExtension> parseFilter(Method method, Map<String, TwigExtension> filters) {
156157

157158

158159
final PhpClass containingClass = method.getContainingClass();
@@ -188,10 +189,10 @@ public static Icon getIcon(TwigExtensionType twigExtensionType) {
188189
}
189190
private static class TwigFilterVisitor extends PsiRecursiveElementWalkingVisitor {
190191
private final Method method;
191-
private final HashMap<String, TwigExtension> filters;
192+
private final Map<String, TwigExtension> filters;
192193
private final PhpClass containingClass;
193194

194-
public TwigFilterVisitor(Method method, HashMap<String, TwigExtension> filters, PhpClass containingClass) {
195+
public TwigFilterVisitor(Method method, Map<String, TwigExtension> filters, PhpClass containingClass) {
195196
this.method = method;
196197
this.filters = filters;
197198
this.containingClass = containingClass;
@@ -226,7 +227,13 @@ private void visitNewExpression(NewExpressionImpl element) {
226227
signature = getCallableSignature(psiElement[1], method);
227228
}
228229

229-
filters.put(funcName, new TwigExtension(TwigExtensionType.FILTER, signature));
230+
TwigExtension twigExtension = new TwigExtension(TwigExtensionType.FILTER, signature);
231+
232+
if(psiElement.length > 2 && psiElement[2] instanceof ArrayCreationExpression) {
233+
decorateOptions((ArrayCreationExpression) psiElement[2], twigExtension);
234+
}
235+
236+
filters.put(funcName, twigExtension);
230237
}
231238

232239
}
@@ -293,12 +300,27 @@ private void visitNewExpression(NewExpressionImpl element) {
293300
}
294301
}
295302

303+
/**
304+
* Add needs_environment, needs_context values to twig extension object
305+
*/
306+
private static void decorateOptions(@NotNull ArrayCreationExpression arrayCreationExpression, @NotNull TwigExtension twigExtension) {
307+
for(String optionTrue: new String[] {"needs_environment", "needs_context"}) {
308+
PhpPsiElement phpPsiElement = PhpElementsUtil.getArrayValue(arrayCreationExpression, optionTrue);
309+
if(phpPsiElement instanceof ConstantReference) {
310+
String value = phpPsiElement.getName();
311+
if(value != null && value.toLowerCase().equals("true")) {
312+
twigExtension.putOption(optionTrue, "true");
313+
}
314+
}
315+
}
316+
}
317+
296318
private static class TwigFunctionVisitor extends PsiRecursiveElementWalkingVisitor {
297319
private final Method method;
298-
private final HashMap<String, TwigExtension> filters;
320+
private final Map<String, TwigExtension> filters;
299321
private final PhpClass containingClass;
300322

301-
public TwigFunctionVisitor(Method method, HashMap<String, TwigExtension> filters, PhpClass containingClass) {
323+
public TwigFunctionVisitor(Method method, Map<String, TwigExtension> filters, PhpClass containingClass) {
302324
this.method = method;
303325
this.filters = filters;
304326
this.containingClass = containingClass;
@@ -333,7 +355,12 @@ private void visitNewExpression(NewExpressionImpl element) {
333355
signature = getCallableSignature(psiElement[1], method);
334356
}
335357

336-
filters.put(funcName, new TwigExtension(TwigExtensionType.SIMPLE_FUNCTION, signature));
358+
TwigExtension twigExtension = new TwigExtension(TwigExtensionType.SIMPLE_FUNCTION, signature);
359+
if(psiElement.length > 2 && psiElement[2] instanceof ArrayCreationExpression) {
360+
decorateOptions((ArrayCreationExpression) psiElement[2], twigExtension);
361+
}
362+
363+
filters.put(funcName, twigExtension);
337364

338365
}
339366

0 commit comments

Comments
 (0)