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);
}
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();
}
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()));
}
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;
}
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();
});
}
Aggregations