Don't bother with a misconfigured MPS generator

·

3 min read

Presumably, most DSLs will likely provide a generator to the end user. MPS comes with a couple of generator settings the user may change on purpose or not. These settings are usually technical details and you don't want to bother your domain experts with configuring these correctly.

In one project a large model and complex generator are used and I discovered cases where it is convenient to automatically change settings preventing the user from fighting with misconfiguration.

In the first scenario, the generation of the large model exceeded the maximum size of trace.info which led to a generator crash. The creation of trace.info is usually enabled by default. In another case, activated transient models caused trouble. There is a small purple button in the IDE status bar and the user may hit this accidentally. If so, the generator is much slower or might even crash for larger models.

As said above, those are technical details and we don't want our domain experts to understand and deal with them. How can we protect them?

Update settings at MPS start

One solution is to change the generator settings to predefined default values on the project load using a project plugin. This can simply be archived by editing the IModifiableGenerationSettings of GenerationSettingsProvider as the code snippet below reveals.

project plugin ProjectGeneratorSettings {

  init(project)->void { 
    GenerationSettingsProvider settingsProvider = project.getPlatform().findComponent(GenerationSettingsProvider.class); 
    if (settingsProvider != null) { 
      IModifiableGenerationSettings settings = settingsProvider.getGenerationSettings(); 
      settings.setGenerateDebugInfo(false); 
      settings.setSaveTransientModels(false);
      settings.setShowWarnings(false);
    } 
  }
}

The first two settings are explained above. The third one can reduce generator log messages and could be beneficial for complex generations. The large generator is based on Mbeddr C, a quite complex DSL and collection of generators, and we cannot avoid all generator warnings as they may come from Mbeddr. Due to the large model, many warnings are generated delaying the completion by around 20 seconds (the complete generation takes around 15 minutes).

Notification balloons

Whenever settings are changed in the background, the user should be notified to avoid any confusion. A good option is using IDEA's notification balloons (Use notification balloons instead of message boxes - Specific Languages).

Observing generator settings

Fixing the settings only at project load implies reloading the project (or restarting MPS). It would be better to observe the settings and react to changes directly. To do so, a listener can be added to the settings field using addSettingsListener(IModifiableGenerationSettings.Listener). The interface has only one method and, unfortunately, doesn't tell us the changed property. Thus, you have to check each you are interested in. The code snippet gives an example of the warnings option.

settings.addListener(new IModifiableGenerationSettings.Listener() { 
  @Override 
  public void settingsChanged() { 
    if (settings.isShowWarnings()) { 
      settings.setShowWarnings(false); 
    }
  } 
});

If you update the settings for your users automatically, you may want to have something like a development mode where settings are editable. Warnings, transient models and the trace.info file can be valuable for language engineers.

Let me know whether you like or dislike those approaches. Perhaps you know and would like to share an even better solution for supporting our users.