Skip to content

Commit 3ff1023

Browse files
committed
Symfony 4.2: Support improved form type extensions #1246
1 parent 09b0f84 commit 3ff1023

File tree

3 files changed

+85
-18
lines changed

3 files changed

+85
-18
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/form/util/FormOptionsUtil.java

-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
* @author Daniel Espendiller <daniel@espendiller.net>
2828
*/
2929
public class FormOptionsUtil {
30-
31-
public static final String EXTENDED_TYPE_METHOD = "getExtendedType";
32-
3330
/**
3431
* Symfony2 / 3 Form setting options per FormType via method
3532
*/

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

+56-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.intellij.psi.xml.XmlTag;
1313
import com.jetbrains.php.PhpIndex;
1414
import com.jetbrains.php.lang.parser.PhpElementTypes;
15+
import com.jetbrains.php.lang.psi.PhpPsiUtil;
1516
import com.jetbrains.php.lang.psi.elements.*;
1617
import com.jetbrains.php.lang.psi.elements.impl.PhpTypedElementImpl;
1718
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
@@ -537,30 +538,70 @@ public static String getFormNameOfPhpClass(@NotNull PhpClass phpClass) {
537538
}
538539

539540
/**
540-
* Get getExtendedType as string
541+
* Get getExtendedType and getExtendedTypes (Symfony >= 4.2) as string
541542
*
542-
* 'Foo::class' and string 'foo' supported
543+
* "return Foo::class;"
544+
* "return 'foobar';"
545+
* "return [Foo::class, FooBar::class];"
546+
* "return true === true ? FileType::class : Form:class;"
547+
* "yield Foo::class;"
543548
*/
544549
@NotNull
545550
public static Collection<String> getFormExtendedType(@NotNull PhpClass phpClass) {
546-
Method getParent = phpClass.findMethodByName(FormOptionsUtil.EXTENDED_TYPE_METHOD);
547-
if(getParent == null) {
548-
return Collections.emptySet();
549-
}
550-
551551
Collection<String> types = new HashSet<>();
552552

553-
for (PhpReturn phpReturn : PsiTreeUtil.collectElementsOfType(getParent, PhpReturn.class)) {
554-
PhpPsiElement firstPsiChild = phpReturn.getFirstPsiChild();
553+
// public function getExtendedType() { return FileType::class; }
554+
// public function getExtendedType() { return true === true ? FileType::class : Form:class; }
555+
Method extendedType = phpClass.findMethodByName("getExtendedType");
556+
if(extendedType != null) {
557+
for (PhpReturn phpReturn : PsiTreeUtil.collectElementsOfType(extendedType, PhpReturn.class)) {
558+
PhpPsiElement firstPsiChild = phpReturn.getFirstPsiChild();
555559

556-
// true ? 'foo' : 'foo'
557-
if(firstPsiChild instanceof TernaryExpression) {
558-
types.addAll(PhpElementsUtil.getTernaryExpressionConditionStrings((TernaryExpression) firstPsiChild));
560+
// true ? 'foo' : 'foo'
561+
if(firstPsiChild instanceof TernaryExpression) {
562+
types.addAll(PhpElementsUtil.getTernaryExpressionConditionStrings((TernaryExpression) firstPsiChild));
563+
}
564+
565+
String stringValue = PhpElementsUtil.getStringValue(firstPsiChild);
566+
if(stringValue != null) {
567+
types.add(stringValue);
568+
}
569+
}
570+
}
571+
572+
// Symfony 4.2: Support improved form type extensions:
573+
// public static function getExtendedTypes(): iterable:
574+
// https://symfony.com/blog/new-in-symfony-4-2-improved-form-type-extensions
575+
Method extendedTypes = phpClass.findMethodByName("getExtendedTypes");
576+
if (extendedTypes != null) {
577+
// [Foo::class, FooBar::class]
578+
for (PhpReturn phpReturn : PsiTreeUtil.collectElementsOfType(extendedTypes, PhpReturn.class)) {
579+
PhpPsiElement arrayCreationExpression = phpReturn.getFirstPsiChild();
580+
if (arrayCreationExpression instanceof ArrayCreationExpression) {
581+
Collection<PsiElement> arrayValues = PhpPsiUtil.getChildren(arrayCreationExpression, psiElement ->
582+
psiElement.getNode().getElementType() == PhpElementTypes.ARRAY_VALUE
583+
);
584+
585+
for (PsiElement child : arrayValues) {
586+
String stringValue = PhpElementsUtil.getStringValue(child.getFirstChild());
587+
if (stringValue != null) {
588+
types.add(stringValue);
589+
}
590+
}
591+
}
559592
}
560593

561-
String stringValue = PhpElementsUtil.getStringValue(firstPsiChild);
562-
if(stringValue != null) {
563-
types.add(stringValue);
594+
// yield Foo::class
595+
for (PhpYield phpReturn : PsiTreeUtil.collectElementsOfType(extendedTypes, PhpYield.class)) {
596+
PsiElement yieldArgument = phpReturn.getArgument();
597+
if (yieldArgument == null) {
598+
continue;
599+
}
600+
601+
String stringValue = PhpElementsUtil.getStringValue(yieldArgument);
602+
if (stringValue != null) {
603+
types.add(stringValue);
604+
}
564605
}
565606
}
566607

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/form/util/FormUtilTest.java

+29
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,33 @@ public void testGetFormExtendedType() {
260260

261261
assertContainsElements(FormUtil.getFormExtendedType(phpClass), "Bar\\Foo");
262262
}
263+
264+
public void testGetFormExtendedTypesAsArray() {
265+
PhpClass phpClass = PhpPsiElementFactory.createFromText(getProject(), PhpClass.class, "<?php\n" +
266+
"class Foobar\n" +
267+
"{\n" +
268+
" public function getExtendedTypes()\n" +
269+
" {\n" +
270+
" return [Foobar::class, 'test'];\n" +
271+
" }\n" +
272+
"}\n"
273+
);
274+
275+
assertContainsElements(FormUtil.getFormExtendedType(phpClass), "Foobar", "test");
276+
}
277+
278+
public void testGetFormExtendedTypesAsYield() {
279+
PhpClass phpClass = PhpPsiElementFactory.createFromText(getProject(), PhpClass.class, "<?php\n" +
280+
"class Foobar\n" +
281+
"{\n" +
282+
" public function getExtendedTypes()\n" +
283+
" {\n" +
284+
" yield Foobar::class;\n" +
285+
" yield 'test';\n'" +
286+
" }\n" +
287+
"}\n"
288+
);
289+
290+
assertContainsElements(FormUtil.getFormExtendedType(phpClass), "Foobar", "test");
291+
}
263292
}

0 commit comments

Comments
 (0)