DOM <=> PSI
Hi all,
I'm new to writing Intellij plugins, and I was wondering if there's any advice on how to convert a PsiElement into a DOM element?
My use case is:
- I already have the interfaces which extend 'com.intellij.util.xml.DomElement'
- I have a PsiElement (from an XML Document) which is given to me from extending GotoDeclarationHandlerBase (below)
public abstract class GotoDeclarationHandlerBase implements GotoDeclarationHandler {
@Nullable
public abstract PsiElement getGotoDeclarationTarget(PsiElement sourceElement, Editor editor);
How do I go about converting this PSI element to a DomElement?
I noticed this is as a TODO on the DOM documentation page that i've been following religiously http://confluence.jetbrains.com/display/IDEADEV/Accessing+XML+through+IntelliJ+IDEA+DOM
Any advice would be much appreciated
Thanks
请先登录再写评论。
What are you trying to achieve? Normally, if you want to add an extra reference to an XML element, you need to use PsiReferenceContributor to inject it, rather than override the "goto declaration" action. This will allow you to also support Find Usages and Rename for your reference.
Hi Dmitry, thanks for your response!
I'm trying to write a plugin that will allow me to jump from uses of a bean to the bean definition, or to a class method
Here is an example of the XML file :
I think I will need a lot of DOM interaction in order to do this?
Another problem is, there are multiple places that bean references can be made, for instance - so I need a way to easily convert a string to a more usable element if possible?
Is there a preferred way to do this sort of manipulation+searching?
Currently I am working with DomElements and following the Custom language tutorial very closely, but as there is no DOM manipulation in that tutorial, I am doing a lot of research!
This is a quick example of the GotoDeclarationHandler i have at the minute
// Handles the goto for the method attribute for the following // <bean ref="id" method="FOO" /> public PsiElement getGotoDeclarationTarget(PsiElement sourceElement, Editor editor) { // Get the parent element, IE the methodAttributeValue final PsiElement parent = sourceElement.getParent(); if (parent == null) { return null; } boolean isMethodPattern = xmlAttributeValue( xmlAttribute("method").withSuperParent(1, xmlTag().withLocalName("bean")) ).accepts(parent); if(isMethodPattern) { // Get the parent xml tag, in order to get the id XmlAttributeValue methodAttributeValue = (XmlAttributeValue) parent; XmlAttribute xmlAttribute = (XmlAttribute) methodAttributeValue.getParent(); XmlTag xmlTag = xmlAttribute.getParent(); // ...As you can see I'm doing a lot of things that the DOM documentation says i shouldn't be doing - so I would really prefer to be working with the DOMElements I have created instead! :)
For reference, this is the DomElement interface I am using for the Bean declaration (The one defined outside of a camel context XML element)
public interface Bean extends DomElement { // TODO - What does @NameValue do? @Attribute("id") GenericAttributeValue<String> getId(); @Attribute("class") @NotNull GenericAttributeValue<PsiClass> getClassAttribute(); }So am thinking I need to a way to perform PSI => DOM if possible, am I right in thinking this?
Thank you in advance for your time! :)
You don't need GotoDeclarationHandler at all, please disable it first to avoid any interference.
In your DOM-class for "<bean>" element define attribute "id" with @NameValue, then "ref" should return GenericAttributeValue<YourBeanClass> and resolving should work out of the box. For non DOM<->DOM references you can use com.intellij.util.xml.CustomReferenceConverter to create your own PsiReferences.
Thank you; I didn't realise that the registered File description would handle all of this for me out of the box!
I had imagined that I would need to do all of this myself, similiar to the Custom Language example that was recently released.
Thanks again.