|
6 | 6 | import com.intellij.patterns.PlatformPatterns;
|
7 | 7 | import com.intellij.psi.PsiElement;
|
8 | 8 | import com.intellij.psi.util.PsiTreeUtil;
|
| 9 | +import com.intellij.util.Function; |
| 10 | +import com.intellij.util.containers.ContainerUtil; |
9 | 11 | import com.jetbrains.php.PhpIndex;
|
10 | 12 | import com.jetbrains.php.lang.psi.elements.*;
|
11 |
| -import com.jetbrains.php.phpunit.PhpUnitUtil; |
12 | 13 | import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
|
13 |
| -import fr.adrienbrault.idea.symfony2plugin.form.visitor.FormOptionLookupVisitor; |
14 | 14 | import fr.adrienbrault.idea.symfony2plugin.form.dict.*;
|
| 15 | +import fr.adrienbrault.idea.symfony2plugin.form.visitor.FormOptionLookupVisitor; |
15 | 16 | import fr.adrienbrault.idea.symfony2plugin.form.visitor.FormOptionVisitor;
|
16 | 17 | import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
|
17 | 18 | import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
|
18 |
| -import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil; |
19 | 19 | import fr.adrienbrault.idea.symfony2plugin.util.service.ServiceXmlParserFactory;
|
20 | 20 | import org.apache.commons.lang.StringUtils;
|
21 | 21 | import org.jetbrains.annotations.NotNull;
|
22 |
| -import org.jetbrains.annotations.Nullable; |
23 | 22 |
|
24 | 23 | import java.util.*;
|
25 | 24 |
|
|
28 | 27 | */
|
29 | 28 | public class FormOptionsUtil {
|
30 | 29 |
|
31 |
| - private static final String EXTENDED_TYPE_METHOD = "getExtendedType"; |
| 30 | + public static final String EXTENDED_TYPE_METHOD = "getExtendedType"; |
32 | 31 | public static final String[] FORM_OPTION_METHODS = new String[]{"setDefaultOptions", "configureOptions"};
|
33 | 32 |
|
| 33 | + /** |
| 34 | + * Find form extensions extends given form type |
| 35 | + * |
| 36 | + * @param formTypeNames Fqn class "Foo\Foo", "\Foo\Foo" or string value "foo"; |
| 37 | + * should have all parents a FormType can have |
| 38 | + */ |
34 | 39 | @NotNull
|
35 |
| - public static List<FormClass> getExtendedTypeClasses(@NotNull Project project, @NotNull String... formTypeNames) { |
36 |
| - |
37 |
| - List<String> formTypeNamesList = Arrays.asList(formTypeNames); |
38 |
| - |
39 |
| - Set<String> stringSet = getFormTypeExtensionClassNames(project); |
| 40 | + public static Collection<FormClass> getExtendedTypeClasses(@NotNull Project project, @NotNull String... formTypeNames) { |
40 | 41 |
|
41 |
| - List<FormClass> extendedTypeClasses = new ArrayList<FormClass>(); |
42 |
| - |
43 |
| - for(String formClass: stringSet) { |
44 |
| - visitExtendedTypeMethod(formTypeNamesList, extendedTypeClasses, false, PhpElementsUtil.getClassMethod(project, formClass, EXTENDED_TYPE_METHOD)); |
45 |
| - } |
46 |
| - |
47 |
| - // use form extension interface if service is empty |
48 |
| - for(PhpClass phpClass: PhpIndex.getInstance(project).getAllSubclasses(FormUtil.FORM_EXTENSION_INTERFACE)) { |
49 |
| - if(!FormUtil.isValidFormPhpClass(phpClass)) { |
50 |
| - continue; |
| 42 | + // strip "\" |
| 43 | + List<String> formTypeNamesList = ContainerUtil.map(Arrays.asList(formTypeNames), new Function<String, String>() { |
| 44 | + @Override |
| 45 | + public String fun(String s) { |
| 46 | + return StringUtils.stripStart(s, "\\"); |
51 | 47 | }
|
| 48 | + }); |
52 | 49 |
|
53 |
| - String className = phpClass.getPresentableFQN(); |
54 |
| - if(className != null && !stringSet.contains(className)) { |
55 |
| - visitExtendedTypeMethod(formTypeNamesList, extendedTypeClasses, true, phpClass.findMethodByName(EXTENDED_TYPE_METHOD)); |
| 50 | + Collection<FormClass> extendedTypeClasses = new ArrayList<FormClass>(); |
| 51 | + for(PhpClass phpClass: getFormTypeExtensionClassNames(project)) { |
| 52 | + String formExtendedType = FormUtil.getFormExtendedType(phpClass); |
| 53 | + if(formExtendedType != null && formTypeNamesList.contains(formExtendedType)) { |
| 54 | + extendedTypeClasses.add(new FormClass(FormClassEnum.EXTENSION, phpClass, true)); |
56 | 55 | }
|
57 | 56 | }
|
58 | 57 |
|
59 | 58 | return extendedTypeClasses;
|
60 | 59 | }
|
61 | 60 |
|
62 | 61 | @NotNull
|
63 |
| - private static Set<String> getFormTypeExtensionClassNames(@NotNull Project project) { |
| 62 | + private static Set<PhpClass> getFormTypeExtensionClassNames(@NotNull Project project) { |
64 | 63 |
|
65 |
| - Set<String> stringSet = new HashSet<String>(); |
| 64 | + Set<PhpClass> phpClasses = new HashSet<PhpClass>(); |
66 | 65 |
|
| 66 | + // @TODO: should be same as interface? |
67 | 67 | for (String s : ServiceXmlParserFactory.getInstance(project, FormExtensionServiceParser.class).getFormExtensions().keySet()) {
|
68 |
| - stringSet.add(s.startsWith("\\") ? s.substring(1) : s); |
| 68 | + ContainerUtil.addIfNotNull( |
| 69 | + phpClasses, |
| 70 | + PhpElementsUtil.getClass(project, s) |
| 71 | + ); |
69 | 72 | }
|
70 | 73 |
|
71 | 74 | for(PhpClass phpClass: PhpIndex.getInstance(project).getAllSubclasses(FormUtil.FORM_EXTENSION_INTERFACE)) {
|
72 | 75 | if(!FormUtil.isValidFormPhpClass(phpClass)) {
|
73 | 76 | continue;
|
74 | 77 | }
|
75 | 78 |
|
76 |
| - String s = phpClass.getPresentableFQN(); |
77 |
| - if(s != null) { |
78 |
| - stringSet.add(s.startsWith("\\") ? s.substring(1) : s); |
79 |
| - } |
80 |
| - } |
81 |
| - |
82 |
| - return stringSet; |
83 |
| - } |
84 |
| - |
85 |
| - private static void visitExtendedTypeMethod(List<String> formTypeNamesList, List<FormClass> extendedTypeClasses, boolean isWeak, @Nullable Method method) { |
86 |
| - if(method == null) { |
87 |
| - return; |
88 |
| - } |
89 |
| - |
90 |
| - // method without class, exit we need fqn class name |
91 |
| - PhpClass containingClass = method.getContainingClass(); |
92 |
| - if(containingClass == null) { |
93 |
| - return; |
94 |
| - } |
95 |
| - |
96 |
| - PhpReturn phpReturn = PsiTreeUtil.findChildOfType(method, PhpReturn.class); |
97 |
| - if(phpReturn != null) { |
98 |
| - PhpPsiElement returnValue = phpReturn.getFirstPsiChild(); |
99 |
| - if(returnValue instanceof StringLiteralExpression && formTypeNamesList.contains(((StringLiteralExpression) returnValue).getContents())) { |
100 |
| - extendedTypeClasses.add(new FormClass(FormClassEnum.EXTENSION, containingClass, isWeak)); |
101 |
| - } |
| 79 | + phpClasses.add(phpClass); |
102 | 80 | }
|
103 | 81 |
|
| 82 | + return phpClasses; |
104 | 83 | }
|
105 | 84 |
|
106 | 85 | @NotNull
|
107 | 86 | public static Map<String, FormOption> getFormExtensionKeys(@NotNull Project project, @NotNull String... formTypeNames) {
|
108 | 87 |
|
109 |
| - List<FormClass> typeClasses = FormOptionsUtil.getExtendedTypeClasses(project, formTypeNames); |
| 88 | + Collection<FormClass> typeClasses = FormOptionsUtil.getExtendedTypeClasses(project, formTypeNames); |
110 | 89 | Map<String, FormOption> extensionClassMap = new HashMap<String, FormOption>();
|
111 | 90 |
|
112 | 91 | for(FormClass extensionClass: typeClasses) {
|
|
0 commit comments