Search in sources :

Example 1 with DomFixedChildDescription

use of com.intellij.util.xml.reflect.DomFixedChildDescription in project intellij-community by JetBrains.

the class IndexedElementInvocationHandler method createPathStableCopy.

@Override
public final DomElement createPathStableCopy() {
    final DomFixedChildDescription description = getChildDescription();
    final DomElement parentCopy = getParent().createStableCopy();
    return getManager().createStableValue((Factory<DomElement>) () -> parentCopy.isValid() ? description.getValues(parentCopy).get(myIndex) : null);
}
Also used : DomElement(com.intellij.util.xml.DomElement) DomFixedChildDescription(com.intellij.util.xml.reflect.DomFixedChildDescription)

Example 2 with DomFixedChildDescription

use of com.intellij.util.xml.reflect.DomFixedChildDescription in project intellij-community by JetBrains.

the class BasicDomElementComponent method bindProperties.

protected final void bindProperties(final DomElement domElement) {
    if (domElement == null)
        return;
    DomElementAnnotationsManager.getInstance(domElement.getManager().getProject()).addHighlightingListener(new DomElementAnnotationsManager.DomHighlightingListener() {

        @Override
        public void highlightingFinished(@NotNull final DomFileElement element) {
            ApplicationManager.getApplication().invokeLater(() -> {
                if (getComponent().isShowing() && element.isValid()) {
                    updateHighlighting();
                }
            });
        }
    }, this);
    for (final AbstractDomChildrenDescription description : domElement.getGenericInfo().getChildrenDescriptions()) {
        final JComponent boundComponent = getBoundComponent(description);
        if (boundComponent != null) {
            if (description instanceof DomFixedChildDescription && DomUtil.isGenericValueType(description.getType())) {
                if ((description.getValues(domElement)).size() == 1) {
                    final GenericDomValue element = domElement.getManager().createStableValue(() -> domElement.isValid() ? (GenericDomValue) description.getValues(domElement).get(0) : null);
                    doBind(DomUIFactory.createControl(element, commitOnEveryChange(element)), boundComponent);
                } else {
                //todo not bound
                }
            } else if (description instanceof DomCollectionChildDescription) {
                doBind(DomUIFactory.getDomUIFactory().createCollectionControl(domElement, (DomCollectionChildDescription) description), boundComponent);
            }
        }
    }
    reset();
}
Also used : DomCollectionChildDescription(com.intellij.util.xml.reflect.DomCollectionChildDescription) DomFileElement(com.intellij.util.xml.DomFileElement) AbstractDomChildrenDescription(com.intellij.util.xml.reflect.AbstractDomChildrenDescription) DomFixedChildDescription(com.intellij.util.xml.reflect.DomFixedChildDescription) DomElementAnnotationsManager(com.intellij.util.xml.highlighting.DomElementAnnotationsManager) GenericDomValue(com.intellij.util.xml.GenericDomValue)

Example 3 with DomFixedChildDescription

use of com.intellij.util.xml.reflect.DomFixedChildDescription in project intellij-community by JetBrains.

the class DomBasicsTest method testChildrenReflection.

public void testChildrenReflection() throws Throwable {
    final MyElement element = createElement("<a><child/><child-element/><child-element/></a>");
    final DomGenericInfo info = element.getGenericInfo();
    final DomFixedChildDescription foo = info.getFixedChildDescription("foo");
    assertFixedChildDescription(foo, element.getFoo(), "foo");
    final DomFixedChildDescription child = info.getFixedChildDescription("child");
    assertFixedChildDescription(child, element.getChild(), "child");
    final DomFixedChildDescription genericChild = info.getFixedChildDescription("generic-value");
    assertGenericChildDescription(genericChild, element.getGenericValue(), "generic-value");
    final DomCollectionChildDescription collectionChild = info.getCollectionChildDescription("child-element");
    assertEquals(element.getChildElements(), collectionChild.getValues(element));
    assertEquals("child-element", collectionChild.getXmlElementName());
    assertEquals(MyElement.class, collectionChild.getType());
    assertEquals(MyElement.class.getMethod("getChildElements"), collectionChild.getGetterMethod().getMethod());
    assertEquals(new HashSet(Arrays.asList(foo, child, collectionChild, genericChild, info.getAttributeChildrenDescriptions().get(0))), new HashSet(info.getChildrenDescriptions()));
}
Also used : DomCollectionChildDescription(com.intellij.util.xml.reflect.DomCollectionChildDescription) DomGenericInfo(com.intellij.util.xml.reflect.DomGenericInfo) DomFixedChildDescription(com.intellij.util.xml.reflect.DomFixedChildDescription)

