Skip to content

Commit e3ac5df

Browse files
committed
add basic form field completion in twig on FormInterface::createView variables
1 parent 6d98ca8 commit e3ac5df

File tree

7 files changed

+138
-17
lines changed

7 files changed

+138
-17
lines changed

src/fr/adrienbrault/idea/symfony2plugin/form/util/FormFieldNameReference.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public PsiElement resolve() {
5252
@NotNull
5353
@Override
5454
public Object[] getVariants() {
55+
return getFormLookups(method);
56+
}
57+
58+
public static LookupElement[] getFormLookups(Method method) {
5559

5660
MethodReference[] formBuilderTypes = FormUtil.getFormBuilderTypes(method);
5761
List<LookupElement> lookupElements = new ArrayList<LookupElement>();
@@ -63,7 +67,7 @@ public Object[] getVariants() {
6367
}
6468
}
6569

66-
return lookupElements.toArray();
70+
return lookupElements.toArray(new LookupElement[lookupElements.size()]);
6771
}
6872

6973
}

src/fr/adrienbrault/idea/symfony2plugin/form/util/FormUtil.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,24 @@ public static PhpClass resolveFormGetterCall(MethodReference methodReference) {
122122
return null;
123123
}
124124

125+
return getFormTypeClass((MethodReference) calledMethodReference);
126+
127+
}
128+
129+
public static PhpClass getFormTypeClass(@Nullable MethodReference calledMethodReference) {
130+
131+
if(calledMethodReference == null) {
132+
return null;
133+
}
134+
125135
if(new Symfony2InterfacesUtil().isCallTo(calledMethodReference, "\\Symfony\\Component\\Form\\FormFactory", "create")) {
126136
return null;
127137
}
128138

129139
// $form = "$this->createForm("new Type()", $entity)";
130-
PsiElement formType = PsiElementUtils.getMethodParameterPsiElementAt((MethodReference) calledMethodReference, 0);
140+
PsiElement formType = PsiElementUtils.getMethodParameterPsiElementAt(calledMethodReference, 0);
131141

132142
return getFormTypeClassOnParameter(formType);
133-
134143
}
135144

