DOM stubs for custom elements

This commit is contained in:
Dmitry Avdeev
2012-08-22 14:26:10 +04:00
parent 9a4e0f00d0
commit 6c2e45f8d5
27 changed files with 258 additions and 85 deletions
@@ -28,6 +28,7 @@ import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
public class LazyParseableElement extends CompositeElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.LazyParseableElement");
@@ -147,6 +148,9 @@ public class LazyParseableElement extends CompositeElement {
}
private void ensureParsed() {
if (!ourParsingAllowed) {
LOG.error("Parsing not allowed!!!");
}
CharSequence text = myText();
if (text == null) return;
@@ -220,4 +224,11 @@ public class LazyParseableElement extends CompositeElement {
}
return start + text.length();
}
private static boolean ourParsingAllowed = true;
@TestOnly
public static void setParsingAllowed(boolean allowed) {
ourParsingAllowed = allowed;
}
}
@@ -19,10 +19,12 @@ import com.intellij.ide.presentation.Presentation;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.NullableLazyValue;
import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.stubs.Stubbed;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.xml.*;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
@@ -62,6 +64,15 @@ public abstract class AbstractDomChildDescriptionImpl implements AbstractDomChil
myCustomAnnotations.put(annotation.annotationType(), annotation);
}
private NotNullLazyValue<Boolean> myStubbed = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return myType instanceof Class && DomReflectionUtil.findAnnotationDFS((Class)myType, Stubbed.class) != null ||
getAnnotation(Stubbed.class) != null;
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -188,4 +199,9 @@ public abstract class AbstractDomChildDescriptionImpl implements AbstractDomChil
}
return null;
}
@Override
public boolean isStubbed() {
return myStubbed.getValue();
}
}
@@ -39,6 +39,7 @@ public abstract class DomAnchorImpl<T extends DomElement> implements DomAnchor<T
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();
@@ -345,4 +346,36 @@ public abstract class DomAnchorImpl<T extends DomElement> implements DomAnchor<T
return result;
}
}
private static class StubAnchor<T extends DomElement> implements DomAnchor<T> {
private final DomInvocationHandler myHandler;
private StubAnchor(DomInvocationHandler handler) {
myHandler = handler;
}
@Nullable
@Override
public T retrieveDomElement() {
return (T)myHandler.getProxy();
}
@NotNull
@Override
public XmlFile getContainingFile() {
return myHandler.getFile();
}
@Nullable
@Override
public PsiElement getPsiElement() {
return myHandler.getXmlElement();
}
}
public static <T extends DomElement> DomAnchor<T> createStubAnchor(T element) {
DomInvocationHandler handler = DomManagerImpl.getDomInvocationHandler(element);
return handler.getStub() == null ? createAnchor(element, true) : new StubAnchor<T>(handler);
}
}
@@ -332,6 +332,11 @@ public class DomFileElementImpl<T extends DomElement> implements DomFileElement<
return checkValidity() == null;
}
@Override
public boolean exists() {
return true;
}
@Nullable
public String checkValidity() {
if (!myFile.isValid()) {
@@ -13,7 +13,6 @@ import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.Stubbed;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
@@ -27,6 +26,7 @@ import com.intellij.util.xml.events.DomEvent;
import com.intellij.util.xml.reflect.*;
import com.intellij.util.xml.stubs.AttributeStub;
import com.intellij.util.xml.stubs.DomStub;
import com.intellij.util.xml.stubs.ElementStub;
import com.intellij.util.xml.stubs.StubParentStrategy;
import net.sf.cglib.proxy.AdvancedProxy;
import net.sf.cglib.proxy.InvocationHandler;
@@ -257,6 +257,10 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
return getParentStrategy().getXmlElement();
}
public boolean exists() {
return getParentStrategy().isPhysical();
}
private DomParentStrategy getParentStrategy() {
myParentStrategy = myParentStrategy.refreshStrategy(this);
return myParentStrategy;
@@ -554,6 +558,12 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
final IndexedElementInvocationHandler getFixedChild(final Pair<FixedChildDescriptionImpl, Integer> info) {
final FixedChildDescriptionImpl description = info.first;
final EvaluatedXmlName evaluatedXmlName = createEvaluatedXmlName(description.getXmlName());
if (myStub != null && description.isStubbed()) {
List<DomStub> stubs = myStub.getChildrenByName(description.getXmlName().getLocalName());
DomStub stub = stubs.isEmpty() ? null : stubs.get(0);
DomParentStrategy strategy = stub == null ? new StubParentStrategy.Empty(myStub) : new StubParentStrategy(stub);
return new IndexedElementInvocationHandler(evaluatedXmlName, description, 0, strategy, myManager, (ElementStub)stub);
}
final XmlTag tag = getXmlTag();
final int index = info.second;
if (tag != null) {
@@ -586,7 +596,7 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
@NotNull
final AttributeChildInvocationHandler getAttributeChild(final AttributeChildDescriptionImpl description) {
final EvaluatedXmlName evaluatedXmlName = createEvaluatedXmlName(description.getXmlName());
if (myStub != null && description.getAnnotation(Stubbed.class) != null) {
if (myStub != null && description.isStubbed()) {
AttributeStub stub = myStub.getAttributeStub(description.getXmlName());
StubParentStrategy strategy = StubParentStrategy.createAttributeStrategy(stub, myStub);
return new AttributeChildInvocationHandler(evaluatedXmlName, description, myManager, strategy, stub);
@@ -758,15 +768,31 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
}
public List<? extends DomElement> getCollectionChildren(final AbstractCollectionChildDescription description, final NotNullFunction<DomInvocationHandler, List<XmlTag>> tagsGetter) {
if (myStub != null && description.getAnnotation(Stubbed.class) != null) {
XmlName xmlName = ((DomChildDescriptionImpl)description).getXmlName();
List<DomStub> stubs = myStub.getChildrenByName(xmlName.getLocalName());
return ContainerUtil.map(stubs, new Function<DomStub, DomElement>() {
@Override
public DomElement fun(DomStub stub) {
return stub.getOrCreateHandler((DomChildDescriptionImpl)description, myManager).getProxy();
}
});
if (myStub != null && description.isStubbed()) {
if (description instanceof DomChildDescriptionImpl) {
XmlName xmlName = ((DomChildDescriptionImpl)description).getXmlName();
List<DomStub> stubs = myStub.getChildrenByName(xmlName.getLocalName());
return ContainerUtil.map(stubs, new Function<DomStub, DomElement>() {
@Override
public DomElement fun(DomStub stub) {
return stub.getOrCreateHandler((DomChildDescriptionImpl)description, myManager).getProxy();
}
});
}
else if (description instanceof CustomDomChildrenDescriptionImpl) {
List<DomStub> stubs = myStub.getChildrenStubs();
return ContainerUtil.mapNotNull(stubs, new NullableFunction<DomStub, DomElement>() {
@Nullable
@Override
public DomElement fun(DomStub stub) {
if (stub instanceof ElementStub && ((ElementStub)stub).isCustom()) {
EvaluatedXmlName name = new DummyEvaluatedXmlName(stub.getName(), null);
return new CollectionElementInvocationHandler(name, (CustomDomChildrenDescriptionImpl)description, myManager, (ElementStub)stub).getProxy();
}
return null;
}
});
}
}
XmlTag tag = getXmlTag();
if (tag == null) return Collections.emptyList();
@@ -39,4 +39,6 @@ public interface DomParentStrategy {
String checkValidity();
XmlFile getContainingFile(DomInvocationHandler handler);
boolean isPhysical();
}
@@ -73,16 +73,15 @@ public class DynamicGenericInfo extends DomGenericInfoEx {
if (myInitialized) return true;
myStaticGenericInfo.buildMethodMaps();
final XmlElement element = myInvocationHandler.getXmlElement();
if (element == null) return true;
if (!myInvocationHandler.exists()) return true;
return ourGuard.doPreventingRecursion(element, false, new Computable<Boolean>() {
return ourGuard.doPreventingRecursion(myInvocationHandler, false, new Computable<Boolean>() {
@Override
public Boolean compute() {
DomExtensionsRegistrarImpl registrar = runDomExtenders();
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (element) {
synchronized (myInvocationHandler) {
if (!myInitialized) {
if (registrar != null) {
applyExtensions(registrar);
@@ -92,6 +92,11 @@ public class PhysicalDomParentStrategy implements DomParentStrategy {
return DomImplUtil.getFile(handler);
}
@Override
public boolean isPhysical() {
return true;
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
public boolean equals(final Object o) {
return strategyEquals(this, o);
@@ -64,6 +64,11 @@ public class RootDomParentStrategy implements DomParentStrategy {
return myFileElement.getFile();
}
@Override
public boolean isPhysical() {
return true;
}
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof RootDomParentStrategy)) return false;
@@ -18,7 +18,6 @@ package com.intellij.util.xml.impl;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.xml.DomUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -87,6 +86,11 @@ public class VirtualDomParentStrategy implements DomParentStrategy {
return DomImplUtil.getFile(handler);
}
@Override
public boolean isPhysical() {
return false;
}
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof VirtualDomParentStrategy)) return false;
@@ -21,10 +21,8 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.StringRef;
import com.intellij.util.xml.EvaluatedXmlNameImpl;
import com.intellij.util.xml.XmlName;
import com.intellij.util.xml.impl.CollectionElementInvocationHandler;
import com.intellij.util.xml.impl.DomChildDescriptionImpl;
import com.intellij.util.xml.impl.DomInvocationHandler;
import com.intellij.util.xml.impl.DomManagerImpl;
import com.intellij.util.xml.impl.*;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -49,7 +47,7 @@ public abstract class DomStub extends ObjectStubBase<DomStub> {
public abstract List<DomStub> getChildrenStubs();
public int getChildIndex(DomStub child) {
List<DomStub> stubs = getChildrenByName(child.getName());
List<DomStub> stubs = getChildrenByName(XmlUtil.getLocalName(child.getName()));
return stubs.indexOf(child);
}
@@ -57,11 +55,11 @@ public abstract class DomStub extends ObjectStubBase<DomStub> {
return myName.getString();
}
public List<DomStub> getChildrenByName(final String localName) {
public List<DomStub> getChildrenByName(final CharSequence localName) {
return ContainerUtil.filter(getChildrenStubs(), new Condition<DomStub>() {
@Override
public boolean value(DomStub stub) {
return stub.getName().equals(localName);
return stub instanceof ElementStub && XmlUtil.getLocalName(stub.getName()).equals(localName);
}
});
}
@@ -29,9 +29,11 @@ import java.util.List;
public class ElementStub extends DomStub {
private final List<DomStub> myChildren = new SmartList<DomStub>();
private final boolean myCustom;
public ElementStub(@Nullable ElementStub parent, StringRef name) {
public ElementStub(@Nullable ElementStub parent, StringRef name, boolean custom) {
super(parent, name);
myCustom = custom;
}
void addChild(DomStub child) {
@@ -58,4 +60,8 @@ public class ElementStub extends DomStub {
if (obj == this) return true;
return obj instanceof ElementStub && id == ((ElementStub)obj).id && myName.equals(((ElementStub)obj).myName);
}
public boolean isCustom() {
return myCustom;
}
}
@@ -33,11 +33,12 @@ public class ElementStubSerializer implements ObjectStubSerializer<ElementStub,
@Override
public void serialize(ElementStub stub, StubOutputStream dataStream) throws IOException {
dataStream.writeName(stub.getName());
dataStream.writeBoolean(stub.isCustom());
}
@Override
public ElementStub deserialize(StubInputStream dataStream, ElementStub parentStub) throws IOException {
return new ElementStub(parentStub, dataStream.readName());
return new ElementStub(parentStub, dataStream.readName(), dataStream.readBoolean());
}
@Override
@@ -32,7 +32,7 @@ public class FileStub extends ElementStub {
private final XmlFileHeader myHeader;
public FileStub(StringRef tagName, StringRef tagNamespace, StringRef publicId, StringRef systemId) {
super(null, tagName);
super(null, tagName, false);
myHeader = new XmlFileHeader(tagName == null ? null : tagName.getString(),
tagNamespace == null ? null : tagNamespace.getString(),
publicId == null ? null : publicId.getString(),
@@ -40,7 +40,7 @@ public class FileStub extends ElementStub {
}
public FileStub(XmlFileHeader header) {
super(null, StringRef.fromString(header.getRootTagLocalName()));
super(null, StringRef.fromString(header.getRootTagLocalName()), false);
myHeader = header;
}
@@ -30,17 +30,7 @@ public class StubParentStrategy implements DomParentStrategy {
public static StubParentStrategy createAttributeStrategy(@Nullable AttributeStub stub, @NotNull final DomStub parent) {
if (stub == null) {
return new StubParentStrategy(parent) {
@Override
public DomInvocationHandler getParentHandler() {
return parent.getHandler();
}
@Override
public XmlElement getXmlElement() {
return null;
}
};
return new Empty(parent);
}
else {
return new StubParentStrategy(stub) {
@@ -59,7 +49,7 @@ public class StubParentStrategy implements DomParentStrategy {
protected final DomStub myStub;
public StubParentStrategy(DomStub stub) {
public StubParentStrategy(@NotNull DomStub stub) {
myStub = stub;
}
@@ -112,9 +102,38 @@ public class StubParentStrategy implements DomParentStrategy {
return getParentHandler().getFile();
}
@Override
public boolean isPhysical() {
return true;
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object obj) {
return PhysicalDomParentStrategy.strategyEquals(this, obj);
}
public static class Empty extends StubParentStrategy {
private final DomStub myParent;
public Empty(DomStub parent) {
super(parent);
myParent = parent;
}
@Override
public DomInvocationHandler getParentHandler() {
return myParent.getHandler();
}
@Override
public XmlElement getXmlElement() {
return null;
}
@Override
public boolean isPhysical() {
return false;
}
}
}
@@ -68,7 +68,7 @@ public class DomStubBuilder implements BinaryFileStubBuilder {
@Override
public int getStubVersion() {
int version = 3;
int version = 6;
DomFileDescription[] descriptions = Extensions.getExtensions(DomFileDescription.EP_NAME);
for (DomFileDescription description : descriptions) {
version += description.getStubVersion();
@@ -24,6 +24,7 @@ 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.reflect.CustomDomChildrenDescription;
import com.intellij.util.xml.stubs.AttributeStub;
import com.intellij.util.xml.stubs.ElementStub;
import com.intellij.util.xml.stubs.FileStub;
@@ -46,12 +47,13 @@ public class DomStubBuilderVisitor implements DomElementVisitor {
public void visitDomElement(DomElement element) {
if (element.getAnnotation(Stubbed.class) != null ||
element.getChildDescription().getAnnotation(Stubbed.class) != null) {
element.getChildDescription().isStubbed()) {
XmlElement xmlElement = element.getXmlElement();
if (xmlElement instanceof XmlTag) {
ElementStub old = myRoot;
myRoot = new ElementStub(myRoot, StringRef.fromString(((PsiNamedElement)xmlElement).getName()));
boolean custom = element.getChildDescription() instanceof CustomDomChildrenDescription;
myRoot = new ElementStub(myRoot, StringRef.fromString(((PsiNamedElement)xmlElement).getName()), custom);
List<DomElement> children = DomUtil.getDefinedChildren(element, true, true);
for (DomElement child : children) {
visitDomElement(child);
@@ -171,6 +171,11 @@ public class DomElementXmlDescriptor extends AbstractDomChildrenDescriptor {
public DomElement getDomDeclaration() {
return myDomElement;
}
@Override
public boolean isStubbed() {
return false;
}
}
}
@@ -15,16 +15,16 @@
*/
package com.intellij.util.xml;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.xml.reflect.DomGenericInfo;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
import com.intellij.util.xml.reflect.DomGenericInfo;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import java.lang.reflect.Type;
@@ -59,6 +59,11 @@ public interface DomElement extends AnnotatedElement, UserDataHolder {
boolean isValid();
/**
* @return true if corresponding XML element exists
*/
boolean exists();
@NotNull
DomGenericInfo getGenericInfo();
@@ -18,10 +18,7 @@ import com.intellij.util.ReflectionUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.reflect.DomAttributeChildDescription;
import com.intellij.util.xml.reflect.DomCollectionChildDescription;
import com.intellij.util.xml.reflect.DomFixedChildDescription;
import com.intellij.util.xml.reflect.DomGenericInfo;
import com.intellij.util.xml.reflect.*;
import com.intellij.xml.util.XmlTagUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -455,4 +452,19 @@ public class DomUtil {
return Pair.create(startToken.getTextRange().shiftRight(-tag.getTextRange().getStartOffset()), (PsiElement)tag);
}
public static <T extends DomElement> List<T> getChildrenOf(DomElement parent, final Class<T> type) {
final ArrayList<T> list = new ArrayList<T>();
List<? extends AbstractDomChildrenDescription> descriptions = parent.getGenericInfo().getChildrenDescriptions();
for (AbstractDomChildrenDescription description : descriptions) {
if (description.getType() instanceof Class && type.isAssignableFrom((Class<?>)description.getType())) {
for (T value : (List<T>)description.getValues(parent)) {
if (value.exists()) {
list.add(value);
}
}
}
}
return list;
}
}
@@ -56,4 +56,6 @@ public interface AbstractDomChildrenDescription extends AnnotatedElement, PomTar
@Nullable
DomElement getDomDeclaration();
boolean isStubbed();
}
@@ -64,6 +64,11 @@ public class MockDomElement extends UserDataHolderBase implements DomElement{
throw new UnsupportedOperationException("Method isValid is not yet implemented in " + getClass().getName());
}
@Override
public boolean exists() {
throw new UnsupportedOperationException("Method exists is not yet implemented in " + getClass().getName());
}
@Override
@NotNull
public DomGenericInfo getGenericInfo() {
@@ -106,6 +106,11 @@ public class MockDomFileElement extends UserDataHolderBase implements DomFileEle
throw new UnsupportedOperationException("Method isValid is not yet implemented in " + getClass().getName());
}
@Override
public boolean exists() {
throw new UnsupportedOperationException("Method exists is not yet implemented in " + getClass().getName());
}
@Override
@NotNull
public DomGenericInfo getGenericInfo() {
@@ -18,10 +18,14 @@ package com.intellij.util.xml.stubs;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.stubs.ObjectStubTree;
import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.xml.XmlFile;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileDescription;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import com.intellij.util.xml.impl.DomManagerImpl;
import com.intellij.util.xml.stubs.model.Foo;
@@ -67,4 +71,21 @@ public abstract class DomStubTest extends LightCodeInsightFixtureTestCase {
ElementStub stub = getRootStub(file);
assertEquals(stubText, DebugUtil.stubTreeToString(stub));
}
protected <T extends DomElement> DomFileElement<T> prepare(String path, Class<T> domClass) {
PsiFile file = myFixture.configureByFile(path);
assertFalse(file.getNode().isParsed());
VirtualFile virtualFile = file.getVirtualFile();
ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), virtualFile, file);
assertNotNull(tree);
((PsiManagerImpl)getPsiManager()).cleanupForNextTest();
file = getPsiManager().findFile(virtualFile);
assertFalse(file.getNode().isParsed());
DomFileElement<T> fileElement = DomManager.getDomManager(getProject()).getFileElement((XmlFile)file, domClass);
assertNotNull(fileElement);
return fileElement;
}
}
@@ -15,18 +15,13 @@
*/
package com.intellij.util.xml.stubs;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.stubs.ObjectStubTree;
import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.stubs.model.Bar;
import com.intellij.util.xml.stubs.model.Foo;
@@ -42,7 +37,7 @@ public class DomStubUsingTest extends DomStubTest {
public void testFoo() throws Exception {
DomFileElement<Foo> fileElement = prepare("foo.xml");
DomFileElement<Foo> fileElement = prepare("foo.xml", Foo.class);
PsiFile file = fileElement.getFile();
assertFalse(file.getNode().isParsed());
@@ -71,7 +66,7 @@ public class DomStubUsingTest extends DomStubTest {
}
public void testAccessingPsi() throws Exception {
DomFileElement<Foo> element = prepare("foo.xml");
DomFileElement<Foo> element = prepare("foo.xml", Foo.class);
assertNotNull(element.getXmlElement());
XmlTag tag = element.getRootTag();
@@ -88,7 +83,7 @@ public class DomStubUsingTest extends DomStubTest {
}
public void testConverters() throws Exception {
DomFileElement<Foo> element = prepare("converters.xml");
DomFileElement<Foo> element = prepare("converters.xml", Foo.class);
Bar bar = element.getRootElement().getBars().get(0);
PsiClass value = bar.getClazz().getValue();
assertNotNull(value);
@@ -97,7 +92,7 @@ public class DomStubUsingTest extends DomStubTest {
}
public void testParent() throws Exception {
DomFileElement<Foo> element = prepare("parent.xml");
DomFileElement<Foo> element = prepare("parent.xml", Foo.class);
Bar bar = element.getRootElement().getBars().get(0);
GenericAttributeValue<Integer> notStubbed = bar.getNotStubbed();
@@ -111,20 +106,11 @@ public class DomStubUsingTest extends DomStubTest {
assertEquals(bar, parent);
}
private DomFileElement<Foo> prepare(String path) {
PsiFile file = myFixture.configureByFile(path);
assertFalse(file.getNode().isParsed());
VirtualFile virtualFile = file.getVirtualFile();
ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), virtualFile, file);
assertNotNull(tree);
public void testChildrenOfType() throws Exception {
((PsiManagerImpl)getPsiManager()).cleanupForNextTest();
file = getPsiManager().findFile(virtualFile);
assertFalse(file.getNode().isParsed());
DomFileElement<Foo> fileElement = DomManager.getDomManager(getProject()).getFileElement((XmlFile)file, Foo.class);
assertNotNull(fileElement);
return fileElement;
DomFileElement<Foo> element = prepare("foo.xml", Foo.class);
Foo foo = element.getRootElement();
List<Bar> bars = DomUtil.getChildrenOf(foo, Bar.class);
assertEquals(2, bars.size());
}
}
@@ -178,7 +178,7 @@ public class XmlBuilderDriver {
}
}
CharSequence localName = getLocalName(tagName);
CharSequence localName = XmlUtil.getLocalName(tagName);
String namespace = getNamespace(tagName);
XmlBuilder.ProcessingOrder order = builder.startTag(localName, namespace, node.getStartOffset(), node.getEndOffset(), headerEndOffset);
@@ -263,14 +263,6 @@ public class XmlBuilderDriver {
return "";
}
private static CharSequence getLocalName(final CharSequence tagName) {
int pos = StringUtil.indexOf(tagName, ':');
if (pos == -1) {
return tagName;
}
return tagName.subSequence(pos + 1, tagName.length());
}
private void checkForXmlns(LighterASTNode attrNode, FlyweightCapableTreeStructure<LighterASTNode> structure) {
final CharSequence name = getAttributeName(attrNode, structure);
if (Comparing.equal(name, XMLNS)) {
@@ -596,6 +596,14 @@ public class XmlUtil {
: doctype;
}
public static CharSequence getLocalName(final CharSequence tagName) {
int pos = StringUtil.indexOf(tagName, ':');
if (pos == -1) {
return tagName;
}
return tagName.subSequence(pos + 1, tagName.length());
}
private static class XmlElementProcessor {
private final PsiElementProcessor processor;
private final PsiFile targetFile;