Search in sources :

Example 1 with ElementStub

use of com.intellij.util.xml.stubs.ElementStub in project intellij-community by JetBrains.

the class DomInvocationHandler method getCollectionChildren.

public List<? extends DomElement> getCollectionChildren(final AbstractCollectionChildDescription description) {
    if (myStub != null && description.isStubbed()) {
        if (description instanceof DomChildDescriptionImpl) {
            XmlName xmlName = ((DomChildDescriptionImpl) description).getXmlName();
            List<DomStub> stubs = myStub.getChildrenByName(xmlName.getLocalName(), xmlName.getNamespaceKey());
            return ContainerUtil.map(stubs, stub -> stub.getOrCreateHandler((DomChildDescriptionImpl) description, myManager).getProxy());
        } else if (description instanceof CustomDomChildrenDescriptionImpl) {
            List<DomStub> stubs = myStub.getChildrenStubs();
            return ContainerUtil.mapNotNull(stubs, (NullableFunction<DomStub, DomElement>) stub -> {
                if (stub instanceof ElementStub && stub.isCustom()) {
                    EvaluatedXmlName name = new DummyEvaluatedXmlName(stub.getName(), "");
                    return new CollectionElementInvocationHandler(name, (CustomDomChildrenDescriptionImpl) description, myManager, (ElementStub) stub).getProxy();
                }
                return null;
            });
        }
    }
    XmlTag tag = getXmlTag();
    if (tag == null)
        return Collections.emptyList();
    final List<XmlTag> subTags = getCollectionSubTags(description, tag);
    if (subTags.isEmpty())
        return Collections.emptyList();
    List<DomElement> elements = new ArrayList<>(subTags.size());
    for (XmlTag subTag : subTags) {
        final SemKey<? extends DomInvocationHandler> key = description instanceof CustomDomChildrenDescription ? DomManagerImpl.DOM_CUSTOM_HANDLER_KEY : DomManagerImpl.DOM_COLLECTION_HANDLER_KEY;
        final DomInvocationHandler semElement = myManager.getSemService().getSemElement(key, subTag);
        if (semElement == null) {
            String msg = "No child for subTag '" + subTag.getName() + "' in tag '" + tag.getName() + "' using key " + key + "; subtag count=" + subTags.size();
            DomInvocationHandler anyDom = myManager.getDomHandler(subTag);
            if (anyDom != null) {
                msg += "\n sub-dom=" + anyDom + " with " + anyDom.getChildDescription();
            }
            throw new AssertionError(msg);
        } else {
            elements.add(semElement.getProxy());
        }
    }
    return Collections.unmodifiableList(elements);
}
Also used : ArrayList(java.util.ArrayList) DomStub(com.intellij.util.xml.stubs.DomStub) ArrayList(java.util.ArrayList) List(java.util.List) ElementStub(com.intellij.util.xml.stubs.ElementStub) XmlTag(com.intellij.psi.xml.XmlTag)

Example 2 with ElementStub

use of com.intellij.util.xml.stubs.ElementStub in project intellij-community by JetBrains.

the class CollectionElementInvocationHandler method hashCode.

@Override
public int hashCode() {
    ElementStub stub = getStub();
    if (stub != null) {
        return stub.getName().hashCode() + stub.id;
    }
    final XmlElement element = getXmlElement();
    return element == null ? super.hashCode() : element.hashCode();
}
Also used : XmlElement(com.intellij.psi.xml.XmlElement) ElementStub(com.intellij.util.xml.stubs.ElementStub)

Example 3 with ElementStub

use of com.intellij.util.xml.stubs.ElementStub in project intellij-community by JetBrains.

the class DomStubBuilderVisitor method visitXmlElement.

