Skip to content

Commit bf0869d

Browse files
committed
WIP: form field navigation and linemarker for Twig
1 parent b70e250 commit bf0869d

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigLineMarkerProvider.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNu
110110
if(lineOverwrites != null) {
111111
results.add(lineOverwrites);
112112
}
113+
} else if(TwigPattern.getFunctionPattern("form_row", "form_widget").accepts(psiElement)) {
114+
LineMarkerInfo lineOverwrites = attachFormTypeFields(psiElement);
115+
if(lineOverwrites != null) {
116+
results.add(lineOverwrites);
117+
}
113118
}
114119
}
115120
}
@@ -299,7 +304,45 @@ private LineMarkerInfo attachBlockOverwrites(@NotNull PsiElement psiElement, @No
299304

300305
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.OVERRIDES)
301306
.setTargets(new BlockOverwriteLazyValue(psiElement))
302-
.setTooltipText("Overwrites")
307+
.setTooltipText("Navigate to form")
308+
.setCellRenderer(new MyBlockListCellRenderer());
309+
310+
return builder.createLineMarkerInfo(firstChild);
311+
}
312+
313+
@Nullable
314+
private LineMarkerInfo attachFormTypeFields(@NotNull PsiElement psiElement) {
315+
PsiElement firstChild = psiElement.getFirstChild();
316+
if (firstChild == null) {
317+
return null;
318+
}
319+
320+
PsiElement nextSiblingOfType = PsiElementUtils.getNextSiblingOfType(firstChild, PlatformPatterns.psiElement().withElementType(TwigTokenTypes.IDENTIFIER).beforeLeaf(PlatformPatterns.psiElement(TwigTokenTypes.RBRACE)));
321+
if (nextSiblingOfType == null) {
322+
return null;
323+
}
324+
325+
Collection<TwigTypeContainer> twigTypeContainers = TwigTypeResolveUtil.resolveTwigMethodName(nextSiblingOfType, TwigTypeResolveUtil.formatPsiTypeNameWithCurrent(nextSiblingOfType));
326+
327+
Collection<PsiElement> targets = new HashSet<>();
328+
329+
for (TwigTypeContainer twigTypeContainer : twigTypeContainers) {
330+
Object dataHolder = twigTypeContainer.getDataHolder();
331+
if (dataHolder instanceof FormDataHolder && PhpElementsUtil.isInstanceOf(((FormDataHolder) dataHolder).getFormType(), "\\Symfony\\Component\\Form\\FormTypeInterface")) {
332+
PsiElement field = ((FormDataHolder) dataHolder).getField();
333+
if (field != null) {
334+
targets.add(field);
335+
}
336+
}
337+
}
338+
339+
if (targets.isEmpty()) {
340+
return null;
341+
}
342+
343+
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.FORM_TYPE_LINE_MARKER)
344+
.setTargets(targets)
345+
.setTooltipText("Navigate to form field")
303346
.setCellRenderer(new MyBlockListCellRenderer());
304347

305348
return builder.createLineMarkerInfo(psiElement);

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
66
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
77
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
8+
import org.jetbrains.annotations.NotNull;
89
import org.jetbrains.annotations.Nullable;
910

1011
import java.util.ArrayList;
@@ -15,16 +16,20 @@
1516
* @author Daniel Espendiller <daniel@espendiller.net>
1617
*/
1718
public class TwigTypeContainer {
18-
19+
@Nullable
1920
private PhpNamedElement phpNamedElement;
21+
22+
@Nullable
2023
private String stringElement;
24+
25+
@Nullable
2126
private Object dataHolder;
2227

23-
public TwigTypeContainer(PhpNamedElement phpNamedElement) {
28+
public TwigTypeContainer(@Nullable PhpNamedElement phpNamedElement) {
2429
this.phpNamedElement = phpNamedElement;
2530
}
2631

27-
public TwigTypeContainer(String stringElement) {
32+
public TwigTypeContainer(@Nullable String stringElement) {
2833
this.stringElement = stringElement;
2934
}
3035

@@ -52,11 +57,12 @@ public static Collection<TwigTypeContainer> fromCollection(Project project, Coll
5257
return twigTypeContainerList;
5358
}
5459

55-
public TwigTypeContainer withDataHolder(Object object) {
60+
public TwigTypeContainer withDataHolder(@NotNull Object object) {
5661
this.dataHolder = object;
5762
return this;
5863
}
5964

65+
@Nullable
6066
public Object getDataHolder() {
6167
return dataHolder;
6268
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/variable/resolver/FormFieldResolver.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,23 @@ private static void attachFormFields(@Nullable MethodReference methodReference,
123123
}
124124

125125
@NotNull
126-
private static List<TwigTypeContainer> getTwigTypeContainer(@NotNull Method method, @NotNull PhpClass formTypClass) {
127-
List<TwigTypeContainer> twigTypeContainers = new ArrayList<>();
126+
private static Collection<TwigTypeContainer> getTwigTypeContainer(@NotNull Method method, @NotNull PhpClass formTypClass) {
127+
Collection<TwigTypeContainer> twigTypeContainers = new ArrayList<>();
128128

129129
for(MethodReference methodReference: FormUtil.getFormBuilderTypes(method)) {
130-
131130
String fieldName = PsiElementUtils.getMethodParameterAt(methodReference, 0);
131+
if (fieldName == null) {
132+
continue;
133+
}
134+
132135
PsiElement psiElement = PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 1);
133136
TwigTypeContainer twigTypeContainer = new TwigTypeContainer(fieldName);
134137

135138
// find form field type
136139
if(psiElement != null) {
137140
PhpClass fieldType = FormUtil.getFormTypeClassOnParameter(psiElement);
138141
if(fieldType != null) {
139-
twigTypeContainer.withDataHolder(new FormDataHolder(fieldType, formTypClass));
142+
twigTypeContainer.withDataHolder(new FormDataHolder(fieldType, formTypClass, psiElement));
140143
}
141144
}
142145

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/variable/resolver/holder/FormDataHolder.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.variable.resolver.holder;
22

3+
import com.intellij.psi.PsiElement;
34
import com.jetbrains.php.lang.psi.elements.PhpClass;
45
import org.jetbrains.annotations.NotNull;
6+
import org.jetbrains.annotations.Nullable;
57

68
/**
79
* @author Daniel Espendiller <daniel@espendiller.net>
@@ -13,11 +15,20 @@ public class FormDataHolder {
1315
@NotNull
1416
private final PhpClass formType;
1517

18+
@Nullable
19+
private PsiElement field;
20+
1621
public FormDataHolder(@NotNull PhpClass phpClass, @NotNull PhpClass formType) {
1722
this.phpClass = phpClass;
1823
this.formType = formType;
1924
}
2025

26+
public FormDataHolder(@NotNull PhpClass phpClass, @NotNull PhpClass formType, @NotNull PsiElement field) {
27+
this.phpClass = phpClass;
28+
this.formType = formType;
29+
this.field = field;
30+
}
31+
2132
@NotNull
2233
public PhpClass getPhpClass() {
2334
return phpClass;
@@ -27,4 +38,9 @@ public PhpClass getPhpClass() {
2738
public PhpClass getFormType() {
2839
return formType;
2940
}
41+
42+
@Nullable
43+
public PsiElement getField() {
44+
return this.field;
45+
}
3046
}

0 commit comments

Comments
 (0)