What’s New in MPS 2023.2

MPS 2023.2 brings improvements to BaseLanguage lambda generation, JUnit 5 support, type system inference rule overriding, and more.

Support for JUnit 5

JUnit5

Tests in MPS are now generated as JUnit 5 tests. Limited support for JUnit 4 is still provided.

  • Any appropriately annotated Java class can be executed as a test.
  • Both options for running MPS tests – in-process and spawned – are available.
  • Existing test roots are generated with JUP Jupiter API annotations:
    • BTestCase
    • NodeTestCase
    • EditorTestCase
    • MigrationTestCase
    • PatternTest
    • GeneratorTest

Ant task for launching module tests with JUnit 5

A new launchtests Ant task is available with support for the following elements:

  • library
  • macro
  • plugin
  • testmodules

It supports the execution of all test artifacts, with the exception of JUnit 3, and serves as the new target for the test configuration build part.

Executing tests from MPS

  • Any Java class appropriately annotated can be executed as a test.
  • There is now only limited support for JUnit 4.
  • Both in-process and spawned executions are possible.

Test platform API

This API allows you to extend the types of tests available in MPS, as well as implement listeners for test sessions.

Classes in jetbrains.mps.baseLanguage.unitTest.platform form the MPS test platform API:

TestPlatform Defines the API for the MPS test platform.
TestDescriptor Represents a single test on the MPS test platform.
TestSource Represents the test source, such as an SNode.
TestSession Represents a test session.
TestDiscoveryParticipant Enables joining the test discovery process.
TestSessionListener Makes it possible to receive notifications from the test session.

Experimental support for custom test engines

JUnit 5 introduces, among other things, support for implementing tests that are executed with a custom engine. A popular example of such an engine is jqwik – a property-based testing framework.

Enhanced support for overriding type system rules
Client sponsored

TS Overriding

We recently added a feature that allows type system rules to override rules defined on super-concepts. This can be done in cases where the sub-concepts are defined in a language that extends the language containing the super-concept. The feature is supported for Inference rules.

BaseLanguage improvements

In an earlier update, MPS received enhanced support for method references and the conversion of closures into Java lambdas. We’ve broadened this support with numerous minor features and bug fixes.

Lambdas

Generation of closures as lambdas

Closures used in collection operations are now generated as Java lambdas, which was initially available only for regular function calls that used Java interfaces. To maintain backward compatibility, there are instances when a closure will still be generated as an anonymous class:

  • When a variable name clashes with an external variable – a warning is now displayed suggesting it be renamed.
  • When the target Java version is 8 or below.
  • When raw types are used – these do not function well with Java lambdas.

Generally, this results in the improved quality of generated code, as lambdas, apart from being more readable, are less likely to be generated incorrectly. On the other hand, MPS allows features with raw types that Java would not allow, as detecting such instances is still challenging. As a result, in locations where raw types are employed, generation may fail.

Closure Param

Closure parameters

Closure parameters previously had various possible forms: ~param, <type> param, param, and var param. Adding parameters while skipping the type was cumbersome. In this release, we’ve deprecated the ~param form in favor of the simple untyped parameter, which is now inserted by default. Also, when a closure is inserted in a function call, default parameters will be inserted from the expected function type. Lastly, if their type is omitted in the source code, the generated parameters will now omit the type, thereby further enhancing the compilation quality.

Streams

Stream interoperability

While sequences are used extensively in MPS, there are occasions when Java streams must also be used. This update offers improved inference to mitigate type system issues related to complex methods that the Stream API may use. We’ve added two operations to bridge streams and sequences:

  • <stream>.asSequence will convert a sequence to a stream.
  • <sequence>.toStream(parallel=…) will do the opposite.

In addition to allowing you to choose which API to use, this allows you to combine the benefits of sequences (repeatability) with those of streams (various collectors, more operators).

Collection improvements

We previously introduced the diamond operator (new ArrayList<>()) for BaseLanguage constructors, but collection creators were excluded from this improvement. In this update, you can now omit type parameters from new collections, simplifying the code-writing process:

  • Type inferred from initial values: var myList = new arraylist<> {myInitialValue}
  • Type inferred from variable declaration: map<int, string> myMap = new hashmap<>

In addition, we’ve improved support for variance in collections. For example, it’s no longer possible to assign a ? extends Number notation. However, the type system will no longer object to the use of such bounded types when they are valid. The sequence<> type will remain covariant by default, as it won’t result in any unsafe consequences since you cannot insert it into a sequence of elements that are not of its type. This may bring new type-checking issues where unsafe code previously went undetected. These can be resolved with either bounded types list<? extends node<>> or sequence types sequence<node<>>.

Configuration settings