void visitXmlElement(XmlElement element, ElementStub parent, int index) {
    DomInvocationHandler handler = myManager.getDomHandler(element);
    if (handler == null || handler.getAnnotation(Stubbed.class) == null && !handler.getChildDescription().isStubbed())
        return;
    AbstractDomChildrenDescription description = handler.getChildDescription();
    String nsKey = description instanceof DomChildrenDescription ? ((DomChildrenDescription) description).getXmlName().getNamespaceKey() : "";
    if (element instanceof XmlTag) {
        XmlTag tag = (XmlTag) element;
        String elementClass = null;
        if (handler.getAnnotation(StubbedOccurrence.class) != null) {
            final Type type = description.getType();
            elementClass = ((Class) type).getName();
        }
        ElementStub stub = new ElementStub(parent, StringRef.fromString(tag.getName()), StringRef.fromNullableString(nsKey), index, description instanceof CustomDomChildrenDescription, elementClass == null ? null : StringRef.fromNullableString(elementClass), tag.getSubTags().length == 0 ? tag.getValue().getTrimmedText() : "");
        for (XmlAttribute attribute : tag.getAttributes()) {
            visitXmlElement(attribute, stub, 0);
        }
        Map<String, Integer> indices = new HashMap<>();
        for (final XmlTag subTag : tag.getSubTags()) {
            String name = subTag.getName();
            Integer i = indices.get(name);
            i = i == null ? 0 : i + 1;
            visitXmlElement(subTag, stub, i);
            indices.put(name, i);
        }
    } else if (element instanceof XmlAttribute) {
        new AttributeStub(parent, StringRef.fromString(((XmlAttribute) element).getLocalName()), StringRef.fromNullableString(nsKey), ((XmlAttribute) element).getValue());
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) Stubbed(com.intellij.util.xml.Stubbed) HashMap(java.util.HashMap) DomInvocationHandler(com.intellij.util.xml.impl.DomInvocationHandler) CustomDomChildrenDescription(com.intellij.util.xml.reflect.CustomDomChildrenDescription) DomChildrenDescription(com.intellij.util.xml.reflect.DomChildrenDescription) AbstractDomChildrenDescription(com.intellij.util.xml.reflect.AbstractDomChildrenDescription) CustomDomChildrenDescription(com.intellij.util.xml.reflect.CustomDomChildrenDescription) Type(java.lang.reflect.Type) AttributeStub(com.intellij.util.xml.stubs.AttributeStub) AbstractDomChildrenDescription(com.intellij.util.xml.reflect.AbstractDomChildrenDescription) ElementStub(com.intellij.util.xml.stubs.ElementStub) XmlTag(com.intellij.psi.xml.XmlTag) StubbedOccurrence(com.intellij.util.xml.StubbedOccurrence)

Example 4 with ElementStub

use of com.intellij.util.xml.stubs.ElementStub in project intellij-community by JetBrains.

the class DomSemContributor method registerSemProviders.

@Override
public void registerSemProviders(SemRegistrar registrar) {
    registrar.registerSemElementProvider(DomManagerImpl.FILE_DESCRIPTION_KEY, xmlFile(), xmlFile -> {
        ApplicationManager.getApplication().assertReadAccessAllowed();
        return new FileDescriptionCachedValueProvider(DomManagerImpl.getDomManager(xmlFile.getProject()), xmlFile);
    });
    registrar.registerSemElementProvider(DomManagerImpl.DOM_HANDLER_KEY, xmlTag().withParent(psiElement(XmlElementType.XML_DOCUMENT).withParent(xmlFile())), xmlTag -> {
        final FileDescriptionCachedValueProvider provider = mySemService.getSemElement(DomManagerImpl.FILE_DESCRIPTION_KEY, xmlTag.getContainingFile());
        assert provider != null;
        final DomFileElementImpl element = provider.getFileElement();
        if (element != null) {
            final DomRootInvocationHandler handler = element.getRootHandler();
            if (handler.getXmlTag() == xmlTag) {
                return handler;
            }
        }
        return null;
    });
    final ElementPattern<XmlTag> nonRootTag = xmlTag().withParent(or(xmlTag(), xmlEntityRef().withParent(xmlTag())));
    registrar.registerSemElementProvider(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, nonRootTag, tag -> {
        final XmlTag parentTag = PhysicalDomParentStrategy.getParentTag(tag);
        assert parentTag != null;
        DomInvocationHandler parent = getParentDom(parentTag);
        if (parent == null)
            return null;
        final String localName = tag.getLocalName();
        final String namespace = tag.getNamespace();
        final DomFixedChildDescription description = findChildrenDescription(parent.getGenericInfo().getFixedChildrenDescriptions(), tag, parent);
        if (description != null) {
            final int totalCount = description.getCount();
            int index = 0;
            PsiElement current = tag;
            while (true) {
                current = current.getPrevSibling();
                if (current == null) {
                    break;
                }
                if (current instanceof XmlTag) {
                    final XmlTag xmlTag = (XmlTag) current;
                    if (localName.equals(xmlTag.getLocalName()) && namespace.equals(xmlTag.getNamespace())) {
                        index++;
                        if (index >= totalCount) {
                            return null;
                        }
                    }
                }
            }
            final DomManagerImpl myDomManager = parent.getManager();
            return new IndexedElementInvocationHandler(parent.createEvaluatedXmlName(description.getXmlName()), (FixedChildDescriptionImpl) description, index, new PhysicalDomParentStrategy(tag, myDomManager), myDomManager, null);
        }
        return null;
    });
    registrar.registerSemElementProvider(DomManagerImpl.DOM_COLLECTION_HANDLER_KEY, nonRootTag, tag -> {
        final XmlTag parentTag = PhysicalDomParentStrategy.getParentTag(tag);
        assert parentTag != null;
        DomInvocationHandler parent = getParentDom(parentTag);
        if (parent == null)
            return null;
        final DomCollectionChildDescription description = findChildrenDescription(parent.getGenericInfo().getCollectionChildrenDescriptions(), tag, parent);
        if (description != null) {
            DomStub parentStub = parent.getStub();
            if (parentStub != null) {
                int index = ArrayUtil.indexOf(parentTag.findSubTags(tag.getName(), tag.getNamespace()), tag);
                ElementStub stub = parentStub.getElementStub(tag.getLocalName(), index);
                if (stub != null) {
                    XmlName name = description.getXmlName();
                    EvaluatedXmlNameImpl evaluatedXmlName = EvaluatedXmlNameImpl.createEvaluatedXmlName(name, name.getNamespaceKey(), true);
                    return new CollectionElementInvocationHandler(evaluatedXmlName, (AbstractDomChildDescriptionImpl) description, parent.getManager(), stub);
                }
            }
            return new CollectionElementInvocationHandler(description.getType(), tag, (AbstractCollectionChildDescription) description, parent, null);
        }
        return null;
    });
    registrar.registerSemElementProvider(DomManagerImpl.DOM_CUSTOM_HANDLER_KEY, nonRootTag, new NullableFunction<XmlTag, CollectionElementInvocationHandler>() {

        private final RecursionGuard myGuard = RecursionManager.createGuard("customDomParent");

        @Override
        public CollectionElementInvocationHandler fun(XmlTag tag) {
            if (StringUtil.isEmpty(tag.getName()))
                return null;
            final XmlTag parentTag = PhysicalDomParentStrategy.getParentTag(tag);
            assert parentTag != null;
            DomInvocationHandler parent = myGuard.doPreventingRecursion(tag, true, (NullableComputable<DomInvocationHandler>) () -> getParentDom(parentTag));
            if (parent == null)
                return null;
            DomGenericInfoEx info = parent.getGenericInfo();
            final List<? extends CustomDomChildrenDescription> customs = info.getCustomNameChildrenDescription();
            if (customs.isEmpty())
                return null;
            if (mySemService.getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, tag) == null && mySemService.getSemElement(DomManagerImpl.DOM_COLLECTION_HANDLER_KEY, tag) == null) {
                String localName = tag.getLocalName();
                XmlFile file = parent.getFile();
                for (final DomFixedChildDescription description : info.getFixedChildrenDescriptions()) {
                    XmlName xmlName = description.getXmlName();
                    if (localName.equals(xmlName.getLocalName()) && DomImplUtil.isNameSuitable(xmlName, tag, parent, file)) {
                        return null;
                    }
                }
                for (CustomDomChildrenDescription description : customs) {
                    if (description.getTagNameDescriptor() != null) {
                        AbstractCollectionChildDescription desc = (AbstractCollectionChildDescription) description;
                        Type type = description.getType();
                        return new CollectionElementInvocationHandler(type, tag, desc, parent, null);
                    }
                }
            }
            return null;
        }
    });
    registrar.registerSemElementProvider(DomManagerImpl.DOM_ATTRIBUTE_HANDLER_KEY, xmlAttribute(), attribute -> {
        final XmlTag tag = PhysicalDomParentStrategy.getParentTag(attribute);
        final DomInvocationHandler handler = tag == null ? null : getParentDom(tag);
        if (handler == null)
            return null;
        final String localName = attribute.getLocalName();
        final Ref<AttributeChildInvocationHandler> result = Ref.create(null);
        handler.getGenericInfo().processAttributeChildrenDescriptions(description -> {
            if (description.getXmlName().getLocalName().equals(localName)) {
                final EvaluatedXmlName evaluatedXmlName = handler.createEvaluatedXmlName(description.getXmlName());
                final String ns = evaluatedXmlName.getNamespace(tag, handler.getFile());
                if (ns.equals(tag.getNamespace()) && localName.equals(attribute.getName()) || ns.equals(attribute.getNamespace())) {
                    final DomManagerImpl myDomManager = handler.getManager();
                    final AttributeChildInvocationHandler attributeHandler = new AttributeChildInvocationHandler(evaluatedXmlName, description, myDomManager, new PhysicalDomParentStrategy(attribute, myDomManager), null);
                    result.set(attributeHandler);
                    return false;
                }
            }
            return true;
        });
        return result.get();
    });
}
Also used : DomStub(com.intellij.util.xml.stubs.DomStub) CustomDomChildrenDescription(com.intellij.util.xml.reflect.CustomDomChildrenDescription) EvaluatedXmlName(com.intellij.util.xml.EvaluatedXmlName) XmlName(com.intellij.util.xml.XmlName) PsiElement(com.intellij.psi.PsiElement) EvaluatedXmlName(com.intellij.util.xml.EvaluatedXmlName) XmlFile(com.intellij.psi.xml.XmlFile) RecursionGuard(com.intellij.openapi.util.RecursionGuard) NullableComputable(com.intellij.openapi.util.NullableComputable) EvaluatedXmlNameImpl(com.intellij.util.xml.EvaluatedXmlNameImpl) XmlElementType(com.intellij.psi.xml.XmlElementType) Type(java.lang.reflect.Type) DomCollectionChildDescription(com.intellij.util.xml.reflect.DomCollectionChildDescription) DomFixedChildDescription(com.intellij.util.xml.reflect.DomFixedChildDescription) ElementStub(com.intellij.util.xml.stubs.ElementStub) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

