diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java index 010162102ae6..76594d8099cb 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java @@ -20,6 +20,7 @@ import com.intellij.javaee.ExternalResourceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -547,7 +548,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator visited) { - XmlNSDescriptorImpl responsibleDescriptor = this; - if (namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) { - final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true); + protected TypeDescriptor findTypeDescriptorImpl(XmlTag rootTag, final String name, String namespace) { + return RecursionManager.createGuard("findDescriptor").doPreventingRecursion(rootTag, true, () -> { + XmlNSDescriptorImpl responsibleDescriptor = this; + if (namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) { + final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true); - if (nsDescriptor instanceof XmlNSDescriptorImpl) { - responsibleDescriptor = (XmlNSDescriptorImpl)nsDescriptor; + if (nsDescriptor instanceof XmlNSDescriptorImpl) { + responsibleDescriptor = (XmlNSDescriptorImpl)nsDescriptor; + } } - } - if (responsibleDescriptor != this) { - return responsibleDescriptor.findTypeDescriptor(XmlUtil.findLocalNameByQualifiedName(name)); - } + if (responsibleDescriptor != this) { + return responsibleDescriptor.findTypeDescriptor(XmlUtil.findLocalNameByQualifiedName(name)); + } - if (rootTag == null) return null; - if (visited != null) { - if (visited.contains(rootTag)) return null; - visited.add(rootTag); - } + if (rootTag == null) return null; - final Pair pair = Pair.create(new QNameKey(name, namespace), rootTag); + final Pair pair = Pair.create(new QNameKey(name, namespace), rootTag); + final CachedValue descriptor = myTypesMap.get(pair); + if (descriptor != null) { + TypeDescriptor value = descriptor.getValue(); + if (value == null || + (value instanceof ComplexTypeDescriptor && + ((ComplexTypeDescriptor)value).getDeclaration().isValid() + ) + ) { + return value; + } + } - final CachedValue descriptor = myTypesMap.get(pair); - if(descriptor != null) { - TypeDescriptor value = descriptor.getValue(); - if (value == null || - ( value instanceof ComplexTypeDescriptor && - ((ComplexTypeDescriptor)value).getDeclaration().isValid() - ) - ) - return value; - } - - XmlTag[] tags = rootTag.getSubTags(); - - if (visited == null) { - visited = new HashSet<>(1); - visited.add(rootTag); - } - - return doFindIn(tags, name, namespace, pair, rootTag, visited); + XmlTag[] tags = rootTag.getSubTags(); + return doFindIn(tags, name, namespace, pair, rootTag); + }); } - private TypeDescriptor doFindIn(final XmlTag[] tags, final String name, final String namespace, final Pair pair, final XmlTag rootTag, final Set visited) { + private TypeDescriptor doFindIn(final XmlTag[] tags, + final String name, + final String namespace, + final Pair pair, + final XmlTag rootTag) { for (final XmlTag tag : tags) { if (equalsToSchemaName(tag, "complexType")) { if (name == null) { @@ -664,8 +661,8 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator(complexTypeDescriptor, rTag); }, false ); @@ -711,15 +708,16 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator