Skip to content

Commit 02ba051

Browse files
authored
Merge pull request #2085 from Haehnchen/feature/form-data-performace
migrate form data class indexer to use control flow
2 parents cfd59f0 + f557e92 commit 02ba051

File tree

1 file changed

+77
-67
lines changed

1 file changed

+77
-67
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/FormDataClassStubIndex.java

Lines changed: 77 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
import com.intellij.psi.PsiElement;
44
import com.intellij.psi.PsiFile;
5-
import com.intellij.psi.PsiRecursiveElementVisitor;
65
import com.intellij.psi.util.PsiTreeUtil;
76
import com.intellij.util.indexing.*;
87
import com.intellij.util.io.DataExternalizer;
98
import com.intellij.util.io.EnumeratorStringDescriptor;
109
import com.intellij.util.io.KeyDescriptor;
10+
import com.jetbrains.php.codeInsight.controlFlow.PhpControlFlowUtil;
11+
import com.jetbrains.php.codeInsight.controlFlow.PhpInstructionProcessor;
12+
import com.jetbrains.php.codeInsight.controlFlow.instructions.PhpCallInstruction;
1113
import com.jetbrains.php.lang.PhpFileType;
1214
import com.jetbrains.php.lang.psi.PhpFile;
1315
import com.jetbrains.php.lang.psi.elements.*;
1416
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.StringSetDataExternalizer;
1517
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
16-
import gnu.trove.THashMap;
1718
import org.apache.commons.lang.StringUtils;
1819
import org.jetbrains.annotations.NotNull;
1920
import org.jetbrains.annotations.Nullable;
2021

