- Language migrations
- Language implementation stripping
- Working with parentheses in BaseLanguage expressions
- Reuse caches option
- In-process execution mode
- JDK8 supported as a runtime
- Module dependencies
- EAP 2
Keep track of language versions and automatically migrate user code to newer language versions
After a language has been published, the language authors should take special care whenever they're changing the usages of deprecated language constructions. It should be possible for the language designer to have some maintenance code run automatically on the user-side, that will change the user's code so that it complies with the changes made to the language. This is called language migration.
MPS 3.2 supports the full language migration story:
- Language designer can write scripts for migrating user code and bundle them with the language
- MPS automatically tracks language versions used in the client code
- MPS runs the necessary migrations, when necessary
- MPS controls that the user's project is up-to-date with all language changes
A couple of examples
Both attached samples contain the same languages and solutions, but show different ways to perform the migration. There are two languages describing a set of dependent "components", one introducing the declaration of a component, and another introducing a "dependency" between components. We suppose that the developer of those languages has introduced a new component declaration and a new type of dependency. Now he wants to migrate old code to new language constructions.
The first example shows how to provide migration information from one script and use it in another. It replaces the old component with the new one and saves the mapping from old node ids to new node ids for further usage from the script, which migrates references.
The second example uses the pattern-quotation migration to do the same thing without persisting any info. This can be done as the pattern-quotation migration saves the ids of the nodes, and we only need to change the reference to a new reference, without changing its target.
Basic language refactorings became transparent
In addition to migrations MPS 3.2 has made simple language changes transparent. It is now possible to instantly rename all meta-level entities, such as languages, concepts, properties, references and child roles. Models using the corresponding languages will not be unnecessarily marked as changed and will work correctly regardless of whether the models have been regenerated.
(This feature is still under development in EAP 1, regeneration of the smodel language queries, generators and quotations is still needed to invoke manually in EAP 1)
New model persistence
In order to be able to use the new migrations and the instant rename refactoring, you should migrate to a new model persistence.
In MPS 3.2 EAP 1, this can be done through Tools->Migrations 3.2->Migrate from Names to Ids.
In the IDEA Plugin, this feature is not available in EAP 1.
Note: After applying this action, you will not be able to use your models with older MPS versions anymore.
Language implementation stripping
Remove language definition from the distributable language plugins to protect your intellectual property
MPS is very open about language definitions by default. The sources of all language aspects, such as the editors or the generator, are bundled with the compiled language artifacts so that users of the languages may easily see all the definitions. While this is a sensible default for open-source projects, there may be situations in life when hiding the implementation could be desired, though. Especially closed-source projects may need to protect carefully their intellectual property contained in the implementation. Their users should still be able to call all the code, but after pressing Control + B they only get to see as little of the definition as possible.
MPS has been for some time already supporting the ability to hide the implementation of classes written in BaseLanguage. You could hide the implementation from the users of your library - they were not allowed to see the BaseLanguage source code of its models if you wanted.
In 3.2 MPS adds the ability to hide the implementation of languages. If you do not want to expose the internal workings of your language, simply set a flag on the build script and MPS will remove the implementation from the generated language definition artifacts. See the details at the dedicated page.
Working with parentheses in BaseLanguage expressions
Manipulate parentheses in BaseLanguage naturally
The fluent parenthesis support in 3.1 was already a great productivity boost. In 3.2 you can work with parentheses in BaseLanguage expressions as seamlessly as you would in a text editor - the editor will always correctly balance the parentheses no matter where you put them, how you nest them or how many of them you create on a node. Check out these short demos (demo 1, demo 2, demo 3) and certainly try it yourself with MPS 3.2.
Save time when running tests
Unit-tests have been optimized, so that in 3.2 the tests performance is several times higher than in 3.1. Also the log message window has become much more verbose, to give you better understanding of what's happening at any moment of test execution.
Reuse caches option
MPS tests execution performance has improved a lot in the new version. Such boost was enabled particularly by reusing the old caches of headless MPS instance when running tests. It is possible to set and unset this option in the run configuration dialog.
Also you can specify the directory to save the caches in. By default, MPS choses the temp directory. Thus with the option "Reuse caches" set on, MPS saves its caches in the specified folder and reuses them whenever possible. If the option is unset, the directory is cleared on every run.
In-process execution mode
MPS 3.2 allows to execute tests in a so-called in-process mode. It was designed specifically for tests, which start another MPS instance in a background process.
(For example, for the language typesystem tests MPS should safely be able to check the types of nodes on the fly. Instead, it used to start a new MPS instance, which took quite a while and slowed down the tests)
In the new version it is possible to run all tests in the same process. Now there is an option in the run configuration dialog to set this behavior. When the option "Execute in the same process" is set (the default setting), the test is executed in the current MPS environment. To run tests in the original way (in a second process) you should uncheck this option.
This way of tests' execution is applicable to all test kinds in MPS. Thus it works even for the editor tests!
Although the performance is so much better for in-process test execution, there are certain drawbacks in this workflow. Note, that the tests are executed in the same MPS environment that holds the project, so there is a possibility, that the code you write in your test may be potentially dangerous and sometimes cause real harm. For example, a test, which disposes the current project, could destroy the whole project. So the user of this feature needs to be careful when writing the tests.
There are certain cases when the test must not be executable in-process. In that case it is possible to switch an option in the inspector to prohibit the in-process execution for that specific test.
JDK8 supported as a runtime
Use JDK8 as a run-time platform for running MPS
The most recent Java runtime Java 8 is now supported as a run-time platform to run MPS.
A completely new strategy for grouping of involved generators into steps. Previous MPS versions used to fit as many generators into the same micro-step as possible, while the new approach prefers to keep every generator as lonely as possible. Eventually, you'll see many more generation steps, although each of them would be shorter and faster to process. Of course, the generators forced to run together with priority rules still run at the same step. Handling a few unrelated generators at the same generation step caused a slowdown, since even a generator that got nothing to do still spent a lot of time checking its applicability condition due to other generators from the same step looking for their part of the job. With in-place transformation, the performance penalty for the extra generation steps is negligible.
Ignored priority rules
In addition to conflicting priorities, there are rules that get ignored during the generation plan. This might happen if an input model doesn't have any concept of a language participating in a priority rule. Since there's no actual use of a language, the rule is ignored, and the 'Show Generation Plan' action reports them along with conflicting rules. Previous MPS versions used to include generators of otherwise unused languages into the generation process, now these generators get no chance to jump in.
Target languages (languages produced by templates) are now considered as implicit 'not later than' rules. You don't need to specify these priorities manually. However, if your generator does some tricks with 'before' and 'after' of the actual target languages, you might face behaviour changes or even a failed generation process. Always check the output of the 'Show Generation Plan' action for possible conflicts and ignored rules.
There are two new dependency scope/kind values in use, 'Generation Target' and 'Design'.
'Generation Target' replaces 'Extends' relation between two languages (L2 extends L1), when one needed to specify that Generator of L2 generates into L1 and thus needs its runtime dependencies. Now, when a language (L2) is translated to another language (L1), and L1 has runtime dependencies, use L1 as 'Generation Target' of L2. Though this approach is much better than 'Extends', it's still not perfect as it's rather an attribute of a generator than of a language. Once Generators become fully independent from their languages, we might need to fix this approach (different generators may target different languages, thus target has to be specified for a generator, not the source language).
'Design' dependency replaces 'Extends' between two generators. Use it when you need to reference another generator to specify priority rules (though consider if you indeed need these priorities, see changes in the Generator Plan, above)
Module dependency calculation for build scripts has been updated to reflect aforementioned scopes. You might face certain unexpected changes in the build scripts.
New serialization format for trace.info files
It is much more concise, the new files are about half of the old size. The old format is now supported for read only, and will be dropped in the next MPS release.
A new kind of "export" labels and "expose" node macros in generator models allows you to describe what a model 'exports' to the outer world. These exports could be queried from a generation process of any other model through "generator context", thus facilitating cross-model information exchange.
Please note that some polish activities are expected to the feature before the final 3.2 release, especially the visual representation might get changed (i.e. the names are not final yet).
Version control support changes
"Merge hints" to resolve conflicts automatically
Sometimes merge conflicts are not so crucial to be resolved manually and it is acceptable to have them resolved automatically somehow, instead of spending time with manual conflict resolution. MPS 3.2 allows properties, links and all properties and links of a concept (or an interface concept) to be annotated with a @mergeHint attribute for this purpose.
The @mergeHint attribute comes from the jetbrains.mps.vcs.mergehints langauage and can be attached to PropertyDeclaration, LinkDeclaration or ConceptDeclaration. By attaching this attribute you tell the merger that in case of conflict on the value of the annotated element it should be resolved by mere using one of the colliding versions ("ours" or "theirs") automatically. If there is no conflict at all - the attribute does not affect the merger behavior in any way.
Automatic resolution of changes in non-conflicting models
Additionally a new "Resolve changes in nonconflicting MPS models" action was added to the Git menu:
This action takes all model files that are marked as conflicted and tries to resolve the conflicts automatically (also using the @mergeHint attribute when necessary). If all conflicts in a model can be resolved automatically, the file is marked as resolved. Otherwise, if some conflicts in the model file cannot be resolved automatically, no changes are made to the model and it is left to manual resolution.
New merge driver
In order to be able to correctly work with the new model persistence you have to install the latest merge driver that comes with MPS 3.2 EAP2.
In addition to previously introduced language migrations, we've added support for so-called project migrations. Project migrations are not triggered by language usages, but instead they define themselves under which conditions they should be run. These migrations are always applied to the whole project.
Migration wizard to convert projects from 3.1 to 3.2
The MPS 3.2 EAP2 comes with a migration that allows the users to migrate from MPS 3.1 to 3.2 seamlessly. The migration includes one project migration and one language migration. When an old project is opened in 3.2 the first time, you should see the migration assistant window popping up. The assistant will let you migrate the project to 3.2.