Example 4 with DomFixedChildDescription

use of com.intellij.util.xml.reflect.DomFixedChildDescription in project intellij-community by JetBrains.

the class BaseDomElementNode method doGetChildren.

protected final SimpleNode[] doGetChildren(final DomElement element) {
    if (!element.isValid())
        return NO_CHILDREN;
    List<SimpleNode> children = new ArrayList<>();
    final XmlTag tag = element.getXmlTag();
    if (tag != null && !(tag.getContainingFile() instanceof XmlFile))
        return NO_CHILDREN;
    final XmlElementDescriptor xmlElementDescriptor = tag == null ? null : tag.getDescriptor();
    final XmlElementDescriptor[] xmlDescriptors = xmlElementDescriptor == null ? null : xmlElementDescriptor.getElementsDescriptors(tag);
    for (DomFixedChildDescription description : element.getGenericInfo().getFixedChildrenDescriptions()) {
        String childName = description.getXmlElementName();
        if (xmlDescriptors != null) {
            if (findDescriptor(xmlDescriptors, childName) == -1)
                continue;
        }
        final List<? extends DomElement> values = description.getStableValues(element);
        if (shouldBeShown(description.getType())) {
            if (DomUtil.isGenericValueType(description.getType())) {
                for (DomElement value : values) {
                    children.add(new GenericValueNode((GenericDomValue) value, this));
                }
            } else {
                for (DomElement domElement : values) {
                    children.add(new BaseDomElementNode(domElement, myRootDomElement, this));
                }
            }
        }
    }
    for (DomCollectionChildDescription description : element.getGenericInfo().getCollectionChildrenDescriptions()) {
        if (shouldBeShown(description.getType())) {
            DomElementsGroupNode groupNode = new DomElementsGroupNode(element, description, this, myRootDomElement);
            if (isMarkedType(description.getType(), CONSOLIDATED_NODES_KEY)) {
                Collections.addAll(children, groupNode.getChildren());
            } else {
                children.add(groupNode);
            }
        }
    }
    AbstractDomElementNode[] childrenNodes = children.toArray(new AbstractDomElementNode[children.size()]);
    Comparator<AbstractDomElementNode> comparator = DomUtil.getFile(myDomElement).getUserData(COMPARATOR_KEY);
    if (comparator == null) {
        comparator = getDefaultComparator(element);
    }
    if (comparator != null) {
        Arrays.sort(childrenNodes, comparator);
    }
    return childrenNodes;
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) SimpleNode(com.intellij.ui.treeStructure.SimpleNode) DomCollectionChildDescription(com.intellij.util.xml.reflect.DomCollectionChildDescription) DomFixedChildDescription(com.intellij.util.xml.reflect.DomFixedChildDescription) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) XmlTag(com.intellij.psi.xml.XmlTag)

Example 5 with DomFixedChildDescription

use of com.intellij.util.xml.reflect.DomFixedChildDescription 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

DomFixedChildDescription (com.intellij.util.xml.reflect.DomFixedChildDescription)6 DomCollectionChildDescription (com.intellij.util.xml.reflect.DomCollectionChildDescription)5 XmlFile (com.intellij.psi.xml.XmlFile)2 XmlTag (com.intellij.psi.xml.XmlTag)2 NullableComputable (com.intellij.openapi.util.NullableComputable)1 RecursionGuard (com.intellij.openapi.util.RecursionGuard)1 PsiElement (com.intellij.psi.PsiElement)1 XmlElementType (com.intellij.psi.xml.XmlElementType)1 SimpleNode (com.intellij.ui.treeStructure.SimpleNode)1 DomElement (com.intellij.util.xml.DomElement)1 DomFileElement (com.intellij.util.xml.DomFileElement)1 EvaluatedXmlName (com.intellij.util.xml.EvaluatedXmlName)1 EvaluatedXmlNameImpl (com.intellij.util.xml.EvaluatedXmlNameImpl)1 GenericDomValue (com.intellij.util.xml.GenericDomValue)1 XmlName (com.intellij.util.xml.XmlName)1 DomElementAnnotationsManager (com.intellij.util.xml.highlighting.DomElementAnnotationsManager)1 AbstractDomChildrenDescription (com.intellij.util.xml.reflect.AbstractDomChildrenDescription)1 CustomDomChildrenDescription (com.intellij.util.xml.reflect.CustomDomChildrenDescription)1 DomGenericInfo (com.intellij.util.xml.reflect.DomGenericInfo)1 DomStub (com.intellij.util.xml.stubs.DomStub)1