While implementing code templates for the Isis Script DSL editor I struggled with the template variable resolver for Xbase Imports.

Isis Script Templates

Despite the corresponding TemplateVariableResolver implementation ImportsVariableResolver is active by default it’s not working as expected - no imports are added.

Debugging the implementation of the resolveVariables() method reveals that it doesn’t get the expected TemplateContext implementation XbaseTemplateContext which provides access to the DSLs import section:

public List<String> resolveValues(TemplateVariable variable, XtextTemplateContext xtextTemplateContext) {
	variable.setUnambiguous(true);
	variable.setValue(""); //$NON-NLS-1$
	if (xtextTemplateContext instanceof XbaseTemplateContext) {
		XbaseTemplateContext xbaseCtx = (XbaseTemplateContext) xtextTemplateContext;
		List<?> params = variable.getVariableType().getParams();
		if (params.size() > 0) {
			for (Iterator<?> iterator = params.iterator(); iterator.hasNext();) {
				String typeName = (String) iterator.next();
				xbaseCtx.addImport(typeName);
			}
		}
	}
	return new ArrayList<String>();
}

Xtexts content assist retrives this TemplateContext implementation from the XbaseTemplateProposalProvider - an extension of Xtexts DefaultTemplateProposalProvider.

To use XbaseTemplateProposalProvider instead of DefaultTemplateProposalProvider we have to override the corresponding Guice binding for ITemplateProposalProvider:

public Class<? extends ITemplateProposalProvider> bindITemplateProposalProvider() {
	return DefaultTemplateProposalProvider.class;
}

Unluckily XbaseTemplateProposalProvider can’t be used here due to the lack of an @Inject annotation for its constructor (Xtext version 2.8.4). So we have to create our own subclass providing an annotated constructor

@Singleton
public class IsisTemplateProposalProvider extends XbaseTemplateProposalProvider {

	@Inject
	public IsisTemplateProposalProvider(TemplateStore templateStore, ContextTypeRegistry registry,
			ContextTypeIdHelper helper) {
		super(templateStore, registry, helper);
	}

}

and use this in our Xtext editors UI Guice module

public class IsisUiModule extends AbstractIsisUiModule {

	public IsisUiModule(AbstractUIPlugin plugin) {
		super(plugin);
	}

	@Override
	public Class<? extends ITemplateProposalProvider> bindITemplateProposalProvider() {
		return IsisTemplateProposalProvider.class;
	}
}

Providing our own subclass of XbaseTemplateProposalProvider allows us to customize the template proposals of our Xtext editor. Here we can override getImage() to show a different image for the proposals or override getRelevance() for changing the order of the proposals.