Skip to content

Commit bb9a86c

Browse files
authored
Merge pull request #1981 from Haehnchen/feature/data-class-linemarker
provide a form data_class linemarker
2 parents a104bcd + e88ebf9 commit bb9a86c

File tree

5 files changed

+130
-20
lines changed

5 files changed

+130
-20
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/form/FormTypeReferenceContributor.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
1818
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
1919
import org.jetbrains.annotations.NotNull;
20+
import org.jetbrains.annotations.Nullable;
2021

2122
import java.util.ArrayList;
2223
import java.util.Collection;
@@ -164,26 +165,7 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @No
164165
return new PsiReference[0];
165166
}
166167

167-
Collection<String> classes = new ArrayList<>();
168-
169-
// $resolver->setDefaults(['data_class' => User::class]);
170-
PsiElement className = PhpElementsUtil.getArrayKeyValueInsideSignaturePsi(psiElement, FormOptionsUtil.FORM_OPTION_METHODS, "setDefaults", "data_class");
171-
if(className != null) {
172-
String stringValue = PhpElementsUtil.getStringValue(className);
173-
if(stringValue != null) {
174-
classes.add(stringValue);
175-
}
176-
}
177-
178-
// $resolver->setDefault('data_class', User::class);
179-
classes.addAll(FormOptionsUtil.getMethodReferenceStringParameter(psiElement, FormOptionsUtil.FORM_OPTION_METHODS, "setDefault", "data_class"));
180-
181-
// find first class
182-
PhpClass phpClass = classes.stream()
183-
.map(clazz -> PhpElementsUtil.getClassInterface(psiElement.getProject(), clazz))
184-
.filter(Objects::nonNull).findFirst()
185-
.orElse(null);
186-
168+
PhpClass phpClass = getFormPhpClassFromContext(psiElement);
187169
if(phpClass == null) {
188170
return new PsiReference[0];
189171
}
@@ -345,6 +327,31 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @No
345327
);
346328
}
347329

330+
@Nullable
331+
public static PhpClass getFormPhpClassFromContext(@NotNull PsiElement psiElement) {
332+
Collection<String> classes = new ArrayList<>();
333+
334+
// $resolver->setDefaults(['data_class' => User::class]);
335+
PsiElement className = PhpElementsUtil.getArrayKeyValueInsideSignaturePsi(psiElement, FormOptionsUtil.FORM_OPTION_METHODS, "setDefaults", "data_class");
336+
if(className != null) {
337+
String stringValue = PhpElementsUtil.getStringValue(className);
338+
if(stringValue != null) {
339+
classes.add(stringValue);
340+
}
341+
}
342+
343+
// $resolver->setDefault('data_class', User::class);
344+
classes.addAll(FormOptionsUtil.getMethodReferenceStringParameter(psiElement, FormOptionsUtil.FORM_OPTION_METHODS, "setDefault", "data_class"));
345+
346+
// find first class
347+
PhpClass phpClass = classes.stream()
348+
.map(clazz -> PhpElementsUtil.getClassInterface(psiElement.getProject(), clazz))
349+
.filter(Objects::nonNull).findFirst()
350+
.orElse(null);
351+
352+
return phpClass;
353+
}
354+
348355
private static class FormTypeReferenceRef extends FormTypeReference {
349356
public FormTypeReferenceRef(@NotNull StringLiteralExpression element) {
350357
super(element);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package fr.adrienbrault.idea.symfony2plugin.form;
2+
3+
import com.intellij.codeInsight.daemon.LineMarkerInfo;
4+
import com.intellij.codeInsight.daemon.LineMarkerProvider;
5+
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
6+
import com.intellij.psi.PsiElement;
7+
import com.jetbrains.php.lang.psi.elements.PhpClass;
8+
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
9+
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
10+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
11+
import org.jetbrains.annotations.NotNull;
12+
import org.jetbrains.annotations.Nullable;
13+
14+
import java.util.Collection;
15+
import java.util.List;
16+
17+
/**
18+
* @author Daniel Espendiller <daniel@espendiller.net>
19+
*/
20+
public class PhpLineMarkerProvider implements LineMarkerProvider {
21+
@Nullable
22+
@Override
23+
public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement psiElement) {
24+
return null;
25+
}
26+
27+
@Override
28+
public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElements, @NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos) {
29+
if(psiElements.size() == 0 || !Symfony2ProjectComponent.isEnabled(psiElements.get(0))) {
30+
return;
31+
}
32+
33+
for (PsiElement psiElement : psiElements) {
34+
if (PhpElementsUtil.getClassNamePattern().accepts(psiElement)) {
35+
attachFormDataClass(lineMarkerInfos, psiElement);
36+
}
37+
}
38+
}
39+
40+
private void attachFormDataClass(@NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos, @NotNull PsiElement leaf) {
41+
PsiElement phpClassContext = leaf.getContext();
42+
if(!(phpClassContext instanceof PhpClass) || !PhpElementsUtil.isInstanceOf((PhpClass) phpClassContext, "\\Symfony\\Component\\Form\\FormTypeInterface")) {
43+
return;
44+
}
45+
46+
PhpClass formDataClass = FormTypeReferenceContributor.getFormPhpClassFromContext(leaf);
47+
if (formDataClass != null) {
48+
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.SYMFONY_LINE_MARKER)
49+
.setTargets(formDataClass)
50+
.setTooltipText("Navigate to data class");
51+
52+
lineMarkerInfos.add(builder.createLineMarkerInfo(leaf));
53+
}
54+
}
55+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@
238238
<codeInsight.lineMarkerProvider language="yaml" implementationClass="fr.adrienbrault.idea.symfony2plugin.dic.linemarker.YamlLineMarkerProvider"/>
239239
<codeInsight.lineMarkerProvider language="yaml" implementationClass="fr.adrienbrault.idea.symfony2plugin.config.ConfigLineMarkerProvider"/>
240240
<codeInsight.lineMarkerProvider language="XML" implementationClass="fr.adrienbrault.idea.symfony2plugin.doctrine.metadata.DoctrineMetadataLineMarkerProvider"/>
241+
<codeInsight.lineMarkerProvider language="PHP" implementationClass="fr.adrienbrault.idea.symfony2plugin.form.PhpLineMarkerProvider"/>
241242

