faster anchor creation for dom2 declarations (IDEA-77058)

This commit is contained in:
peter
2011-11-21 15:21:11 +01:00
parent 739f59958e
commit 05b05bdeb7
7 changed files with 74 additions and 17 deletions

View File

@@ -50,8 +50,7 @@ public class ExtensionDomExtender extends DomExtender<Extensions> {
private static final PsiClassConverter CLASS_CONVERTER = new PluginPsiClassConverter();
private static final DomExtender EXTENSION_EXTENDER = new DomExtender() {
public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) {
final DomAnchor anchor = domElement.getChildDescription().getUserData(DomExtension.KEY_DECLARATION);
final ExtensionPoint extensionPoint = (ExtensionPoint)anchor.retrieveDomElement();
final ExtensionPoint extensionPoint = (ExtensionPoint)domElement.getChildDescription().getDomDeclaration();
assert extensionPoint != null;
String interfaceName = extensionPoint.getInterface().getStringValue();

View File

@@ -26,7 +26,6 @@ import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.xml.*;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
import com.intellij.util.xml.reflect.DomExtension;
import com.intellij.util.xml.reflect.DomExtensionImpl;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
@@ -135,16 +134,16 @@ public abstract class AbstractDomChildDescriptionImpl implements AbstractDomChil
@Nullable
public PsiElement getDeclaration(final Project project) {
final DomAnchor anchor = getUserData(DomExtension.KEY_DECLARATION);
if (anchor != null) {
final DomElement declaration = anchor.retrieveDomElement();
if (declaration != null) {
final DomTarget target = DomTarget.getTarget(declaration);
if (target != null) {
return PomService.convertToPsi(target);
}
return declaration.getXmlElement();
DomElement domDeclaration = getDomDeclaration();
if (domDeclaration != null) {
final DomTarget target = DomTarget.getTarget(domDeclaration);
if (target != null) {
return PomService.convertToPsi(target);
}
return domDeclaration.getXmlElement();
}
final DomAnchor anchor = getUserData(DomExtensionImpl.KEY_DOM_DECLARATION);
if (anchor != null) {
return anchor.getContainingFile();
}
final SmartPsiElementPointer<?> pointer = getUserData(DomExtensionImpl.DECLARING_ELEMENT_KEY);
@@ -157,4 +156,13 @@ public abstract class AbstractDomChildDescriptionImpl implements AbstractDomChil
return PomService.convertToPsi(project, this);
}
@Override
public DomElement getDomDeclaration() {
final DomAnchor anchor = getUserData(DomExtensionImpl.KEY_DOM_DECLARATION);
if (anchor != null) {
return anchor.retrieveDomElement();
}
return null;
}
}

View File

@@ -15,15 +15,18 @@
*/
package com.intellij.util.xml.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiAnchor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.*;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -34,6 +37,16 @@ public abstract class DomAnchorImpl<T extends DomElement> implements DomAnchor<T
private static final Logger LOG = Logger.getInstance("#com.intellij.util.xml.impl.DomAnchorImpl");
public static <T extends DomElement> DomAnchorImpl<T> createAnchor(@NotNull T t) {
return createAnchor(t, false);
}
public static <T extends DomElement> DomAnchorImpl<T> createAnchor(@NotNull T t, boolean usePsi) {
if (usePsi) {
final XmlElement element = t.getXmlElement();
if (element != null) {
return new PsiBasedDomAnchor<T>(PsiAnchor.create(element), element.getProject());
}
}
final DomElement parent = t.getParent();
if (parent == null) {
LOG.error("Parent null: " + t);
@@ -271,4 +284,33 @@ public abstract class DomAnchorImpl<T extends DomElement> implements DomAnchor<T
}
private static class PsiBasedDomAnchor<T extends DomElement> extends DomAnchorImpl<T> {
private final PsiAnchor myAnchor;
private final Project myProject;
public PsiBasedDomAnchor(PsiAnchor anchor, Project project) {
myAnchor = anchor;
myProject = project;
}
@Override
public T retrieveDomElement() {
PsiElement psi = myAnchor.retrieve();
if (psi == null) return null;
if (psi instanceof XmlTag) {
return (T)DomManager.getDomManager(myProject).getDomElement((XmlTag)psi);
}
if (psi instanceof XmlAttribute) {
return (T)DomManager.getDomManager(myProject).getDomElement((XmlAttribute)psi);
}
return null;
}
@NotNull
@Override
public XmlFile getContainingFile() {
return (XmlFile)myAnchor.getFile();
}
}
}

View File

@@ -21,6 +21,7 @@ import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.util.SmartList;
import com.intellij.util.xml.Converter;
import com.intellij.util.xml.DomAnchor;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.XmlName;
import com.intellij.util.xml.impl.ConvertAnnotationImpl;
@@ -38,6 +39,7 @@ import java.util.Map;
* @author peter
*/
public class DomExtensionImpl implements DomExtension {
public static final Key<DomAnchor> KEY_DOM_DECLARATION = Key.create("DOM_DECLARATION");
public static final Key<List<DomExtender>> DOM_EXTENDER_KEY = Key.create("Dom.Extender");
public static Key<SmartPsiElementPointer<?>> DECLARING_ELEMENT_KEY = Key.create("Dom.Extension.PsiDeclaration");
private final XmlName myXmlName;
@@ -73,7 +75,7 @@ public class DomExtensionImpl implements DomExtension {
}
public DomExtension setDeclaringElement(@NotNull DomElement declaringElement) {
putUserData(KEY_DECLARATION, DomAnchorImpl.createAnchor(declaringElement));
putUserData(KEY_DOM_DECLARATION, DomAnchorImpl.createAnchor(declaringElement, true));
return this;
}

View File

@@ -166,6 +166,11 @@ public class DomElementXmlDescriptor extends AbstractDomChildrenDescriptor {
public PsiElement getDeclaration(final Project project) {
return PomService.convertToPsi(project, this);
}
@Override
public DomElement getDomDeclaration() {
return myDomElement;
}
}
}

View File

@@ -53,4 +53,7 @@ public interface AbstractDomChildrenDescription extends AnnotatedElement, PomTar
@Nullable
PsiElement getDeclaration(Project project);
@Nullable
DomElement getDomDeclaration();
}

View File

@@ -19,7 +19,6 @@ package com.intellij.util.xml.reflect;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.util.xml.Converter;
import com.intellij.util.xml.DomAnchor;
import com.intellij.util.xml.DomElement;
import org.jetbrains.annotations.NotNull;
@@ -30,7 +29,6 @@ import java.lang.reflect.Type;
* @author peter
*/
public interface DomExtension {
Key<DomAnchor> KEY_DECLARATION = Key.create("DOM_DECLARATION");
@NotNull
Type getType();