In this post I‘m sharing some of our experiences from updating to MPS 2018.3 in various codebases. I did the migration in three projects: the MPS Extensions, mbeddr and IETS 3. The final version of MPS 2018.3 is now release for about a week.
The migration in all three projects is done. All projects compile against the lastest version of MPS and all migrations were executed. Some of the projects still contain model checking errors because of new checks introduced in the update but the generated code works. For all except one the fixes are straight forward, but some are hard to automate. This post is also not a complete list of all API changes in the tool, its meant as an overview about the different activities during them migration and mentions changes that were significant. I won’t list all the low level API change that you might encounter when you‘re building something like the MPS extensions that integrate on a very low level and depend on a lot of its internals. If you are primarily a user of MPS and building languages with it then this post should give a good impression on what has changed.
Compared with previous releases the changes to most APIs are minor. No big refactoring, like for instance the new transformation menu language that replaced the actions, are included in this release. The new features are all adding to MPS and not replacing existing ones.
The change that caused the biggest manual work was by far the removal of the
IconManager. It was deprecated for years but it‘s usage, even in newer parts of the codebase, was still significant. One problem was that most of the parts in our codebase were using the stub build from MPSs Jar files. Stubs build from Jar contain the
@Deprecated annotation but do not import the deprecation message, which in this case had the information on how to replace the deprecated class. While MPS also ships the same class as the original model with the details on how to replace it, this information was largely not available because the stubs were used.
Replacing the individual use cases was mostly substituting
GlobalIconManager.getInstance().getIconFor(x). Some other were a bit harder to replace, especially when icons were loaded from files or jar files as resources. You can take a look at this commit in IETS 3 for more details.
Read/Write Actions and Commands now require a
Repository to execute. For the past two MPS versions not passing the repository was a warning. While the generated code still complies and seems to execute just fine, I guess in on of the next MPS versions this will change. We haven‘t finished migrating all of our usage yet but it seems straight forward in most cases. I was looking into a way to automate this refactoring but I seems hard to do in many cases.
This only affects you if you are generating MPS test cases from your models. More specifically if you are using
BaseTransformationTestCase as a base class for your tests. In previous versions all tests were executed in a read action or command by default. The logic was hard coded in the test runner. Now this behavior is controlled by JUint
Rules. For more information see this commit.
A longer standing issue with error reporting for model checking errors was fixed. The error cause model checking messages not to show under certain condition, especially when they were attached to parts of the node that is shown in the inspector. The errors would only show up in the model checking window but never cause errors markers to appear in the editor. The fix for this change cause some confusion in our code base because we were observing lots of errors in our build scripts after the update to MPS 2018.3. We first thought the problem was related to changes in the build language but after some help by Alex from JetBrains team we were able to identify the problem. Turned out the fix was pretty simple, simply adding a new import to the module containing our build scripts did the trick.
MPS 2018.3 introduces a couple of new features and you can find about them here. I would like to highlight two changes from the list and how we plan to use them in the future, especially in the MPS extensions.
A feature that’s not explicitly included into the announcement: the TextGen aspect of a concept can now return a path instead of just a file name. This is used for new feature that allows generating different package for Java but it’s also available for other TextGen definitions. While it doesn’t allow to control the output location from a generation plan directly, it allows some control over the output location form the TextGen aspect. We are hoping to see further improvements in this area in future versions of MPS, e.g. output location control with
fork operations in a gen plan.
We plan to provide some community guidelines on how to use the TextGen path feature through the MPS extensions in generic way. As a short term plan we want to add a new node attribute/annotation to the MPS extensions that allows storing the output location. This annotation is then used in the TextGen implementation to determine the path for the file. We will provide documentation on the semantics of the annotation and how it apply it.
Currently no pull request for this is open but we are looking to implementing this soon. We hope to see some adaption of this annotation in the MPS community when a language feature a TextGen in order to have a common way of influencing the output location across languages.
Plugins for Tests
A long standing problem when executing tests from MPS was: how to tell the test environment which plugins are required. MPS tried to figure out the list of plugins automatically from the build scripts, but in some cases this wasn’t working as expected and various workarounds existed.
From now on you can specify addition plugins, that are required during the test execution, directly in the build script. We are looking forward to clean up some of the mess we had in our test build scripts in the near future with this feature.
The biggest learning for us was: we have to get faster in removing deprecated code usage. Not just because the usage itself, but also because the code is read by other people and might get used as a blue print to solve similar problems. Reusing the code that was used deprecated concepts caused the usage to spread through a large part of the code base. MPS has added support for finding some of these cases in the current release, which will help to raise awareness. In addition we are putting bigger efforts on deprecated code usage into our code review and prevent adding new code that uses deprecated concepts from MPS.
Other breaking changes, like the test execution, were of minor impact and ,while required some work, the new implementations often give us more flexibility when extending MPS.