242243
<gotoSymbolContributor implementation="fr.adrienbrault.idea.symfony2plugin.navigation.ServiceSymbolContributor"/>
243244
<gotoSymbolContributor implementation="fr.adrienbrault.idea.symfony2plugin.navigation.RouteSymbolContributor"/>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.form;
2+
3+
import com.jetbrains.php.lang.PhpFileType;
4+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
5+
6+
/**
7+
* @author Daniel Espendiller <daniel@espendiller.net>
8+
* @see fr.adrienbrault.idea.symfony2plugin.form.PhpLineMarkerProvider
9+
*/
10+
public class PhpLineMarkerProviderTest extends SymfonyLightCodeInsightFixtureTestCase {
11+
public void setUp() throws Exception {
12+
super.setUp();
13+
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("classes.php"));
14+
}
15+
16+
protected String getTestDataPath() {
17+
return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/form/fixtures";
18+
}
19+
20+
public void testThatRouteLineMarkerForControllerIsGiven() {
21+
assertLineMarker(
22+
myFixture.configureByText(
23+
PhpFileType.INSTANCE,
24+
"<?php\n" +
25+
"\n" +
26+
"use Symfony\\Component\\Form\\AbstractType;\n" +
27+
"use Symfony\\Component\\OptionsResolver\\OptionsResolver;\n" +
28+
"\n" +
29+
"class Form extends AbstractType\n" +
30+
"{\n" +
31+
" public function configureOptions(OptionsResolver $resolver): void\n" +
32+
" {\n" +
33+
" $resolver->setDefaults([\n" +
34+
" 'data_class' => \\Form\\DataClass\\Model::class,\n" +
35+
" ]);\n" +
36+
" }\n" +
37+
"}"
38+
),
39+
new LineMarker.ToolTipEqualsAssert("Navigate to data class")
40+
);
41+
42+
}
43+
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/form/fixtures/classes.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public function create();
3030
}
3131

3232
interface FormTypeExtensionInterface {}
33+
34+
abstract class AbstractType implements FormTypeInterface
35+
{
36+
}
3337
}
3438

3539

0 commit comments

Comments
 (0)