mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new dependencies collection method (fixed serious threading issues)
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.intellij.lang.xpath.psi.impl;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
@@ -25,25 +24,41 @@ import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.intellij.lang.xpath.xslt.impl.XsltIncludeIndex;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ResolveUtil {
|
||||
public static final Key<List<PsiElement>> DEPENDENCIES = Key.create("XSLT_DEPENDENCIES");
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private final THashSet<PsiElement> myHistory = new THashSet<PsiElement>(TObjectHashingStrategy.IDENTITY);
|
||||
|
||||
private ResolveUtil() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Collection<XmlFile> getDependencies(XmlFile element) {
|
||||
final CommonProcessors.CollectUniquesProcessor<XmlFile> processor = new CommonProcessors.CollectUniquesProcessor<XmlFile>() {
|
||||
@Override
|
||||
public boolean process(XmlFile file) {
|
||||
if (!getResults().contains(file)) {
|
||||
XsltIncludeIndex.processForwardDependencies(file, this);
|
||||
}
|
||||
return super.process(file);
|
||||
}
|
||||
};
|
||||
XsltIncludeIndex.processForwardDependencies(element, processor);
|
||||
return processor.getResults();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiFile resolveFile(String name, PsiFile baseFile) {
|
||||
if (baseFile == null) return null;
|
||||
|
||||
+7
-8
@@ -18,7 +18,6 @@ package org.intellij.lang.xpath.xslt.context;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataCache;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.ParameterizedCachedValue;
|
||||
@@ -27,7 +26,6 @@ import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.apache.commons.collections.map.CompositeMap;
|
||||
import org.intellij.lang.xpath.context.ContextType;
|
||||
import org.intellij.lang.xpath.context.XPathVersion;
|
||||
@@ -45,8 +43,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Xslt2ContextProvider extends XsltContextProviderBase {
|
||||
@@ -170,14 +168,15 @@ public class Xslt2ContextProvider extends XsltContextProviderBase {
|
||||
candidates.put(Pair.create(function.getQName(), function.getParameters().length), function);
|
||||
}
|
||||
|
||||
List<PsiElement> data = param.getUserData(ResolveUtil.DEPENDENCIES);
|
||||
if (data == null) {
|
||||
data = new SmartList<PsiElement>(param);
|
||||
final Collection<XmlFile> data = ResolveUtil.getDependencies(param);
|
||||
final Object[] dependencies;
|
||||
if (data == null || data.size() == 0) {
|
||||
dependencies = new Object[]{ param };
|
||||
} else {
|
||||
data.add(param);
|
||||
param.putUserData(ResolveUtil.DEPENDENCIES, null);
|
||||
dependencies = ArrayUtil.toObjectArray(data);
|
||||
}
|
||||
return CachedValueProvider.Result.create(candidates, ArrayUtil.toObjectArray(data));
|
||||
return CachedValueProvider.Result.create(candidates, dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
-31
@@ -40,41 +40,55 @@ public class XsltIncludeIndex {
|
||||
|
||||
public static boolean isReachableFrom(XmlFile which, XmlFile from) {
|
||||
return from == which || _isReachableFrom(from.getVirtualFile(), FileIncludeManager.getManager(which.getProject()).getIncludingFiles(which.getVirtualFile(), true));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean _isReachableFrom(VirtualFile from, VirtualFile[] which) {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < which.length; i++) {
|
||||
final VirtualFile file = which[i];
|
||||
if (file == from) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean processBackwardDependencies(@NotNull XmlFile file, Processor<XmlFile> processor) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
private static boolean _isReachableFrom(VirtualFile from, VirtualFile[] which) {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < which.length; i++) {
|
||||
final VirtualFile file = which[i];
|
||||
if (file == from) {
|
||||
return true;
|
||||
}
|
||||
final Project project = file.getProject();
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final VirtualFile[] files = FileIncludeManager.getManager(project).getIncludingFiles(virtualFile, true);
|
||||
final PsiFile[] psiFiles = ContainerUtil.map2Array(files, PsiFile.class, new NullableFunction<VirtualFile, PsiFile>() {
|
||||
public PsiFile fun(VirtualFile file) {
|
||||
return psiManager.findFile(file);
|
||||
}
|
||||
});
|
||||
for (final PsiFile psiFile : psiFiles) {
|
||||
if (XsltSupport.isXsltFile(psiFile)) {
|
||||
if (!processor.process((XmlFile)psiFile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static boolean processForwardDependencies(@NotNull XmlFile file, Processor<XmlFile> processor) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
return true;
|
||||
}
|
||||
final Project project = file.getProject();
|
||||
|
||||
}
|
||||
final VirtualFile[] files = FileIncludeManager.getManager(project).getIncludedFiles(virtualFile, true);
|
||||
return _process(files, project, processor);
|
||||
}
|
||||
|
||||
public static boolean processBackwardDependencies(@NotNull XmlFile file, Processor<XmlFile> processor) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
return true;
|
||||
}
|
||||
final Project project = file.getProject();
|
||||
|
||||
final VirtualFile[] files = FileIncludeManager.getManager(project).getIncludingFiles(virtualFile, true);
|
||||
return _process(files, project, processor);
|
||||
}
|
||||
|
||||
private static boolean _process(VirtualFile[] files, Project project, Processor<XmlFile> processor) {
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
final PsiFile[] psiFiles = ContainerUtil.map2Array(files, PsiFile.class, new NullableFunction<VirtualFile, PsiFile>() {
|
||||
public PsiFile fun(VirtualFile file) {
|
||||
return psiManager.findFile(file);
|
||||
}
|
||||
});
|
||||
for (final PsiFile psiFile : psiFiles) {
|
||||
if (XsltSupport.isXsltFile(psiFile)) {
|
||||
if (!processor.process((XmlFile)psiFile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-18
@@ -15,20 +15,15 @@
|
||||
*/
|
||||
package org.intellij.lang.xpath.xslt.util;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import org.intellij.lang.xpath.psi.impl.ResolveUtil;
|
||||
import org.intellij.lang.xpath.xslt.XsltSupport;
|
||||
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class IncludeAwareMatcher extends BaseMatcher {
|
||||
protected final XmlDocument myDocument;
|
||||
|
||||
@@ -53,14 +48,6 @@ public abstract class IncludeAwareMatcher extends BaseMatcher {
|
||||
|
||||
final PsiFile file = ResolveUtil.resolveFile(href, f);
|
||||
if (file instanceof XmlFile) {
|
||||
|
||||
final List<PsiElement> data = myDocument.getContainingFile().getUserData(ResolveUtil.DEPENDENCIES);
|
||||
if (data == null) {
|
||||
myDocument.getContainingFile().putUserData(ResolveUtil.DEPENDENCIES, new SmartList<PsiElement>(file));
|
||||
} else if (!data.contains(file)) {
|
||||
data.add(file);
|
||||
}
|
||||
|
||||
return Result.create(changeDocument(((XmlFile)file).getDocument()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user