ElementStub (com.intellij.util.xml.stubs.ElementStub)4 XmlTag (com.intellij.psi.xml.XmlTag)3 CustomDomChildrenDescription (com.intellij.util.xml.reflect.CustomDomChildrenDescription)2 DomStub (com.intellij.util.xml.stubs.DomStub)2 Type (java.lang.reflect.Type)2 NullableComputable (com.intellij.openapi.util.NullableComputable)1 RecursionGuard (com.intellij.openapi.util.RecursionGuard)1 PsiElement (com.intellij.psi.PsiElement)1 XmlAttribute (com.intellij.psi.xml.XmlAttribute)1 XmlElement (com.intellij.psi.xml.XmlElement)1 XmlElementType (com.intellij.psi.xml.XmlElementType)1 XmlFile (com.intellij.psi.xml.XmlFile)1 EvaluatedXmlName (com.intellij.util.xml.EvaluatedXmlName)1 EvaluatedXmlNameImpl (com.intellij.util.xml.EvaluatedXmlNameImpl)1 Stubbed (com.intellij.util.xml.Stubbed)1 StubbedOccurrence (com.intellij.util.xml.StubbedOccurrence)1 XmlName (com.intellij.util.xml.XmlName)1 DomInvocationHandler (com.intellij.util.xml.impl.DomInvocationHandler)1 AbstractDomChildrenDescription (com.intellij.util.xml.reflect.AbstractDomChildrenDescription)1 DomChildrenDescription (com.intellij.util.xml.reflect.DomChildrenDescription)1