136145
/**

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,18 @@ public static Collection<TwigTypeContainer> resolveTwigMethodName(PsiElement psi
8787
return Collections.emptyList();
8888
}
8989

90-
Collection<? extends PhpNamedElement> rootVariable = getRootVariableByName(psiElement, typeName[0]);
90+
List<PsiVariable> rootVariables = getRootVariableByName(psiElement, typeName[0]);
9191
if(typeName.length == 1) {
9292

93-
Collection<TwigTypeContainer> twigTypeContainers = TwigTypeContainer.fromCollection(rootVariable);
94-
93+
Collection<TwigTypeContainer> twigTypeContainers = TwigTypeContainer.fromCollection(psiElement.getProject(), rootVariables);
9594
for(TwigTypeResolver twigTypeResolver: twigTypeResolvers) {
96-
twigTypeResolver.resolve(twigTypeContainers, twigTypeContainers, typeName[0], new ArrayList<List<TwigTypeContainer>>());
95+
twigTypeResolver.resolve(twigTypeContainers, twigTypeContainers, typeName[0], new ArrayList<List<TwigTypeContainer>>(), rootVariables);
9796
}
9897

9998
return twigTypeContainers;
10099
}
101100

102-
Collection<TwigTypeContainer> type = TwigTypeContainer.fromCollection(rootVariable);
101+
Collection<TwigTypeContainer> type = TwigTypeContainer.fromCollection(psiElement.getProject(), rootVariables);
103102
Collection<List<TwigTypeContainer>> previousElements = new ArrayList<List<TwigTypeContainer>> ();
104103
previousElements.add(new ArrayList<TwigTypeContainer>(type));
105104

@@ -267,12 +266,13 @@ public boolean value(PsiElement psiElement) {
267266

268267
}
269268

270-
private static Collection<? extends PhpNamedElement> getRootVariableByName(PsiElement psiElement, String variableName) {
269+
private static List<PsiVariable> getRootVariableByName(PsiElement psiElement, String variableName) {
271270

272-
ArrayList<PhpNamedElement> phpNamedElements = new ArrayList<PhpNamedElement>();
271+
List<PsiVariable> phpNamedElements = new ArrayList<PsiVariable>();
273272
for(Map.Entry<String, PsiVariable> variable : collectScopeVariables(psiElement).entrySet()) {
274273
if(variable.getKey().equals(variableName)) {
275-
phpNamedElements.addAll(PhpElementsUtil.getClassFromPhpTypeSet(psiElement.getProject(), variable.getValue().getTypes()));
274+
phpNamedElements.add(variable.getValue());
275+
//phpNamedElements.addAll(PhpElementsUtil.getClassFromPhpTypeSet(psiElement.getProject(), variable.getValue().getTypes()));
276276
}
277277

278278
}
@@ -300,7 +300,7 @@ private static Collection<TwigTypeContainer> resolveTwigMethodName(Collection<Tw
300300
}
301301

302302
for(TwigTypeResolver twigTypeResolver: twigTypeResolvers) {
303-
twigTypeResolver.resolve(phpNamedElements, previousElement, typeName, twigTypeContainer);
303+
twigTypeResolver.resolve(phpNamedElements, previousElement, typeName, twigTypeContainer, null);
304304
}
305305

306306
}

src/fr/adrienbrault/idea/symfony2plugin/templating/variable/TwigTypeContainer.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.variable;
22

3+
import com.intellij.openapi.project.Project;
4+
import com.jetbrains.php.lang.psi.elements.PhpClass;
35
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
6+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
7+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
48
import org.jetbrains.annotations.Nullable;
59

610
import java.util.ArrayList;
@@ -30,12 +34,15 @@ public String getStringElement() {
3034
return stringElement;
3135
}
3236

33-
public static Collection<TwigTypeContainer> fromCollection(Collection<? extends PhpNamedElement> phpNamedElements) {
37+
public static Collection<TwigTypeContainer> fromCollection(Project project, List<PsiVariable> psiVariables) {
3438

3539
List<TwigTypeContainer> twigTypeContainerList = new ArrayList<TwigTypeContainer>();
3640

37-
for(PhpNamedElement phpNamedElement :phpNamedElements) {
38-
twigTypeContainerList.add(new TwigTypeContainer(phpNamedElement));
41+
for(PsiVariable phpNamedElement :psiVariables) {
42+
Collection<PhpClass> phpClass = PhpElementsUtil.getClassFromPhpTypeSet(project, phpNamedElement.getTypes());
43+
if(phpClass.size() > 0) {
44+
twigTypeContainerList.add(new TwigTypeContainer(phpClass.iterator().next()));
45+
}
3946
}
4047

4148
return twigTypeContainerList;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package fr.adrienbrault.idea.symfony2plugin.templating.variable.resolver;
2+
3+
import com.google.common.collect.Iterables;
4+
import com.intellij.codeInsight.lookup.LookupElement;
5+
import com.intellij.psi.PsiElement;
6+
import com.intellij.psi.util.PsiTreeUtil;
7+
import com.jetbrains.php.lang.psi.elements.Method;
8+
import com.jetbrains.php.lang.psi.elements.MethodReference;
9+
import com.jetbrains.php.lang.psi.elements.PhpClass;
10+
import com.jetbrains.php.lang.psi.elements.Variable;
11+
import fr.adrienbrault.idea.symfony2plugin.Symfony2InterfacesUtil;
12+
import fr.adrienbrault.idea.symfony2plugin.dic.MethodReferenceBag;
13+
import fr.adrienbrault.idea.symfony2plugin.form.util.FormFieldNameReference;
14+
import fr.adrienbrault.idea.symfony2plugin.form.util.FormUtil;
15+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigTypeContainer;
16+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
17+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
18+
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
19+
import org.jetbrains.annotations.Nullable;
20+
21+
import java.util.Collection;
22+
import java.util.List;
23+
24+
public class FormFieldResolver implements TwigTypeResolver {
25+
26+
public void resolve(Collection<TwigTypeContainer> targets, Collection<TwigTypeContainer> previousElement, String typeName, Collection<List<TwigTypeContainer>> previousElements, @Nullable List<PsiVariable> psiVariables) {
27+
28+
if(psiVariables == null || previousElements == null || previousElements.size() != 0) {
29+
return;
30+
}
31+
32+
Symfony2InterfacesUtil symfony2InterfacesUtil = new Symfony2InterfacesUtil();
33+
TwigTypeContainer twigTypeContainer = targets.iterator().next();
34+
35+
if(twigTypeContainer.getPhpNamedElement() instanceof PhpClass) {
36+
if(symfony2InterfacesUtil.isInstanceOf((PhpClass) twigTypeContainer.getPhpNamedElement(), "\\Symfony\\Component\\Form\\FormView")) {
37+
if(psiVariables.size() > 0) {
38+
PsiElement var = psiVariables.get(0).getElement();
39+
40+
// $form->createView()
41+
if(var instanceof MethodReference) {
42+
PsiElement form = var.getFirstChild();
43+
if(form instanceof Variable) {
44+
PsiElement varDecl = ((Variable) form).resolve();
45+
if(varDecl instanceof Variable) {
46+
MethodReference methodReference = PsiTreeUtil.getNextSiblingOfType(varDecl, MethodReference.class);
47+
attachFormFields(methodReference, targets);
48+
}
49+
}
50+
}
51+
52+
/*
53+
// $form
54+
if(var instanceof Variable) {
55+
PsiElement varDecl = ((Variable) var).resolve();
56+
if(varDecl instanceof Variable) {
57+
MethodReference methodReference = PsiTreeUtil.getNextSiblingOfType(varDecl, MethodReference.class);
58+
attachFormFields(methodReference, targets);
59+
}
60+
} */
61+
62+
}
63+
}
64+
65+
}
66+
}
67+
68+
private static void attachFormFields(@Nullable MethodReference methodReference, Collection<TwigTypeContainer> targets) {
69+
70+
if(methodReference == null) {
71+
return;
72+
}
73+
74+
Symfony2InterfacesUtil symfony2InterfacesUtil = new Symfony2InterfacesUtil();
75+
if(symfony2InterfacesUtil.isCallTo(methodReference, "\\Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller", "createForm")) {
76+
PsiElement formType = PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0);
77+
if(formType != null) {
78+
PhpClass phpClass = FormUtil.getFormTypeClassOnParameter(formType);
79+
80+
if(phpClass == null) {
81+
return;
82+
}
83+
84+
Method method = PhpElementsUtil.getClassMethod(phpClass, "buildForm");
85+
if(method == null) {
86+
return;
87+
}
88+
89+
for(LookupElement lookupElement: FormFieldNameReference.getFormLookups(method)) {
90+
targets.add(new TwigTypeContainer(lookupElement.getLookupString()));
91+
}
92+
}
93+
94+
}
95+
96+
}
97+
98+
}

