From aef5aef05f28852f00e18c42e32126ce729392a8 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Wed, 14 Dec 2011 17:46:41 +0100 Subject: [PATCH] new dependencies collection method (fixed serious threading issues) --- .../lang/xpath/psi/impl/ResolveUtil.java | 25 ++++-- .../xslt/context/Xslt2ContextProvider.java | 15 ++-- .../xpath/xslt/impl/XsltIncludeIndex.java | 76 +++++++++++-------- .../xpath/xslt/util/IncludeAwareMatcher.java | 23 ++---- 4 files changed, 77 insertions(+), 62 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/ResolveUtil.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/ResolveUtil.java index 4e69d9e00d0f..4b08417a9097 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/ResolveUtil.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/ResolveUtil.java @@ -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> DEPENDENCIES = Key.create("XSLT_DEPENDENCIES"); - @SuppressWarnings({"unchecked"}) + @SuppressWarnings({"unchecked"}) private final THashSet myHistory = new THashSet(TObjectHashingStrategy.IDENTITY); private ResolveUtil() { } + @Nullable + public static Collection getDependencies(XmlFile element) { + final CommonProcessors.CollectUniquesProcessor processor = new CommonProcessors.CollectUniquesProcessor() { + @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; diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/Xslt2ContextProvider.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/Xslt2ContextProvider.java index 054adb037e8a..67a7d3a0018e 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/Xslt2ContextProvider.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/Xslt2ContextProvider.java @@ -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 data = param.getUserData(ResolveUtil.DEPENDENCIES); - if (data == null) { - data = new SmartList(param); + final Collection 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); } } } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java index d503c7d38428..b15d485771ea 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java @@ -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 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() { - 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 processor) { + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) { return true; } + final Project project = file.getProject(); -} \ No newline at end of file + final VirtualFile[] files = FileIncludeManager.getManager(project).getIncludedFiles(virtualFile, true); + return _process(files, project, processor); + } + + public static boolean processBackwardDependencies(@NotNull XmlFile file, Processor 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 processor) { + final PsiManager psiManager = PsiManager.getInstance(project); + final PsiFile[] psiFiles = ContainerUtil.map2Array(files, PsiFile.class, new NullableFunction() { + 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; + } +} diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/util/IncludeAwareMatcher.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/util/IncludeAwareMatcher.java index e29e6e4004f7..cf5874eaf60c 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/util/IncludeAwareMatcher.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/util/IncludeAwareMatcher.java @@ -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 data = myDocument.getContainingFile().getUserData(ResolveUtil.DEPENDENCIES); - if (data == null) { - myDocument.getContainingFile().putUserData(ResolveUtil.DEPENDENCIES, new SmartList(file)); - } else if (!data.contains(file)) { - data.add(file); - } - return Result.create(changeDocument(((XmlFile)file).getDocument())); } }