MPS 2022.3 Is Finally Here!
This version was supposed to be released last year, but we had to delay the release date because of some technical issues. MPS is built on top of the IntelliJ IDEA platform, so every release cycle, we have to migrate to the new version of the platform. Sometimes the migration is straightforward, other times not so much. We’re working to make this migration smoother to avoid delays in the future. We apologize for any inconvenience that this delay might have caused you.
Let’s take a look at the new functionality that we prepared for this release or watch our screencast to get better acquainted with the main features.
The constraint rules update (Client sponsored)
The Constraint Rules language was created to address Constraint language deficiencies. For this release, the Constraint Rules have taken a step forward in improving the usability of the language.
- The constraint rules definitions can now be referred to from NodeTestCases. Previously, this was not possible.
- The experimental constraint rules definitions allow logging messages to be specified in the Inspector window for better tracing and debugging.
- The error message for constraint rules can be targeted for specific nodes’ properties or references. Instead of the error highlighting the whole node, it can be configured to highlight only a property or a reference.
Improved Module Class Loading
MPS modules serve different purposes, ranging from a sandbox to play with your language to an active plugin code to alter MPS or IntelliJ IDEA platform behavior. To address this range of tasks, MPS relied on a few scattered and confusing flags and settings, like SolutionKind, IDEA Plugin Module Facet, Compile In MPS, and many more (see MPS-20726).
In MPS 2022.3, we’ve brought all these under a single umbrella. The Java Facet page for the Solution module was reworked to house all relevant settings and identify common scenarios to help language designers and users easily recognize a module’s intended use. IDEA Plugin Module Facet has been deprecated and will no longer be used. We’ve exposed the settings for Solution modules only – both Language and Generator modules take the same approach, but have their settings configured implicitly.
This is how the Java Facet page from Solution Properties looks now, with a collapsed section at the top, where the “Compile In MPS” flag used to be:
The section expands to reveal different settings to control compilation, class loading, and extension for a module:
“Compilation” determines whether MPS will compile generated sources or if there’s another mechanism that compiles classes and MPS shouldn’t compile anything. Still, MPS assumes there are classes for the module in the case when “External Compiler” is selected. If your module is not expected to deliver classes for MPS use, like for a sandbox or a solution that the generated sources are part of another project, use “None”:
The “Class loader” setting determines whether MPS is responsible for creating a class loader or if classes are loaded by code that contributes a module. One of the most common module contributors is IDEA Plugin. In this case, the “Module Contributor” setting tells MPS to use the IDEA Plugin class loader to access module classes:
The last setting, “Contributes extensions to MPS”, determines whether MPS will try to load its plugins and extensions from the module. This is most common for pluginSolution and is implicit for Languages:
Unless your module provides extensions, keeping the setting on “No” avoids unnecessary overhead from extension look-up. Classes are still available for any code that depends on a solution. Language runtime solutions or a solution with stub models are examples of modules that comes with classes but don’t provide MPS extensions:
There’s also a migration that updates project module descriptors to reflect these settings in an explicit form for all module types, including Languages and Generators. We’ll keep old values (solutionKind and compileInMps attributes) in XML for a transition period until the next MPS release.
Migration sync with MPS extensions
MPS has always had an active community that brings value to the ecosystem and we have always encouraged users to use external libraries to enrich the product’s functionality. Third-party libraries, such as MPS Extensions, have been key to improving the user experience for products built with MPS. Even though this has brought many benefits to the community, there is a significant downside – the user needs to wait for the migration of the third-party library to update the MPS version. We’ve been working together with itemis, our official partner and main MPS extension maintainer, to synchronize our releases for smoother migration to the newest version of the product.
Additional utility methods in the language definition
Language designers can now reduce the amount of repetitive code by extracting it into helper methods right inside the definition root node. These additional methods can be defined in:
- Transformation and substitute actions
- Inference and checking rules
Intentions also allow for additional fields to preserve the values calculated in the isApplicable method to be used in the execute method.
Kotlin stubs for JVM
It ‘s now possible to import stubs from compiled Kotlin/JVM libraries, while it was previously only possible to import Kotlin/Common libraries. With this improvement, it’s possible to use libraries compiled to JVM (Java, Kotlin, or mixed) through the Kotlin JVM model root in your module options.
For example, the Kotlin UI DSL has been loaded as stubs into jetbrains.mps.kotlin.ui.dsl module. While this library was already available as Java classes, this module allows you to reference it using Kotlin.
For a pure Java library, it doesn’t make any difference whether you use Java Classes or Kotlin JVM. The new functionality applies only to using Kotlin in the loaded library.
Kotlin edition improvements
Several minor changes and improvements have been bundled with this new version of MPS:
- Kotlin classes are now rootable nodes and have their own icons.
- Kotlin code can now refer to Java enum entries.
- The this expression can now correctly refer to a label (e.g. this@SomeClass).
- withKotlin flags in build scripts now ask for a $kotlinc_home macro instead of a previously hardcoded location.
- Stubs have been improved:
- Excluding / Including packages in the stub options now functions as it would with Java stubs.
- Several methods with unstable IDs, leading to broken references, have been fixed.
Transformation to create a constructor from a type
It’s now possible to create a constructor call for a given call using a right transformation by typing left parenthesis. This can work for any Kotlin type that supports this operation (this is extensible for user types) and can facilitate creating a default expression for a given type, like when creating a lambda from a functional interface type.
Improvements to extension functions in Scopes
Extension functions were not always handled correctly in scopes, leading to some situations where it was not possible to select the right function.
These scopes have been changed to not exclude compatible methods in scopes. This comes at the cost of having some items in scopes that are not applicable due to the performance of the current type of system implementation.
The automatic resolution of function references can fix references in case a non-applicable function is selected.
Together with this new functionality, we’ve fixed a long list of bugs. Try the new version and give us feedback on our issue tracker. As for every release, don’t forget to review our Migration Guidelines before updating to the latest version.
Your JetBrains MPS team
Subscribe to Blog updates
Thanks, we've got you!