Disable Make

Disable Make On Startup

We’ve added a new option, Disable Make On Startup, which is available in Settings | Project Settings | Make. When this option is selected, MPS will not make all of the project’s modules when starting up. This may come in handy if you want to increase startup speed in situations when the initial make process takes too long or is likely to fail since manual configuration is necessary before the project can be successfully made.

Edit Library

Edit library and source paths under module Java properties

A new Edit option was added to the Java tab of the module properties dialog. It’s hard to spot, but very convenient. When you need to alter the set of your module’s jar libraries, just use this new option, and you won’t have to perform a tedious sequence of an entry removal followed by an add.

Other

TODO Comment

The TODO ability for custom comments

Extending the IGenericComment concept allows concepts that represent comments in custom languages to participate in the TODO functionality of MPS. Comments that represent TODOs will be collected by the TODO Finder, listed in the TODO Viewer, and checked during the commit process.

Language aspects: manage Create New actions

For creating instances in an aspect model, MPS has so far followed a general logic that involved rootable non-abstract concepts, ordered by name or flag. Now optional configuration can be specified along with an aspect declaration, allowing language designers to control which concepts are presented to the user, as well as their grouping and ordering.

“Please re-export dependency…” check now obsolete

This confusing warning used to be shown when a ClassConcept extended or otherwise exposed its use of a ClassConcept from another module. Prior to version 2023.2, MPS relied on module dependencies specified in module descriptors to build the dependencies graph. Now that MPS builds the dependency information based on the actual generators and languages involved in transforming a model, you no longer need to specify these dependencies explicitly, hence there’s no more need for the check.

Client-sponsored features ported from older releases

Sharing is a useful trait of any community. The following features have been implemented based on requests from the commercial MPS users who sponsored us developing them. Now, you can also take full advantage of these handy additions.

Parallel model checker

The model checker can now effectively utilize parallel hardware, thereby speeding up the process of model checking. Depending on the settings in Settings | Tools | Model Checker, it can spawn multiple threads when starting this process.

Improved File-per-root persistence performance

The FilePerRootDataSource.getStreamByName() method has been optimized to improve the performance of model data loading. If you use File-per-root persistence to store rather large models, this change will be noticeable.

Find dialog

Improved support for Find text in project

The existing Find text in project action has been improved, and it now also searches for references of named nodes, bringing up additional relevant results. A preview panel has been added that allows you to see the results directly in the search dialog. Text containing HTML content is now rendered as plain text in the results and not as HTML as in previous versions.

Skip dependency migration in Ant tasks

While migrating a project using Ant tasks provided by MPS, dependencies may not get properly migrated. We added a flag to continue the migration of a project even in such cases. Stopping the migration process as soon as a non-migrated dependency is discovered remains the default behavior. To use this flag, add haltOnDependencyError="false" to your migrate Ant task.

Platform updates

Full IDE zoom

In v2023.2 it’s possible to zoom into and out of the IDE entirely, increasing or decreasing the size of all UI elements at once. From the main menu, select View | Appearance and adjust the IDE’s scaling. Additionally, you can assign custom shortcuts for calling these actions in Settings/Preferences | Keymap | Main Menu | View | Appearance.

New Remember size for each tool window setting

In MPS 2023.2, we’ve introduced a new layout option that allows you to unify the width of the side tool windows or retain the ability to freely adjust their sizes as you customize your layout. The new Remember size for each tool window checkbox is available in Settings/Preferences | Appearance & Behavior | Appearance | Tool Windows. Learn about how this setting works for the new and the old UI in this blog post.

Syntax highlighting in inspection descriptions

Syntax highlighting in inspection descriptions

In Settings / Preferences | Editor | Inspections, code samples now include syntax highlighting, which makes it easier to understand what triggers an inspection and decide whether you want it to be active or inactive.

Fill Paragraph for Markdown files

Fill Paragraph for Markdown files

The Fill Paragraph editor action is now supported for Markdown files, allowing you to break long texts into several lines of even length. To do this, set the caret inside the paragraph you want to edit and search for the Fill Paragraph command using Find Action (Ctrl+Shift+A).

Improved Branches popup

Improved Branches popup

We’ve improved the usability of the Branches popup. For instance, navigating between branches is now easier, as they are grouped and stored in expandable lists.

Auto-completion in the Create New Branch popup

Auto-completion in the Create New Branch popup

MPS 2023.2 provides auto-completion in the Create New Branch popup. Once you start typing a name for your new branch, the IDE will suggest relevant prefixes based on the names of existing local branches.

Migration Guide

For every major release, we prepare instructions on how to migrate from older MPS versions to ensure everything goes smoothly. Please review them carefully.