Merging result from multiple reference providers. Follow
Hi all,
I'm in a situation where reference target can come from multiple classes of destinations, which makes merge result from
reference providers necessary. I came with following solution:
public class CompositeRerefernce extends PsiReferenceBase {
final PsiReference[] references;
public CompositeRerefernce(@NotNull PsiElement element, PsiReference... references) {
super(element);
this.references = references;
}
@Nullable
@Override
public PsiElement resolve() {
for (PsiReference reference : references) {
PsiElement resolve = reference.resolve();
if (null != resolve) {
return resolve;
}
}
return null;
}
@NotNull
@Override
public Object[] getVariants() {
ArrayList candidates = new ArrayList();
for (PsiReference reference : references) {
candidates.addAll(Arrays.asList(reference.getVariants()));
}
return candidates.toArray();
}
}
Is there better way to do this?
Please sign in to leave a comment.
It seems you might replace your class with com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
I tried poly references, but they seem to behave differenlty. Somehow they are not marked as errors, whenr eference is resolved to null
( or I miss something ) obvious. I have different kinds of objects ( actions, events etc - yes, I'm developing homegrown BPM ) and they
have to be merged in different contexts ( say, actions can come as sources and destinations, but certain kinds of events are accetable either as source or destination only )
- and indifuvudual collections can be used as references. Actually I could use PSI elements as differences are in presentation only but I did not managed
@Presentation annotation to work in code completionpopup and in gutter.
( tried to steal from struts2 plugin, but did not found where and what;) )
About not highlighting references, please post relevant part of your DOM XML and code of Converter.
For completion, you'll have to build your own variants using LookupElementBuilder. You can obtain @Presentation values via com.intellij.ide.TypePresentationService.
Converter is very easy, nothing special there :
Just combination of references I delegate to. And I build lookups elements in indivudual references ( for example gateways or events can have different icons based on types)
And in DOM:
I hoped there is some reallly easy to use generic mechanism in DOM saving me some boilerplate code
Do your PsiPolyReferences always return non-empty result from multiResolve?
Do you really need to create custom references here, maybe your possible DOM "target" classes can share a common "ImATarget" interface and you could use plain ResolvingConverter<ImATarget>.
Looking into ResolvingConverter, I could use generic method to retrieve icons / texts from DOM.
Not sure I will profit from it - Events are either source or destination, based on enum type of yet anoher attribute,
different attributes of same DOM object are used as references in different contexts.
You could use that attribute to decide what converter instance to use via com.intellij.util.xml.ResolvingConverter.WrappedResolvingConverter