custom language PsiReferenceContributor to DomElement

Hi all,

I am facing some issues with PsiReferenceContributor; Here is an overview of my use case + problem! :)

The blueprint specification allows property injection  from configuration using the notation ${propertyName}.
For example, below we can see that the 'contact' bean will have an injected firstName of 'CustomValue';

    <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint" update-strategy="reload">
        <cm:default-properties>
            <cm:property name="myCustomConfig" value="CustomValue"/>
        </cm:default-properties>
    </cm:property-placeholder>

    <bean id="contact" class="foo.bar.example.Contact">
        <property name="firstName" value="${myCustomConfig}" />
    </bean>



Currently I have the following code:
- A lexer/parser for this custom blueprint injection language;
- A languageInjector for injecting the Blueprint language into the property value attribute

I can see from the PsiViewer that my language is successfully injected into the attribute, and is lexing + parsing my custom language.


http://devnet.jetbrains.com/servlet/JiveServlet/download/5489669-18276/BlueprintInjectionPsiScreenshot.png

However when I try to wire up a PsiReferenceContributor using the pattern 'PlatformPatterns.psiElement(InjectionPropertyDefinition.class)' as shown below, my PsiReferenceProvider method getReferencesByElement is never triggered;

    @Override
    public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
        ElementPattern pattern = PlatformPatterns.psiElement(InjectionPropertyDefinition.class);

        registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
            @NotNull
            @Override
            public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
              // Method never triggered
             return PsiReference.EMPTY_ARRAY;
            }
        });
    }


However, removing the argument InjectionProperyDefinition and simply using  'PlatformPatterns.psiElement()' does allow it to trigger successfully;

For reference - my current plan is that once this method successfully triggers, I can then try to return a custom PsiReferenceBase instance that points to the relevant DomElement;

Any feedback on this matter would be great! :)

Cheers,
Alan



Attachment(s):
BlueprintInjectionPsiScreenshot.png
3 comments

Hello, Alan.

Try to extends your psi element with com.intellij.psi.ContributedReferenceHost interface. And implement method getReferences, for example as following.

@NotNull
  public PsiReference[] getReferences() {
    return PsiReferenceService.getService().getContributedReferences(this);
  }

During invocation PsiReferenceService will check if your class implements ContributedReferenceHost. If so then it will invoke all registered reference providers for your element.

Or, the second solution: Just override getReferences method in your psi element with your custom logic without registering any reference providers.

0

Hey Den[iy]s,

Thanks for the reply! That seems to trigger it now for me - perfect! :)

---

For anyone Googling/searching this post; I am using GrammarKit BNF + Flex, and this is what I did :

Created a basc interface for my element which extends ContributedReferenceHost

public interface BlueprintInjectionPropertyDefinition extends PsiNameIdentifierOwner, ContributedReferenceHost {
}



Implemented this basic interface :

public abstract class BlueprintInjectionPropertyDefinitionImpl extends ASTWrapperPsiElement implements BlueprintInjectionPropertyDefinition {
    public BlueprintInjectionPropertyDefinitionImpl(@NotNull ASTNode node) {
        super(node);
    }

    @Override
    @NotNull
    public PsiReference[] getReferences() {
        return PsiReferenceService.getService().getContributedReferences(this);
    }
}


Updated the grammar to include the interface and mixin, with the correct fully qualified paths


propertyDefinition ::= FUNCTION_START PROPERTY_NAME FUNCTION_END {
    mixin="your.path.BlueprintInjectionPropertyDefinitionImpl"
    implements="your.path.BlueprintInjectionPropertyDefinition"
}


Cheers
Alan

0

Hello Alan,

could you please contact me at yXann.cXebron@jetbrains.com (remove X's), I have some questions about your plugin.

Thanks,
Yann

0

Please sign in to leave a comment.