MPS plugin for IntelliJ IDEA
MPS 2.5 can be run as a plugin for IntelliJ IDEA enabling MPS-based DSLs to be used directly in a Java IDE and so interoperate tightly with the Java code. Custom languages can be exported from MPS as IDEA plugins as well. IntelliJ IDEA became another platform for MPS-based DSLs use, besides standalone Java applications and MPS itself.
There are several aspects of integrating MPS into IntelliJ IDEA:
- MPS Facet + settings (model roots/used languages/output path/...)
- Explore .mps files in IDEA project view -> double-click on root to open editor
- Change model properties (imported models/used languages) by calling popup menu on model file
- Generating code by making the project
- navigate to errors in DSL code reported by generator (make)
- see http://confluence.jetbrains.net/display/MPSInt/MPS+Make+In+IDEA
- two modes of generating files: to different source root or to the same folder next to .mps file
- hiding generated code
- Debugger in IDEA plugin: put a breakpoint into DSL code, run java application and stop on this breakpoint & explore stack trace
- VCS integration
- Actions available in the IDEA plugin
- Navigate to model/module/root (Alt+F1) is similar to MPS
- create complete list?
- Two aspects of working with MPS plugins for IDEA:
- deploying your own languages
- using one of languages distributed with MPS
- MPS plugin distribution description (plugins + possibility to switch then on/off)
The Dependencies Analyzer can report dependencies among modules or models. It can be called from the main menu or from the popup menu of modules/models:
The interactive report, shown in a panel at the bottom, allows the user to view usages of modules by other modules. The panel on the right side displays modules and models dependent on the module selected in the left-hand side list.
Module Dependencies Tool
With this tool it is possible to overview all the module (or set of modules) dependencies and used languages, detect cyclic dependencies as well as see in details paths that lead to the given dependency. The tool can be invoked from the project pane when one or more modules selected there.
Module Dependency Tool shows in the left panel all transitive dependencies of module and optionally all used (directly or indirectly) languages. It is possible to expand any dependency node and get all dependencies of the expanded node as children. These will be again transitive dependency but for the expanded node.
Select one of dependency nodes or set of nodes in the left panel. Right panel shows paths to the each selected module from its "parent" module. You can see brief explanation of each relation between modules in the right tree. It can be depends on, uses language, exports runtime, uses devkit, etc. For convinience the name of the target dependent module is shown in bold.
There are two types of dependency paths: Dependency and Used Language. When you select module in the Used Language folder in the left tree right tree shows only dependency paths making "used language" relation for the given module. To show "ordinary" dependencies on language as a module you should choose it out of Used Languages folder (like jetbrains.mps.lang.core in the picture below). It is possible to select several nodes (e.g. the same language dependency inside and outside Used Language folder), then you get union of paths.
If you want to track not only "visible" but also runtime dependencies you should check "runtime" option in toolbar. Only runtime dependencies are marked with "(runtime)" comment in the left tree.
By default dependency paths are shown in "from the shortest to longest" order. But there are still paths that are not shown: paths with the same tail part as one of the already shown path. It is still possible to see all such paths in the right tree with the "Show all paths" option. Only starting (distinct) part of path is shown, symbols "... -->" mean that there is continueation of the path already shown in the tree; you can follow path by double clicking its last element.
Modules participating in dependency cycles are shown in red color in the left tree. It is possible to see paths in cycle by selecting module dependency equal to parent or for convinience by using popup menu:
For some types of dependencies it is possible to show usages or safe delete with popup menu. For "depends on" (dependency without re-export) Dependencies Analyzer will be invoked on Show Usages.
Changes in Refactoring language
UI for getting refactoring parameters now is removed from refactoring language. Now choosers for parameters are not called, it is not allowed to show UI in
ask boolean), keystroke has no effect. All this functionality should be moved to an action correspondent to the refactoring.
The following constructs added to the refactoring language:
is applicable refactoring<
returns true if refactoring target corresponds to the current target (type, single/multiple) and applicable as in refactoring
isApplicablemethod, and there is no refactoring that overrides current refactoring for this target.
executes refactoring for target with parameters
create refactoring context for refactoring, target and fill parameters in context, this context then can be used for refactoring execution or for further work with parameters; UI is not shown during this call
It is necessary to manually migrate user refactorings. Migration consists of
- create action for refactoring
- copy caption, create context parameters
- add refactoring keystroke with the newly created action to KeymapChangesDeclaration
- create ActionGroupDeclaration for refactoring that modifies jetbrains.mps.ide.actions.NodeRefactoring action group at default position
isApplicableclause to the action created; usually it is just
is applicable refactoring< >
executeclause to the action created; all the parameter preparations that were in
initof refactoring should be moved here; at the end it is necessary to execute refacoring with prepared parameters (with
execute refactoring< >
- remove all parameter preparation from
initof refactoring, they should be ready on entry to
init; you can still validate parameters and return false if validation fails
It is possible to suppress errors in editor (and in model checker) now.
If node is instance of a concept which implements ISuppressErrors interface, then all errors in this node and it's children won't be shown. For example comments in baseLanguage implement ISupressErrors.
It is also possible to define child roles, where errors should be suppressed, by overriding interface boolean method suppress(node<> child).
Also if node has attribute of concept implementing ISuppressErrors, errors in such node will be suppressed too.
There is default implementation of ISuppressErrors node attribute. It can be applied only to nodes that are instances of ICanSuppressErrors.
Here is an example of using this attribute and corresponding intention:
There is an error in editor:
BaseLanguage Statement imlpements ICanSuppressErrors, so user can apply highlighted intention here:
Now the error isn't highlighted, but there is a cross icon in the left pane. SuppressErrorsAttribute can be removed either by pressing on that cross or by applying corresponding intention
Extensions provide a possibility to extend certain aspects of a solution or a language, which are not covered by the standard language aspects and the plugin mechanisms.
Support for extensions exists in
- plugin solutions
- Create an extension point
- Create one or more extensions
- Both must be in the plugin model
- Each extension must provide a get method, returning an object
- Each extension may opt to receive activate/deactivate notifications
- An extension may declare fields, just like class
The language jetbrains.mps.lang.extension declares concepts necessary for building extensions.
ExtensionPoint concept represents an extension point. The extension object type must be specified as a parameter.
Extension concept is used to create a concrete extension.
Accessing extension point
An extension point can be accessed by reference using extension point expression.
Accessing extension objects
An extension point includes a way to access all objects provided by its extensions.
Extension points and extensions are managed by the ExtensionRegistry core component.
Saving Transient Models Status In The Status Bar
A button in the status bar allows to enable and disable saving transient models with one click.
If transient nodels saving is enabled, this button shows a notification popup when generation starts.
Popup can be disabled in Settings -> IDE Settings -> Notifications -> Saving Transient Models Is On.
New XML language
Custom persistence for MPS models
Make process improvements
- Faster ANT generate task; no dependencies on the idea platform
- Table selection improvements (check if it was done in 2.5)
- Table column selection
- .hash# files are not generated anymore
- new generator macros (if any?)
Collections language improvements
Build language redesigned
- Cross-project variables support
- Base-directory management in buildScript
- Project dependency management
MPS.Classpath was split into: MPS.Core, MPS.Editor, MPS.Platform and MPS.Workbench
- Moving code from plug-in aspect to separate solutions
- Solution types (plug-in/core/editor)
More reliable merge conflict handling
- MPS plugin structure/ability to switch on/of some parts of MPS by disabling plugins.