Skip to content

Commit 76fbc08

Browse files
committed
fix exception Accessing indexes from PhpTypeProvider2 while building indexes violates contract Haehnchen#670
1 parent ce16b11 commit 76fbc08

File tree

1 file changed

+49
-65
lines changed

1 file changed

+49
-65
lines changed

src/fr/adrienbrault/idea/symfony2plugin/doctrine/metadata/util/DoctrineMetadataUtil.java

Lines changed: 49 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.intellij.codeInsight.lookup.LookupElement;
44
import com.intellij.lang.xml.XMLLanguage;
55
import com.intellij.openapi.project.Project;
6-
import com.intellij.openapi.util.Condition;
76
import com.intellij.openapi.util.Key;
87
import com.intellij.openapi.util.Pair;
98
import com.intellij.openapi.vfs.VirtualFile;
@@ -13,7 +12,6 @@
1312
import com.intellij.psi.search.GlobalSearchScope;
1413
import com.intellij.psi.util.*;
1514
import com.intellij.psi.xml.XmlTag;
16-
import com.intellij.util.Processor;
1715
import com.intellij.util.indexing.FileBasedIndex;
1816
import com.jetbrains.php.PhpIndex;
1917
import com.jetbrains.php.lang.psi.elements.PhpClass;
@@ -25,9 +23,7 @@
2523
import fr.adrienbrault.idea.symfony2plugin.stubs.cache.FileIndexCaches;
2624
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.DoctrineMetadataFileStubIndex;
2725
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
28-
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
2926
import org.apache.commons.lang.StringUtils;
30-
import org.apache.xmlbeans.XmlLanguage;
3127
import org.jetbrains.annotations.NotNull;
3228
import org.jetbrains.annotations.Nullable;
3329
import org.jetbrains.yaml.psi.*;
@@ -41,7 +37,7 @@
4137
*/
4238
public class DoctrineMetadataUtil {
4339

44-
private static final Key<CachedValue<Set<String>>> CLASS_KEYS = new Key<CachedValue<Set<String>>>("CLASS_KEYS");
40+
private static final Key<CachedValue<Set<String>>> CLASS_KEYS = new Key<>("CLASS_KEYS");
4541

4642
private static DoctrineMappingDriverInterface[] MAPPING_DRIVERS = new DoctrineMappingDriverInterface[] {
4743
new DoctrineXmlMappingDriver(),
@@ -51,7 +47,7 @@ public class DoctrineMetadataUtil {
5147

5248
@NotNull
5349
public static Collection<LookupElement> getObjectRepositoryLookupElements(@NotNull Project project) {
54-
return new ArrayList<LookupElement>(DoctrineRepositoryLookupElement.create(PhpIndex.getInstance(project).getAllSubclasses("\\Doctrine\\Common\\Persistence\\ObjectRepository")));
50+
return new ArrayList<>(DoctrineRepositoryLookupElement.create(PhpIndex.getInstance(project).getAllSubclasses("\\Doctrine\\Common\\Persistence\\ObjectRepository")));
5551
}
5652

5753
/**
@@ -60,90 +56,81 @@ public static Collection<LookupElement> getObjectRepositoryLookupElements(@NotNu
6056
@Nullable
6157
public static PhpClass getClassRepository(final @NotNull Project project, final @NotNull String className) {
6258

63-
final PhpClass[] phpClass = {null};
6459
for (VirtualFile virtualFile : FileBasedIndex.getInstance().getContainingFiles(DoctrineMetadataFileStubIndex.KEY, className, GlobalSearchScope.allScope(project))) {
6560

66-
FileBasedIndex.getInstance().processValues(DoctrineMetadataFileStubIndex.KEY, className, virtualFile, new FileBasedIndex.ValueProcessor<DoctrineModelInterface>() {
67-
@Override
68-
public boolean process(VirtualFile virtualFile, DoctrineModelInterface model) {
69-
if (model == null || model.getRepositoryClass() == null) {
70-
return true;
71-
}
61+
final String[] phpClass = {null};
7262

73-
phpClass[0] = PhpElementsUtil.getClassInsideNamespaceScope(project, className, model.getRepositoryClass());
63+
FileBasedIndex.getInstance().processValues(DoctrineMetadataFileStubIndex.KEY, className, virtualFile, (virtualFile1, model) -> {
64+
if (phpClass[0] != null || model == null || model.getRepositoryClass() == null) {
7465
return true;
7566
}
67+
68+
// piping value out of this index thread
69+
phpClass[0] = model.getRepositoryClass();
70+
71+
return true;
7672
}, GlobalSearchScope.allScope(project));
7773

7874
if(phpClass[0] != null) {
79-
return phpClass[0];
75+
return PhpElementsUtil.getClassInsideNamespaceScope(project, className, phpClass[0]);
8076
}
8177
}
8278

83-
return phpClass[0];
79+
return null;
8480
}
8581

8682
@NotNull
8783
public static Collection<VirtualFile> findMetadataFiles(@NotNull Project project, @NotNull String className) {
8884

89-
final Collection<VirtualFile> virtualFiles = new ArrayList<VirtualFile>();
85+
final Collection<VirtualFile> virtualFiles = new ArrayList<>();
9086

91-
FileBasedIndex.getInstance().getFilesWithKey(DoctrineMetadataFileStubIndex.KEY, new HashSet<String>(Collections.singletonList(className)), new Processor<VirtualFile>() {
92-
@Override
93-
public boolean process(VirtualFile virtualFile) {
94-
virtualFiles.add(virtualFile);
95-
return true;
96-
}
87+
FileBasedIndex.getInstance().getFilesWithKey(DoctrineMetadataFileStubIndex.KEY, new HashSet<>(Collections.singletonList(className)), virtualFile -> {
88+
virtualFiles.add(virtualFile);
89+
return true;
9790
}, GlobalSearchScope.allScope(project));
9891

9992
return virtualFiles;
10093
}
10194
@NotNull
10295
public static Collection<VirtualFile> findMetadataForRepositoryClass(@NotNull PhpClass phpClass) {
103-
String presentableFQN = phpClass.getPresentableFQN();
104-
if(presentableFQN == null) {
105-
return Collections.emptyList();
106-
}
96+
return findMetadataForRepositoryClass(
97+
phpClass.getProject(),
98+
StringUtils.stripStart(phpClass.getPresentableFQN(), "\\")
99+
);
100+
}
107101

108-
if(presentableFQN.startsWith("\\")) {
109-
presentableFQN = presentableFQN.substring(1);
110-
}
102+
private static final Key<CachedValue<Map<String, Collection<String>>>> DOCTRINE_REPOSITORY_CACHE;
111103

112-
return findMetadataForRepositoryClass(phpClass.getProject(), presentableFQN);
104+
static {
105+
DOCTRINE_REPOSITORY_CACHE = new Key<>("DOCTRINE_REPOSITORY_CACHE");
113106
}
114107

115-
private static final Key<CachedValue<Map<String, Collection<String>>>> DOCTRINE_REPOSITORY_CACHE = new Key<CachedValue<Map<String, Collection<String>>>>("DOCTRINE_REPOSITORY_CACHE");
116-
117108
@NotNull
118109
public static Collection<VirtualFile> findMetadataForRepositoryClass(final @NotNull Project project, @NotNull String repositoryClass) {
119110

120111
CachedValue<Map<String, Collection<String>>> cache = project.getUserData(DOCTRINE_REPOSITORY_CACHE);
121112
if(cache == null) {
122-
cache = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Map<String, Collection<String>>>() {
123-
@Nullable
124-
@Override
125-
public Result<Map<String, Collection<String>>> compute() {
126-
Map<String, Collection<String>> repositoryMap = new HashMap<String, Collection<String>>();
127-
for (String key : FileIndexCaches.getIndexKeysCache(project, CLASS_KEYS, DoctrineMetadataFileStubIndex.KEY)) {
128-
for (DoctrineModelInterface repositoryDefinition : FileBasedIndex.getInstance().getValues(DoctrineMetadataFileStubIndex.KEY, key, GlobalSearchScope.allScope(project))) {
129-
if(StringUtils.isBlank(repositoryDefinition.getRepositoryClass())) {
130-
continue;
131-
}
132-
133-
PhpClass phpClass = PhpElementsUtil.getClassInsideNamespaceScope(project, key, repositoryDefinition.getRepositoryClass());
134-
if(phpClass != null && phpClass.getPresentableFQN() != null) {
135-
String presentableFQN = phpClass.getPresentableFQN();
136-
if(!repositoryMap.containsKey(presentableFQN)) {
137-
repositoryMap.put(presentableFQN, new HashSet<String>());
138-
}
113+
cache = CachedValuesManager.getManager(project).createCachedValue(() -> {
114+
Map<String, Collection<String>> repositoryMap = new HashMap<>();
115+
for (String key : FileIndexCaches.getIndexKeysCache(project, CLASS_KEYS, DoctrineMetadataFileStubIndex.KEY)) {
116+
for (DoctrineModelInterface repositoryDefinition : FileBasedIndex.getInstance().getValues(DoctrineMetadataFileStubIndex.KEY, key, GlobalSearchScope.allScope(project))) {
117+
if(StringUtils.isBlank(repositoryDefinition.getRepositoryClass())) {
118+
continue;
119+
}
139120

140-
repositoryMap.get(presentableFQN).add(key);
121+
PhpClass phpClass = PhpElementsUtil.getClassInsideNamespaceScope(project, key, repositoryDefinition.getRepositoryClass());
122+
if(phpClass != null) {
123+
String presentableFQN = phpClass.getPresentableFQN();
124+
if(!repositoryMap.containsKey(presentableFQN)) {
125+
repositoryMap.put(presentableFQN, new HashSet<>());
141126
}
127+
128+
repositoryMap.get(presentableFQN).add(key);
142129
}
143130
}
144-
145-
return Result.create(repositoryMap, PsiModificationTracker.MODIFICATION_COUNT);
146131
}
132+
133+
return CachedValueProvider.Result.create(repositoryMap, PsiModificationTracker.MODIFICATION_COUNT);
147134
}, false);
148135

149136
project.putUserData(DOCTRINE_REPOSITORY_CACHE, cache);
@@ -190,7 +177,7 @@ public static Collection<Pair<String, PsiElement>> getTables(@NotNull Project pr
190177
}
191178

192179
// @TODO: add target
193-
pair.add(new Pair<String, PsiElement>(table, psiFile));
180+
pair.add(new Pair<>(table, psiFile));
194181
}
195182
}
196183
}
@@ -251,7 +238,7 @@ public static DoctrineMetadataModel getModelFields(@NotNull Project project, @No
251238
@NotNull
252239
public static Collection<PhpClass> getModels(@NotNull Project project) {
253240

254-
Collection<PhpClass> phpClasses = new ArrayList<PhpClass>();
241+
Collection<PhpClass> phpClasses = new ArrayList<>();
255242
for (String key : FileIndexCaches.getIndexKeysCache(project, CLASS_KEYS, DoctrineMetadataFileStubIndex.KEY)) {
256243
PhpClass classInterface = PhpElementsUtil.getClassInterface(project, key);
257244
if(classInterface != null) {
@@ -282,16 +269,13 @@ public static DoctrineManagerEnum findManagerByScope(@NotNull PsiElement psiElem
282269
public static String findModelNameInScope(@NotNull PsiElement psiElement) {
283270

284271
if(psiElement.getLanguage().equals(XMLLanguage.INSTANCE)) {
285-
PsiElement firstParent = PsiTreeUtil.findFirstParent(psiElement, new Condition<PsiElement>() {
286-
@Override
287-
public boolean value(PsiElement psiElement) {
288-
if (!(psiElement instanceof XmlTag)) {
289-
return false;
290-
}
291-
292-
String name = ((XmlTag) psiElement).getName();
293-
return name.equals("entity") || name.equals("document") || name.equals("embedded") || name.equals("embedded-document");
272+
PsiElement firstParent = PsiTreeUtil.findFirstParent(psiElement, psiElement1 -> {
273+
if (!(psiElement1 instanceof XmlTag)) {
274+
return false;
294275
}
276+
277+
String name = ((XmlTag) psiElement1).getName();
278+
return name.equals("entity") || name.equals("document") || name.equals("embedded") || name.equals("embedded-document");
295279
});
296280

297281
if(firstParent instanceof XmlTag) {
@@ -324,7 +308,7 @@ public boolean value(PsiElement psiElement) {
324308

325309
@NotNull
326310
public static Collection<PhpClass> getClassInsideScope(@NotNull PsiElement psiElement, @NotNull String originValue) {
327-
Collection<PhpClass> classesInterface = new ArrayList<PhpClass>();
311+
Collection<PhpClass> classesInterface = new ArrayList<>();
328312
String modelNameInScope = DoctrineMetadataUtil.findModelNameInScope(psiElement);
329313
if(modelNameInScope != null) {
330314
PhpClass classInsideNamespaceScope = PhpElementsUtil.getClassInsideNamespaceScope(psiElement.getProject(), modelNameInScope, originValue);

0 commit comments

Comments
 (0)