src/fr/adrienbrault/idea/symfony2plugin/templating/variable/resolver/FormVarsResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import com.jetbrains.php.lang.psi.elements.PhpClass;
55
import fr.adrienbrault.idea.symfony2plugin.Symfony2InterfacesUtil;
66
import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigTypeContainer;
7+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
8+
import org.jetbrains.annotations.Nullable;
79

810
import java.util.Collection;
911
import java.util.List;
1012

1113
public class FormVarsResolver implements TwigTypeResolver {
1214

13-
public void resolve(Collection<TwigTypeContainer> targets, Collection<TwigTypeContainer> previousElement, String typeName, Collection<List<TwigTypeContainer>> previousElements) {
15+
public void resolve(Collection<TwigTypeContainer> targets, Collection<TwigTypeContainer> previousElement, String typeName, Collection<List<TwigTypeContainer>> previousElements, @Nullable List<PsiVariable> psiVariables) {
1416

1517
if(!"vars".equals(typeName) || previousElements.size() == 0) {
1618
return;
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.variable.resolver;
22

33
import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigTypeContainer;
4+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
45
import org.jetbrains.annotations.Nullable;
56

67
import java.util.Collection;
78
import java.util.List;
89

910
public interface TwigTypeResolver {
10-
public void resolve(Collection<TwigTypeContainer> targets, @Nullable Collection<TwigTypeContainer> previousElement, String typeName, Collection<List<TwigTypeContainer>> previousElements);
11+
public void resolve(Collection<TwigTypeContainer> targets, @Nullable Collection<TwigTypeContainer> previousElement, String typeName, Collection<List<TwigTypeContainer>> previousElements, @Nullable List<PsiVariable> psiVariables);
1112
}

0 commit comments

Comments
 (0)