Override or cancel vanilla PsiReference
Answered
Hi guys, i'm facing a reference issue.
I need to reference from this kind of xml structure :
<compound-widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sc="http://ofbiz.apache.org/Site-Conf"
xmlns:wf="http://ofbiz.apache.org/Widget-Form"
xmlns:wm="http://ofbiz.apache.org/Widget-Menu"
xmlns:ws="http://ofbiz.apache.org/Widget-Screen"
xsi:noNamespaceSchemaLocation="../../../../framework/widget/dtd/compound-widgets.xsd">
<ws:screens>
<ws:screen name="FooScreen">
<ws:section>
<ws:widgets>
<ws:include-form name="Foo<caret>Form" location="component://foo/bar/CpdFormReferenceFromCpdScreen.xml"/>
</ws:widgets>
</ws:section>
</ws:screen>
</ws:screens>
<wf:forms>
<wf:form name="FooForm">
</wf:form>
</wf:forms>
</compound-widgets>
I thought the element at caret position (next to include-form tag) would not have reference at all from vanilla IDEA, so that i could use my own reference class.
But it appears that there is a reference found, with class
`com.intellij.psi.impl.source.resolve.reference.impl.providers.IdReferenceProvider$GlobalAttributeValueSelfReference@58d305c`
And i'd like to somehow overwite this reference and get my own, is there a way for doing that ?
Or is it that my patterns or dom description that are not correct ?
class CompoundFileDescription<S extends DomElement> extends DomFileDescription<CompoundFile> {
private static final String rootTagName = "compound-widgets"
public static final String SITE_CONF_NS_URL = 'http://ofbiz.apache.org/Site-Conf'
public static final String SITE_CONF_NS = 'sc'
public static final String FORM_NS_URL = 'http://ofbiz.apache.org/Widget-Form'
public static final String FORM_NS = 'wf'
public static final String MENU_NS_URL = 'http://ofbiz.apache.org/Widget-Menu'
public static final String MENU_NS = 'wm'
public static final String SCREEN_NS_URL = 'http://ofbiz.apache.org/Widget-Screen'
public static final String SCREEN_NS = 'ws'
CompoundFileDescription() { super(CompoundFile.class, rootTagName) }
@Override
protected void initializeFileDescription() {
registerNamespacePolicy(SITE_CONF_NS_URL, SITE_CONF_NS)
registerNamespacePolicy(FORM_NS_URL, FORM_NS)
registerNamespacePolicy(MENU_NS_URL, MENU_NS)
registerNamespacePolicy(SCREEN_NS_URL, SCREEN_NS)
}
}
public static final XmlNamedElementPattern.XmlAttributePattern FORM_CALL = XmlPatterns.xmlAttribute().andOr(
XmlPatterns.xmlAttribute()
.withParent(XmlPatterns.xmlTag().withName("include-form")
.withNamespace(CompoundFileDescription.FORM_NS))
.withName("name"),
//...
)
Thanks in advance for any help
Please sign in to leave a comment.
Hi Gaëtan,
What issue does the existing reference cause? Why can't you have both?
My problem is that i'm currently working with TDD, and i'm not getting the right type of reference.
Here is my test code :
I also added the order first to my EP declaration, but it didn't change anything
But from what i understand i should have two different references ? (or PsiMultiRef ?)
I suggest trying something like:
Thanks for this. I now know the problem is elsewhere (i don't know where yet) :
I suspect you add your reference in the higher level of the syntax tree, so
PsiTreeUtil.getParentOfType(elementAtCaret, YourElementWithReferenceType.class)
should do the job.Hi again Karol, and thanks for your patience. I fixed the namespacing in the DomFileDescription wich was inverted and double checked the pattern.
It turns out that the XmlAttributeValue is called when registering the reference provider (i dit come copy-paste in the first days of this project).
AFAIU the pattern sould a least trigger, but it doesn't. I obiously missed something, because there is still not my custom reference but i don't see it :
- patterns looks okay
- DomDescription looks ok (Even if i don't think it plays much of a role in references before resole gets called)
- Namespacing looks okay
Hi Gaëtan,
It’s hard to tell what can be wrong just by looking at these snippets.
I would change the pattern to match the
xmlAttributeValue().inside(...)
. Also, make sure thatwithParent()
is actually correct - it checks for direct parents, and there can be some intermediate node in the tree.I also suggest setting a breakpoint in
com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry#getReferencesFromProviders(PsiElement, PsiReferenceService.Hints)
and checking what happens and why your reference is not provided.Hi Karol, i made it work. The pattern wasn't ok after all. Turns out i had to specify the Namespace in the pattern like this :
I didn't thought it would be needed but it is.
Thanks again !