Skip to content

WIP: form field navigation and linemarker for Twig #1530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNu
if(lineOverwrites != null) {
results.add(lineOverwrites);
}
} else if(TwigPattern.getFunctionPattern("form_row", "form_widget").accepts(psiElement)) {
LineMarkerInfo lineOverwrites = attachFormTypeFields(psiElement);
if(lineOverwrites != null) {
results.add(lineOverwrites);
}
}
}
}
Expand Down Expand Up @@ -299,7 +304,45 @@ private LineMarkerInfo attachBlockOverwrites(@NotNull PsiElement psiElement, @No

NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.OVERRIDES)
.setTargets(new BlockOverwriteLazyValue(psiElement))
.setTooltipText("Overwrites")
.setTooltipText("Navigate to form")
.setCellRenderer(new MyBlockListCellRenderer());

return builder.createLineMarkerInfo(firstChild);
}

@Nullable
private LineMarkerInfo attachFormTypeFields(@NotNull PsiElement psiElement) {
PsiElement firstChild = psiElement.getFirstChild();
if (firstChild == null) {
return null;
}

PsiElement nextSiblingOfType = PsiElementUtils.getNextSiblingOfType(firstChild, PlatformPatterns.psiElement().withElementType(TwigTokenTypes.IDENTIFIER).beforeLeaf(PlatformPatterns.psiElement(TwigTokenTypes.RBRACE)));
if (nextSiblingOfType == null) {
return null;
}

Collection<TwigTypeContainer> twigTypeContainers = TwigTypeResolveUtil.resolveTwigMethodName(nextSiblingOfType, TwigTypeResolveUtil.formatPsiTypeNameWithCurrent(nextSiblingOfType));

Collection<PsiElement> targets = new HashSet<>();

for (TwigTypeContainer twigTypeContainer : twigTypeContainers) {
Object dataHolder = twigTypeContainer.getDataHolder();
if (dataHolder instanceof FormDataHolder && PhpElementsUtil.isInstanceOf(((FormDataHolder) dataHolder).getFormType(), "\\Symfony\\Component\\Form\\FormTypeInterface")) {
PsiElement field = ((FormDataHolder) dataHolder).getField();
if (field != null) {
targets.add(field);
}
}
}

if (targets.isEmpty()) {
return null;
}

NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.FORM_TYPE_LINE_MARKER)
.setTargets(targets)
.setTooltipText("Navigate to form field")
.setCellRenderer(new MyBlockListCellRenderer());

return builder.createLineMarkerInfo(psiElement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
Expand All @@ -15,16 +16,20 @@
* @author Daniel Espendiller <[email protected]>
*/
public class TwigTypeContainer {

@Nullable
private PhpNamedElement phpNamedElement;

@Nullable
private String stringElement;

@Nullable
private Object dataHolder;

public TwigTypeContainer(PhpNamedElement phpNamedElement) {
public TwigTypeContainer(@Nullable PhpNamedElement phpNamedElement) {
this.phpNamedElement = phpNamedElement;
}

public TwigTypeContainer(String stringElement) {
public TwigTypeContainer(@Nullable String stringElement) {
this.stringElement = stringElement;
}

Expand Down Expand Up @@ -52,11 +57,12 @@ public static Collection<TwigTypeContainer> fromCollection(Project project, Coll
return twigTypeContainerList;
}

public TwigTypeContainer withDataHolder(Object object) {
public TwigTypeContainer withDataHolder(@NotNull Object object) {
this.dataHolder = object;
return this;
}

@Nullable
public Object getDataHolder() {
return dataHolder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,20 +123,23 @@ private static void attachFormFields(@Nullable MethodReference methodReference,
}

@NotNull
private static List<TwigTypeContainer> getTwigTypeContainer(@NotNull Method method, @NotNull PhpClass formTypClass) {
List<TwigTypeContainer> twigTypeContainers = new ArrayList<>();
private static Collection<TwigTypeContainer> getTwigTypeContainer(@NotNull Method method, @NotNull PhpClass formTypClass) {
Collection<TwigTypeContainer> twigTypeContainers = new ArrayList<>();

for(MethodReference methodReference: FormUtil.getFormBuilderTypes(method)) {

String fieldName = PsiElementUtils.getMethodParameterAt(methodReference, 0);
if (fieldName == null) {
continue;
}

PsiElement psiElement = PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 1);
TwigTypeContainer twigTypeContainer = new TwigTypeContainer(fieldName);

// find form field type
if(psiElement != null) {
PhpClass fieldType = FormUtil.getFormTypeClassOnParameter(psiElement);
if(fieldType != null) {
twigTypeContainer.withDataHolder(new FormDataHolder(fieldType, formTypClass));
twigTypeContainer.withDataHolder(new FormDataHolder(fieldType, formTypClass, psiElement));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package fr.adrienbrault.idea.symfony2plugin.templating.variable.resolver.holder;

import com.intellij.psi.PsiElement;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Daniel Espendiller <[email protected]>
Expand All @@ -13,11 +15,20 @@ public class FormDataHolder {
@NotNull
private final PhpClass formType;

@Nullable
private PsiElement field;

public FormDataHolder(@NotNull PhpClass phpClass, @NotNull PhpClass formType) {
this.phpClass = phpClass;
this.formType = formType;
}

public FormDataHolder(@NotNull PhpClass phpClass, @NotNull PhpClass formType, @NotNull PsiElement field) {
this.phpClass = phpClass;
this.formType = formType;
this.field = field;
}

@NotNull
public PhpClass getPhpClass() {
return phpClass;
Expand All @@ -27,4 +38,9 @@ public PhpClass getPhpClass() {
public PhpClass getFormType() {
return formType;
}

@Nullable
public PsiElement getField() {
return this.field;
}
}