Enabling TemplateVariableResolver for Xbase imports in Xtext editor
October 4, 2015
eclipse xtext xbaseWhile implementing code templates for the Isis Script DSL editor I struggled with the template variable resolver for Xbase Imports.
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.