How to limit proposed Java types to implementors of an interface

When you develop a DSL that derives from Xbase you likely want to refer to Jvm types through a JvmTypeReference.

CustomBehavior :
    'custom' (name = ID | 'ref' realizedBy=JvmTypeReference) (label = STRING);

If you hit CTRL+SPACE at such a position in the editor, by default you will get all visible Java types proposed:

This is not really useful when it only makes sense to refer to specifc types. If you want to limit the proposals to just implementors of a specific interface, you can customize this in the proposal provider by overriding the method completeJvmParameterizedTypeReference_Type(). The following example from Spray shows limiting the types to implementors of Graphiti’s ICustomFeature interface in the context of Spray’s CustomBehavior:

public class SprayProposalProvider extends AbstractSprayProposalProvider {
    @Inject
    private IJvmTypeProvider.Factory      jvmTypeProviderFactory;
    @Inject
    private ITypesProposalProvider        typeProposalProvider;
    
    @Override
    public void completeJvmParameterizedTypeReference_Type(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        if (EcoreUtil2.getContainerOfType(model, CustomBehavior.class) != null) {
            final IJvmTypeProvider jvmTypeProvider = jvmTypeProviderFactory.createTypeProvider(model.eResource().getResourceSet());
            // Graphiti specific
            final JvmType interfaceToImplement = jvmTypeProvider.findTypeByName(ICustomFeature.class.getName());
            typeProposalProvider.createSubTypeProposals(interfaceToImplement, this, context, SprayPackage.Literals.BEHAVIOR__REALIZED_BY, TypeMatchFilters.canInstantiate(), acceptor);
        } else {
            super.completeJvmParameterizedTypeReference_Type(model, assignment, context, acceptor);
        }
    }

Now you will get the desired subtypes as proposals:

Note that this does only limit proposals to certain types. It does not prevent you from actually referring to another type that you don’t get proposed. This needs to be restricted in your scope provider.
 

About these ads

6 thoughts on “How to limit proposed Java types to implementors of an interface

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s