Skip to content

Commit 5001220

Browse files
committed
fix possible slow index on large files #261
1 parent 00400d4 commit 5001220

File tree

2 files changed

+85
-38
lines changed

2 files changed

+85
-38
lines changed

src/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/AnnotationRoutesStubIndex.java

+84-37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.intellij.util.io.DataExternalizer;
1010
import com.intellij.util.io.EnumeratorStringDescriptor;
1111
import com.intellij.util.io.KeyDescriptor;
12+
import com.jetbrains.php.lang.documentation.phpdoc.PhpDocUtil;
1213
import com.jetbrains.php.lang.documentation.phpdoc.parser.PhpDocElementTypes;
1314
import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag;
1415
import com.jetbrains.php.lang.psi.PhpFile;
@@ -21,9 +22,7 @@
2122
import org.jetbrains.annotations.NotNull;
2223
import org.jetbrains.annotations.Nullable;
2324

24-
import java.util.Collection;
25-
import java.util.HashMap;
26-
import java.util.Map;
25+
import java.util.*;
2726
import java.util.regex.Matcher;
2827
import java.util.regex.Pattern;
2928

@@ -60,22 +59,7 @@ public Map<String, Void> map(FileContent inputData) {
6059
return map;
6160
}
6261

63-
Collection<PhpDocTag> phpDocTagList = PsiTreeUtil.findChildrenOfType(psiFile, PhpDocTag.class);
64-
for(PhpDocTag phpDocTag: phpDocTagList) {
65-
66-
String annotationFqnName = AnnotationRoutesStubIndex.getClassNameReference(phpDocTag);
67-
if("\\Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Route".equals(annotationFqnName)) {
68-
PsiElement phpDocAttributeList = PsiElementUtils.getChildrenOfType(phpDocTag, PlatformPatterns.psiElement(PhpDocElementTypes.phpDocAttributeList));
69-
if(phpDocAttributeList != null) {
70-
// @TODO: use pattern
71-
Matcher matcher = Pattern.compile("name\\s*=\\s*\"(\\w+)\"").matcher(phpDocAttributeList.getText());
72-
if (matcher.find()) {
73-
map.put(matcher.group(1), null);
74-
}
75-
}
76-
}
77-
78-
}
62+
psiFile.accept(new MyPsiRecursiveElementWalkingVisitor(map));
7963

8064
return map;
8165
}
@@ -107,27 +91,11 @@ public int getVersion() {
10791
return 8;
10892
}
10993

110-
@Nullable
111-
public static String getClassNameReference(PhpDocTag phpDocTag) {
112-
113-
// only usable on eap7 because of "@ORM\OneToMany()" bug before
114-
String name = phpDocTag.getName();
115-
if(StringUtils.isBlank(name)) {
116-
return null;
117-
}
118-
119-
String annotationName = name.substring(1);
120-
121-
// @TODO: remove this
122-
// phpstorm6 fallback;
123-
String tagText = phpDocTag.getText();
124-
if(tagText.contains("(")) {
125-
annotationName = tagText.substring(1, tagText.indexOf("("));
126-
}
94+
public static Map<String, String> getFileUseImports(PsiFile psiFile) {
12795

12896
// search for use alias in local file
12997
final Map<String, String> useImports = new HashMap<String, String>();
130-
phpDocTag.getContainingFile().acceptChildren(new PsiRecursiveElementWalkingVisitor() {
98+
psiFile.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
13199
@Override
132100
public void visitElement(PsiElement element) {
133101
if(element instanceof PhpUse) {
@@ -148,6 +116,30 @@ private void visitUse(PhpUse phpUse) {
148116

149117
});
150118

119+
return useImports;
120+
}
121+
122+
@Nullable
123+
public static String getClassNameReference(PhpDocTag phpDocTag) {
124+
return getClassNameReference(phpDocTag, getFileUseImports(phpDocTag.getContainingFile()));
125+
}
126+
127+
@Nullable
128+
public static String getClassNameReference(PhpDocTag phpDocTag, Map<String, String> useImports) {
129+
130+
if(useImports.size() == 0) {
131+
return null;
132+
}
133+
134+
String annotationName = phpDocTag.getName();
135+
if(StringUtils.isBlank(annotationName)) {
136+
return null;
137+
}
138+
139+
if(annotationName.startsWith("@")) {
140+
annotationName = annotationName.substring(1);
141+
}
142+
151143
String className = annotationName;
152144
String subNamespaceName = "";
153145
if(className.contains("\\")) {
@@ -169,6 +161,61 @@ private void visitUse(PhpUse phpUse) {
169161

170162
}
171163

164+
private static class MyPsiRecursiveElementWalkingVisitor extends PsiRecursiveElementWalkingVisitor {
165+
166+
private final Map<String, Void> map;
167+
private Map<String, String> fileImports;
168+
private Set<String> blacklistedTags;
169+
170+
public MyPsiRecursiveElementWalkingVisitor(Map<String, Void> map) {
171+
this.map = map;
172+
}
173+
174+
@Override
175+
public void visitElement(PsiElement element) {
176+
if ((element instanceof PhpDocTag)) {
177+
visitPhpDocTag((PhpDocTag) element);
178+
}
179+
super.visitElement(element);
180+
}
181+
182+
public void visitPhpDocTag(PhpDocTag phpDocTag) {
183+
184+
// init blacklist
185+
if(blacklistedTags == null) {
186+
blacklistedTags = new HashSet<String>();
187+
blacklistedTags.addAll(Arrays.asList(PhpDocUtil.ALL_TAGS));
188+
blacklistedTags.add("@inheritDoc");
189+
}
190+
191+
// "@var" and user non related tags dont need an action
192+
if(blacklistedTags.contains(phpDocTag.getName())) {
193+
return;
194+
}
195+
196+
// init file imports
197+
if(this.fileImports == null) {
198+
this.fileImports = getFileUseImports(phpDocTag.getContainingFile());
199+
}
200+
201+
if(this.fileImports.size() == 0) {
202+
return;
203+
}
204+
205+
String annotationFqnName = AnnotationRoutesStubIndex.getClassNameReference(phpDocTag, this.fileImports);
206+
if("\\Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Route".equals(annotationFqnName)) {
207+
PsiElement phpDocAttributeList = PsiElementUtils.getChildrenOfType(phpDocTag, PlatformPatterns.psiElement(PhpDocElementTypes.phpDocAttributeList));
208+
if(phpDocAttributeList != null) {
209+
// @TODO: use pattern
210+
Matcher matcher = Pattern.compile("name\\s*=\\s*\"(\\w+)\"").matcher(phpDocAttributeList.getText());
211+
if (matcher.find()) {
212+
map.put(matcher.group(1), null);
213+
}
214+
}
215+
}
216+
}
217+
218+
}
172219
}
173220

174221

src/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/YamlRoutesStubIndex.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public static boolean isValidForIndex(FileContent inputData, PsiFile psiFile) {
112112

113113
// is Test file in path name
114114
String relativePath = VfsUtil.getRelativePath(inputData.getFile(), psiFile.getProject().getBaseDir(), '/');
115-
if(relativePath == null || relativePath.contains("Test")) {
115+
if(relativePath == null || relativePath.contains("Test") || relativePath.contains("Fixtures")) {
116116
return false;
117117
}
118118

0 commit comments

Comments
 (0)