PsiReference in yaml file works differently when i use it thought ReferenceInjector and when i use PsiReferenceContributor.

Answered

Hi. My question about PsiReference. I try to use it in yaml file, and don't fully understand how it works. It works differently when i use it thought ReferenceInjector and when i use PsiReferenceContributor.
I prepared simple one class example here
https://github.com/sergeysenja1992/demo-reference-issue
Main question is

list:
- key: A1
- key: A2
  link: A1
- key: A3
  link: A4 # I want error here

 

When reference injected across ReferenceInjector reference A4 show error.
When reference injected across PsiReferenceContributor on A4 no errors.
How can I make automation reference injection that will show error on invalid links?

5
1 comment

I can't reproduce "it works with Injector, but not with Contributor" (and didn't expect it would make a difference).

Actually, highlighting unresolved references must be performed by the plugin itself. There is no "automatic highlighting" unless some other inspection is - by accident - also processing your references and adding highlights for them. You can use Annotator or Inspector for such highlighting, see https://plugins.jetbrains.com/docs/intellij/syntax-highlighting-and-error-highlighting.html#annotator.

Notes: Please upgrade id 'org.jetbrains.intellij' version '0.6.5' to 0.7.2 in Gradle

The actual resolving should occur _inside_ com.icthh.xm.demoplugin.LinkTypeKeyReference#resolve method, not in PsiReferenceProvider, also some cleanup. You can use getVariants() here to quickly visually test your reference is working at expected range.

class YamlPsiReferenceContributor: PsiReferenceContributor() {
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
registrar.registerReferenceProvider(
getPattern(),
object : PsiReferenceProvider() {
override fun getReferencesByElement(
element: PsiElement,
context: ProcessingContext
): Array<PsiReference> {
return arrayOf(LinkTypeKeyReference(element))
}
},
HIGHER_PRIORITY
)
}

private fun getPattern() = psiElement<YAMLScalar>().withParent(
psiElement<YAMLKeyValue>().withName("link").withParent(
psiElement<YAMLMapping>().withParent(
psiElement<YAMLSequenceItem>().withParent(
psiElement<YAMLSequence>().withParent(
psiElement<YAMLKeyValue>().withName("list")
)
)
)
)
)

inline fun <reified T : PsiElement> psiElement() = psiElement(T::class.java)

}

class LinkTypeKeyReference(target:PsiElement):
PsiReferenceBase<PsiElement>(target),
EmptyResolveMessageProvider {
override fun resolve() = findReferenceTarget(element)
override fun getVariants(): Array<Any> {
return arrayOf("1","2","3")
}

override fun getUnresolvedMessagePattern(): String = "Link with value $value not found"
}
1

Please sign in to leave a comment.