diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index 0807bea915c8..73e475e22242 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -44,12 +44,12 @@ class RootIndex { private final Set myProjectExcludedRoots = ContainerUtil.newHashSet(); private final Set myLibraryExcludedRoots = ContainerUtil.newHashSet(); - private final Map myRoots = ContainerUtil.newHashMap(); + private final Map myRoots = ContainerUtil.newTroveMap(); private final Map> myPackagePrefixRoots = ContainerUtil.newHashMap(); private final Map> myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap(); private final Map> myDirectoriesByPackageNameCacheWithLibSrc = ContainerUtil.newConcurrentMap(); - private final Map myIgnoredCache = ContainerUtil.newConcurrentMap(); + private final Map myInfoCache = ContainerUtil.newConcurrentMap(); private final List> myRootTypes = ContainerUtil.newArrayList(); private final TObjectIntHashMap> myRootTypeId = new TObjectIntHashMap>(); @@ -320,15 +320,19 @@ class RootIndex { if (++count > 1000) { throw new IllegalStateException("Possible loop in tree, started at " + dir.getName()); } - final DirectoryInfo info = myRoots.get(root); + DirectoryInfo info = myInfoCache.get(root); if (info != null) { + return info == DirectoryInfo.EMPTY ? null : info; + } + + info = myRoots.get(root); + if (info != null) { + myInfoCache.put(dir, info); return info; } - Boolean ignored = myIgnoredCache.get(root); - if (ignored == null) { - myIgnoredCache.put(root, ignored = isAnyExcludeRoot(root) || FileTypeManager.getInstance().isFileIgnored(root)); - } - if (ignored.booleanValue()) { + + if (isAnyExcludeRoot(root) || FileTypeManager.getInstance().isFileIgnored(root)) { + myInfoCache.put(dir, DirectoryInfo.EMPTY); return null; } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java index 25b4192261fe..cbabea19466e 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -36,6 +36,7 @@ import java.util.Comparator; import java.util.List; public final class DirectoryInfo { + static final DirectoryInfo EMPTY = createNew(); public static final int MAX_ROOT_TYPE_ID = (1 << (Byte.SIZE - 2)) - 1; private final Module module; // module to which content it belongs or null private final VirtualFile libraryClassRoot; // class root in library diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java index f72dcbf4ab03..d1d85ccecbdf 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java @@ -75,7 +75,7 @@ public abstract class DomInvocationHandler rawType = getRawType(); - myInvocationCache = manager.getApplicationComponent().getInvocationCache(rawType); - Class implementation = manager.getApplicationComponent().getImplementation(rawType); - final boolean isInterface = ReflectionCache.isInterface(rawType); - if (implementation == null && !isInterface) { - implementation = (Class)rawType; - } - myProxy = AdvancedProxy.createProxy(this, implementation, isInterface ? new Class[]{rawType} : ArrayUtil.EMPTY_CLASS_ARRAY); + myInvocationCache = manager.getApplicationComponent().getInvocationCache(getRawType()); refreshGenericInfo(dynamic); if (stub != null) { stub.setHandler(this); @@ -206,7 +199,7 @@ public abstract class DomInvocationHandler rawType = getRawType(); + Class implementation = myManager.getApplicationComponent().getImplementation(rawType); + final boolean isInterface = ReflectionCache.isInterface(rawType); + if (implementation == null && !isInterface) { + //noinspection unchecked + implementation = (Class)rawType; + } + myProxy = proxy = AdvancedProxy.createProxy(this, implementation, isInterface ? new Class[]{rawType} : ArrayUtil.EMPTY_CLASS_ARRAY); + } + return proxy; } @NotNull @@ -692,7 +696,7 @@ public abstract class DomInvocationHandler getRawType() { + public final Class getRawType() { return ReflectionUtil.getRawType(myType); } diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java index ffcc033b4aed..fa95b8a4ccb7 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java @@ -155,20 +155,22 @@ public class DynamicGenericInfo extends DomGenericInfoEx { @Nullable private DomExtensionsRegistrarImpl runDomExtenders() { DomExtensionsRegistrarImpl registrar = null; - final DomElement domElement = myInvocationHandler.getProxy(); final Project project = myInvocationHandler.getManager().getProject(); - for (final DomExtenderEP extenderEP : Extensions.getExtensions(DomExtenderEP.EP_NAME)) { - registrar = extenderEP.extend(project, domElement, registrar); + DomExtenderEP[] extenders = Extensions.getExtensions(DomExtenderEP.EP_NAME); + if (extenders.length > 0) { + for (final DomExtenderEP extenderEP : extenders) { + registrar = extenderEP.extend(project, myInvocationHandler, registrar); + } } final AbstractDomChildDescriptionImpl description = myInvocationHandler.getChildDescription(); if (description != null) { - final List extenders = description.getUserData(DomExtensionImpl.DOM_EXTENDER_KEY); - if (extenders != null) { + final List extendersFromParent = description.getUserData(DomExtensionImpl.DOM_EXTENDER_KEY); + if (extendersFromParent != null) { if (registrar == null) registrar = new DomExtensionsRegistrarImpl(); - for (final DomExtender extender : extenders) { + for (final DomExtender extender : extendersFromParent) { //noinspection unchecked - extender.registerExtensions(domElement, registrar); + extender.registerExtensions(myInvocationHandler.getProxy(), registrar); } } } diff --git a/xml/dom-impl/src/com/intellij/util/xml/reflect/DomExtenderEP.java b/xml/dom-impl/src/com/intellij/util/xml/reflect/DomExtenderEP.java index 45ee3aa8c158..b797fda0ed10 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/reflect/DomExtenderEP.java +++ b/xml/dom-impl/src/com/intellij/util/xml/reflect/DomExtenderEP.java @@ -19,7 +19,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.AbstractExtensionPointBean; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; -import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.impl.DomInvocationHandler; import com.intellij.util.xmlb.annotations.Attribute; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,7 +41,7 @@ public class DomExtenderEP extends AbstractExtensionPointBean { @Nullable - public DomExtensionsRegistrarImpl extend(@NotNull final Project project, @NotNull final DomElement element, @Nullable DomExtensionsRegistrarImpl registrar) { + public DomExtensionsRegistrarImpl extend(@NotNull final Project project, @NotNull final DomInvocationHandler handler, @Nullable DomExtensionsRegistrarImpl registrar) { if (myExtender == null) { try { myDomClass = findClass(domClassName); @@ -52,11 +52,12 @@ public class DomExtenderEP extends AbstractExtensionPointBean { return null; } } - if (myDomClass.isInstance(element)) { + if (myDomClass.isAssignableFrom(handler.getRawType())) { if (registrar == null) { registrar = new DomExtensionsRegistrarImpl(); } - myExtender.registerExtensions(element, registrar); + //noinspection unchecked + myExtender.registerExtensions(handler.getProxy(), registrar); } return registrar; } diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilder.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilder.java index 3d960e5ca2e0..f3ead60b0c5f 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilder.java +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilder.java @@ -27,9 +27,11 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.stubs.BinaryFileStubBuilder; import com.intellij.psi.stubs.Stub; import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.FileBasedIndexImpl; import com.intellij.util.indexing.FileContent; import com.intellij.util.xml.*; +import com.intellij.util.xml.impl.DomManagerImpl; import com.intellij.util.xml.stubs.FileStub; import com.intellij.xml.util.XmlUtil; @@ -67,8 +69,10 @@ public class DomStubBuilder implements BinaryFileStubBuilder { LOG.error("null root tag for " + fileElement + " for " + file); } FileStub fileStub = new FileStub(header); - DomStubBuilderVisitor visitor = new DomStubBuilderVisitor(fileStub); - visitor.visitDomElement(fileElement.getRootElement()); + XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag != null) { + new DomStubBuilderVisitor(DomManagerImpl.getDomManager(project)).visitXmlElement(rootTag, fileStub); + } return fileStub; } finally { diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java index ac112104ce0b..086e1a8817c7 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java @@ -15,63 +15,53 @@ */ package com.intellij.util.xml.stubs.builder; -import com.intellij.util.xml.Stubbed; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlTag; import com.intellij.util.io.StringRef; -import com.intellij.util.xml.DomElement; -import com.intellij.util.xml.DomElementVisitor; -import com.intellij.util.xml.DomUtil; +import com.intellij.util.xml.Stubbed; +import com.intellij.util.xml.impl.DomInvocationHandler; +import com.intellij.util.xml.impl.DomManagerImpl; import com.intellij.util.xml.reflect.AbstractDomChildrenDescription; import com.intellij.util.xml.reflect.CustomDomChildrenDescription; import com.intellij.util.xml.reflect.DomChildrenDescription; import com.intellij.util.xml.stubs.AttributeStub; import com.intellij.util.xml.stubs.ElementStub; -import com.intellij.util.xml.stubs.FileStub; - -import java.util.List; /** * @author Dmitry Avdeev * Date: 8/7/12 */ -public class DomStubBuilderVisitor implements DomElementVisitor { +class DomStubBuilderVisitor { + private final DomManagerImpl myManager; - private ElementStub myRoot; - - public DomStubBuilderVisitor(FileStub fileStub) { - myRoot = fileStub; + DomStubBuilderVisitor(DomManagerImpl manager) { + myManager = manager; } + + void visitXmlElement(XmlElement element, ElementStub parent) { + DomInvocationHandler handler = myManager.getDomHandler(element); + if (handler == null || handler.getAnnotation(Stubbed.class) == null && !handler.getChildDescription().isStubbed()) return; - @Override - public void visitDomElement(DomElement element) { - - if (element.getAnnotation(Stubbed.class) != null || - element.getChildDescription().isStubbed()) { - - XmlElement xmlElement = element.getXmlElement(); - AbstractDomChildrenDescription description = element.getChildDescription(); - String nsKey = description instanceof DomChildrenDescription ? ((DomChildrenDescription)description).getXmlName().getNamespaceKey() : ""; - if (xmlElement instanceof XmlTag) { - ElementStub old = myRoot; - myRoot = new ElementStub(myRoot, - StringRef.fromString(((XmlTag)xmlElement).getName()), - StringRef.fromNullableString(nsKey), - description instanceof CustomDomChildrenDescription); - List children = DomUtil.getDefinedChildren(element, true, true); - for (DomElement child : children) { - visitDomElement(child); - } - if (old != null) { - myRoot = old; - } + AbstractDomChildrenDescription description = handler.getChildDescription(); + String nsKey = description instanceof DomChildrenDescription ? ((DomChildrenDescription)description).getXmlName().getNamespaceKey() : ""; + if (element instanceof XmlTag) { + XmlTag tag = (XmlTag)element; + ElementStub stub = new ElementStub(parent, + StringRef.fromString(tag.getName()), + StringRef.fromNullableString(nsKey), + description instanceof CustomDomChildrenDescription); + for (final XmlTag subTag : tag.getSubTags()) { + visitXmlElement(subTag, stub); } - else if (xmlElement instanceof XmlAttribute) { - new AttributeStub(myRoot, StringRef.fromString(((XmlAttribute)xmlElement).getLocalName()), - StringRef.fromNullableString(nsKey), - ((XmlAttribute)xmlElement).getValue()); + for (XmlAttribute attribute : tag.getAttributes()) { + visitXmlElement(attribute, stub); } + } else if (element instanceof XmlAttribute) { + new AttributeStub(parent, StringRef.fromString(((XmlAttribute)element).getLocalName()), + StringRef.fromNullableString(nsKey), + ((XmlAttribute)element).getValue()); } } + }