22+
import java.util.HashMap;
2123
import java.util.HashSet;
2224
import java.util.Map;
2325
import java.util.Set;
@@ -45,87 +47,95 @@ public ID<String, Set<String>> getName() {
4547
@Override
4648
public DataIndexer<String, Set<String>, FileContent> getIndexer() {
4749
return inputData -> {
48-
Map<String, Set<String>> map = new THashMap<>();
50+
Map<String, Set<String>> map = new HashMap<>();
4951

5052
PsiFile psiFile = inputData.getPsiFile();
5153
if(!(psiFile instanceof PhpFile)) {
5254
return map;
5355
}
5456

55-
psiFile.accept(new PsiRecursiveElementVisitor() {
56-
@Override
57-
public void visitElement(@NotNull PsiElement element) {
58-
if (element instanceof MethodReference) {
59-
String phpClassFqn = null;
60-
61-
String name = ((MethodReference) element).getName();
62-
if ("setDefault".equals(name) && ((MethodReference) element).getType().getTypes().stream().anyMatch(s -> s.toLowerCase().contains("optionsresolver"))) {
63-
// $resolver->setDefault('data_class', XXX);
64-
65-
ParameterList parameterList = ((MethodReference) element).getParameterList();
66-
if (parameterList != null) {
67-
PsiElement parameter = parameterList.getParameter(0);
68-
if (parameter instanceof StringLiteralExpression) {
69-
String contents = ((StringLiteralExpression) parameter).getContents();
70-
if ("data_class".equals(contents)) {
71-
PsiElement parameter1 = parameterList.getParameter(1);
72-
if (parameter1 != null) {
73-
phpClassFqn = getString(parameter1);
74-
}
75-
}
57+
for (PhpNamedElement topLevelElement : ((PhpFile) psiFile).getTopLevelDefs().values()) {
58+
if (topLevelElement instanceof PhpClass clazz) {
59+
for (Method method : clazz.getOwnMethods()) {
60+
PhpControlFlowUtil.processFlow(method.getControlFlow(), new PhpInstructionProcessor() {
61+
@Override
62+
public boolean processPhpCallInstruction(PhpCallInstruction instruction) {
63+
if (instruction.getFunctionReference() instanceof MethodReference methodReference) {
64+
visitElement(methodReference, map);
7665
}
66+
return super.processPhpCallInstruction(instruction);
7767
}
78-
} else if ("setDefaults".equals(name) && ((MethodReference) element).getType().getTypes().stream().anyMatch(s -> s.toLowerCase().contains("optionsresolver"))) {
79-
// $resolver->setDefaults(['data_class' => XXX]);
80-
81-
ParameterList parameterList = ((MethodReference) element).getParameterList();
82-
if (parameterList != null) {
83-
PsiElement parameter = parameterList.getParameter(0);
84-
if (parameter instanceof ArrayCreationExpression) {
85-
PhpPsiElement dataClassPsiElement = PhpElementsUtil.getArrayValue((ArrayCreationExpression) parameter, "data_class");
86-
if (dataClassPsiElement != null) {
87-
phpClassFqn = getString(dataClassPsiElement);
88-
}
89-
}
90-
}
91-
}
92-
93-
if (phpClassFqn != null) {
94-
Method methodScope = PsiTreeUtil.getParentOfType(element, Method.class);
95-
if (methodScope != null) {
96-
PhpClass parentOfType = methodScope.getContainingClass();
97-
if (parentOfType != null) {
98-
map.putIfAbsent(phpClassFqn, new HashSet<>());
99-
map.get(phpClassFqn).add(parentOfType.getFQN());
100-
}
101-
}
102-
}
68+
});
10369
}
104-
105-
super.visitElement(element);
10670
}
71+
}
10772

108-
@Nullable
109-
private String getString(@NotNull PsiElement parameter) {
110-
if (parameter instanceof ClassConstantReference) {
111-
String classConstantPhpFqn = PhpElementsUtil.getClassConstantPhpFqn((ClassConstantReference) parameter);
112-
if (StringUtils.isNotBlank(classConstantPhpFqn)) {
113-
return "\\" + StringUtils.stripStart(classConstantPhpFqn, "\\");
114-
}
115-
} else if (parameter instanceof StringLiteralExpression) {
116-
String contents1 = ((StringLiteralExpression) parameter).getContents();
117-
if (StringUtils.isNotBlank(contents1)) {
118-
return "\\" + StringUtils.stripStart(contents1, "\\");
73+
return map;
74+
};
75+
76+
}
77+
public void visitElement(@NotNull MethodReference element, @NotNull Map<String, Set<String>> map) {
78+
String phpClassFqn = null;
79+
80+
String name = element.getName();
81+
if ("setDefault".equals(name) && element.getType().getTypes().stream().anyMatch(s -> s.toLowerCase().contains("optionsresolver"))) {
82+
// $resolver->setDefault('data_class', XXX);
83+
84+
ParameterList parameterList = element.getParameterList();
85+
if (parameterList != null) {
86+
PsiElement parameter = parameterList.getParameter(0);
87+
if (parameter instanceof StringLiteralExpression) {
88+
String contents = ((StringLiteralExpression) parameter).getContents();
89+
if ("data_class".equals(contents)) {
90+
PsiElement parameter1 = parameterList.getParameter(1);
91+
if (parameter1 != null) {
92+
phpClassFqn = getString(parameter1);
11993
}
12094
}
121-
122-
return null;
12395
}
124-
});
96+
}
97+
} else if ("setDefaults".equals(name) && element.getType().getTypes().stream().anyMatch(s -> s.toLowerCase().contains("optionsresolver"))) {
98+
// $resolver->setDefaults(['data_class' => XXX]);
99+
100+
ParameterList parameterList = ((MethodReference) element).getParameterList();
101+
if (parameterList != null) {
102+
PsiElement parameter = parameterList.getParameter(0);
103+
if (parameter instanceof ArrayCreationExpression) {
104+
PhpPsiElement dataClassPsiElement = PhpElementsUtil.getArrayValue((ArrayCreationExpression) parameter, "data_class");
105+
if (dataClassPsiElement != null) {
106+
phpClassFqn = getString(dataClassPsiElement);
107+
}
108+
}
109+
}
110+
}
111+
112+
if (phpClassFqn != null) {
113+
Method methodScope = PsiTreeUtil.getParentOfType(element, Method.class);
114+
if (methodScope != null) {
115+
PhpClass parentOfType = methodScope.getContainingClass();
116+
if (parentOfType != null) {
117+
map.putIfAbsent(phpClassFqn, new HashSet<>());
118+
map.get(phpClassFqn).add(parentOfType.getFQN());
119+
}
120+
}
121+
}
122+
}
125123

126-
return map;
127-
};
124+
@Nullable
125+
private static String getString(@NotNull PsiElement parameter) {
126+
if (parameter instanceof ClassConstantReference) {
127+
String classConstantPhpFqn = PhpElementsUtil.getClassConstantPhpFqn((ClassConstantReference) parameter);
128+
if (StringUtils.isNotBlank(classConstantPhpFqn)) {
129+
return "\\" + StringUtils.stripStart(classConstantPhpFqn, "\\");
130+
}
131+
} else if (parameter instanceof StringLiteralExpression) {
132+
String contents1 = ((StringLiteralExpression) parameter).getContents();
133+
if (StringUtils.isNotBlank(contents1)) {
134+
return "\\" + StringUtils.stripStart(contents1, "\\");
135+
}
136+
}
128137

138+
return null;
129139
}
130140

131141
@NotNull

0 commit comments

Comments
 (0)