-
Notifications
You must be signed in to change notification settings - Fork 77
MPS: Deps and Classpath
In this document, we describe the meaning and effect of different types of dependencies within MPS, including the effects on the applicable Java classpath. We describe both the expected state and all bugs deviating from the expectations, as of MPS version 3.1.4 (build #MPS-135.1441). We mention expected changes for version 3.2.
Table of Contents generated with DocToc
- Overview
- Terminology and UI for Access
- MPS Plugins
- Plugin Disambiguation
- Non-Project Sources
- Java Classpath vs. Relations
- Dependencies
- Used Languages
- Executed Generators
- Generated Relations
- Tests
-
Recipes
- Use Java Type
- Reuse (aka extend, reference) External Java Type
- Create Concept Instance
- Use Intention
- Use Typesystem Rule
- Use alternate Editor with Hint
- Assure Generator is Executed for a Model
- Use
node<SomeConcept>
Type - Call Behavior Method
- Use Concept as Child or Reference
- Extend Concept or Implement ConceptInterface
- Create Editor
- Create Editor Component
- Use Editor Component
- Create Typesystem Rule
- Create Intention
- Create Generator
- Extend Generator
- Generate Java Class extending a Base Class
- Define Runtime Solution
- Define Accessories Model (aka make Concept Instances available everywhere a Langauge is Used)
- Create Utility Model (aka create complex implementations for Behavior Methods or Generators)
All content known to MPS is contained in its Modules Pool.
The Modules Pool is filled from Modules in the current Project and all Non-Project Sources.
MPS in general cares about dependencies between Modules. The dependencies on Models only constrain further the dependencies of the Modules.
There are two main types of Relations: Dependencies are needed for any reference to something in another Module. Used Languages are needed to use something defined in a language. We refer to Relations if we address both types.
Other types of dependencies on Modules include Java Stubs (in combination with Java Libraries), Java Source Stubs (in combination with Java Source Paths), Runtime Solutions and Accessory Models (only available for Languages), and Languages Engaged on Generation.
Build Models abstract Ant files to build and package Modules and IDEA Plugins. They contain a copy of the Relations defined in the Modules, and dependencies to other Build Models and IDEA Plugins.
This section lists the main terms used in this document, including a brief description, their relation to other terms (also via document structure), and the place in the MPS IDE where to access it.
We capitalize all terms with specific meaning to MPS.
UI: File menu
All global and project settings.
Settings applied to all projects opened with this MPS installation. Stored in
Windows:
C:\Users\«username»\Application Settings\.MPS31
Linux:
~/MPS31
[AS]: is it ~/MPS31 or ~/.MPS31?
Mac:
~/Library/Application Support/MPS31
~/Library/Caches/MPS31
~/Library/Logs/MPS31
~/Library/Preferences/MPS31
UI: Entry in Settings Dialog
Variables pointing to some place in the file system. For any path selected in MPS contained within one of these Path Variables, the path is stored relative to the variable.
Known pre-defined Path Variables:
-
${module}
Containing Module -
${user.home}
Current user home directory ??? -
${language_descriptor}
Directory containing the Language Module ? -
${solution_descriptor}
Directory containing the Solution Module ? -
${project}
Directory containing the Project -
${mps_home}
Installation directory of this MPS installation
Do not point Path Variables to a sub-path of another Path Variable, as MPS will always apply the first (pre-defined before user-defined, user-defined in order of definition) one matching.
INVALID example:
Path Variable a --> /some/dir
Path Variable b --> /some/dir/below
UI: Entry in Settings Dialog
Paths recursively scanned for Modules.
More info: Non-Project Sources, Path Variables, Project Libraries
UI: Entry in Settings Dialog
A packaged set of contributions to the IntelliJ IDEA Platform, which MPS is based upon.
Contained in one of the following places:
${mps_home}/plugins
«GlobalSettingsDir»/plugins
There are also other things called plugins, known as MPS Plugins, bearing no relationship to IDEA Plugins. However, MPS Plugins can be packaged into IDEA Plugins, just as any other content of MPS.
More info: Non-Project Sources, Global Settings, Path Variables, IDEA Plugin Module Settings, Plugin Disambiguation
UI: Entry in Settings Dialog
Settings applied to one project. Stored in ${project}/.mps/
.
More info: Project, Path Variables
UI: Entry in Settings Dialog
Paths recursively scanned for Modules.
More info: Non-Project Sources, Path Variables, Global Libraries
UI: Second root entry in Logical View
All content known to MPS is contained in its Modules Pool. This Modules Pool is shared between all windows of the same MPS installation. In some future MPS version, every window should have its independent Modules Pool.
If a Module is contained more than once in the Modules Pool (eg. present both in the current Project and in a Global Library), the behavior is undefined (ie. will mess up badly, don't do this).
More info: Module
UI: If already open: Window menu; New: File menu, Open..., New Window
Every Project is contained in its own window.
More info: Project
UI: First root entry in Logical View
Collection of Modules. A Module can be part of more than one Project. They can be added via "Project Paths" context menu entry of the Project.
Modules can be nested in folders. These folders are stored in the project, ie. the same Module can be in different folders inside different Projects. Folders are only for visual organization, they don't have any effect on storage location, generation or anything else.
More info: MPS Window, Module, Project Settings
Unit of deployment and dependency for Something[^1] with defined relations to other Modules.
[^1]: "Something" denotes anything that can be contained in a Module.
More info: Modules Pool, Project
UI: Entry below Project in Logical View; may be nested in folders
Standard container for Something.
More info: DevKit, Dependencies, Used Languages
Runtime Solutions are regular Solutions with additional semantic meaning: They are defined as Runtime Solution at the Runtime Language Settings. They contain Java code that should be available at run-time if the Language is used.
More info: Language
UI: Entry below Project in Logical View; may be nested in folders
Container for defining a new Language within MPS. Also contains Generators, but this is mostly for historical reasons.
More info: Generator, DevKit, Runtime Solution, Runtime Language Settings, Used Languages Module Settings, Used Languages Model Settings, Aspects, Accessories Models, Utility Models, Plugin Disambiguation, Extends Language Scope, Implicit Generator Dependencies, Implicit Language Exports, Implicit Runtime Exports, Cyclic Dependencies, Used Languages
UI: Entry below Language in Logical View
Container for defining how to translate one kind of Nodes into another kind of Nodes.
More info: Language, Generator Priorities, Generator Models, Transient Models, Utility Models, Languages engaged on generation, Scope, Extends Generator Scope, Implicit Generator Dependencies, Implicit Runtime Exports, Used Languages, Executed Generators, Generated Relations
UI: TODO
Collection of Solutions and Languages to be used in combination.
TODO: Extend
UI: Context menu of Module, Module Properties
Settings applicable to the Module.
UI: Tab in Module Properties dialog
Sources of Something. For all of them, we select or add the source type on the left-hand side and set its source on the right-hand side. The selected directory and all sub-directories are scanned for appropriate content.
-
(default)
Model files edited in MPS -
java_classes
External contents of Java Classpath; contents of jar files are considered. MPS builds Java Model Stubs for all Java class files found in order to reference them inside MPS.To be able to compile code against these stubs, we need to add the jars to the Java Libraries as well.
-
obsolete
As named. Don't use it. -
java_source_stubs
External Java source files. MPS should build Java Model Stubs from these, but does not do so currently (bug)In order to make MPS compile this code and compile other code against these stubs, we need to add the path to the Java Source Paths as well.
More info: Java Module Settings, Non-Project Sources, Path Variables
UI: Tab in Module Properties dialog
Other Modules this Module has a reference to.
-
export
Whether this Dependency should be re-exported.Available only for Dependencies in Default Scope.
-
Scope Scope of the Dependency.
-
Default
Standard Scope. Only Option available for Solutions. -
Extends
Extends Scope. Only available for Languages and Generators.See below for a discussion of the meaning of Extends Scope.
-
More info: Export Flag, Model Dependencies, Dependencies
UI: Tab in Module Properties dialog
Languages used in this Module.
See below for a discussion of the meaning of Language Used.
More info: Language, Model Used Langugaes
UI: Tab in Module Properties dialog
Settings concerning Java compilation of this Module.
-
Solution Kind
Whether Java classes of Module (compilation results) should be available for ClassLoading. Such modules can contain MPS plugins in order to be notified about module ClassLoading initialization and de-initialization.If a Module is loaded automatically, it's scanned for MPS plugins to be started at their defined event.
-
None
Module will not be loaded automatically. -
Core plugin
Module will be loaded automatically.The Module should not contain any references to the MPS editor, MPS UI, or MPS platform. Such module is intended to be compiled without MPS editor classes available in the classpath. On MPS startup time, editor classes can be unavailable within the classpath of such module.
We currently don't know about any use case for this Solution Kind.
-
Editor plugin Module will be loaded automatically.
The module should not contain any references to the (MPS UI ??), or MPS platform, as it's started before these are available.
This Solution Kind should be selected if this plugin is required in Editor Tests.
-
Other plugin Module will be loaded automatically.
The module should not add anything to MPS Editors, this might break Editor tests on the build server.
Select this Solution Kind if we want this Module to be loaded automatically with no other restrictions.
-
-
Source Paths
Paths containing Java source files to be compiled by MPS.The Path also needs to be added to java_source_stubs in order to be available as MPS models containing BaseLanguage concepts representing the content.
-
Libraries
Paths containing Java classes and other resources available on the Java classpath during compilation.When we add something here, a dialog pops up asking about Model Roots. This dialog should add the appropriate entry to the Common Module Settings. However, this is currently broken (bug). Therefore, we need to create the java_classes entry on our own.
More info: Plugin Disambiguation
UI: Tab in Module Properties dialog
Extensible list of facets available for a Module.
-
Idea Plugin
Sets the parent Java classloader for this Module to the classloader of the IDEA Plugin referenced on the IDEA Plugin Module Settings. -
Java
Unused marker facet. Always checked. -
tests
Unused marker facet. Always checked.
More info: IDEA Plugin, Plugin Disambiguation
UI: Optional tab in Module Properties dialog
Settings for parent IDEA Plugin of this Module.
Needs to be activated on the Facets Module Settings.
-
Plugin ID
ID of the parent IDEA plugin.parent means, this solution will be packaged as a part of the specified IDEA plugin. As a result the parent ClassLoader for the ModuleClassLoader of the corresponding solution will be a ClassLoader of specified IDEA plugin, so all classes packaged as a part of corresponding plugin will be available within ModuleClassLoader of this solution.
On the development time one can run build script building complete IDEA plugin, deploy in into the current MPS instance using special Run configuration and continue developing a solution inside the current project. In this case actual solution content from the current project will be used. For more details see MPS Documentation, especially "Debugging the plugin" part.
More info: Plugin Disambiguation
UI: Tab in Module Properties dialog of Language
Settings for Solutions and Models with special meaning for the Language.
-
Runtime Solutions
Solutions containing Java code that should be available at run-time if the Language is used. -
Accessories Models
Models containing Nodes that should be referable if the Language is used.
Refer to Implicit Exports of Runtime Language Settings for a discussion on the effects.
UI: Tab in Module Properties dialog of Generator
The general mechanism of these settings is out of scope of this document. In our scope, we note that any other Generator referenced in these settings needs to be added to the Dependencies tab with Extends scope.
More info: Generator, Extends Scope for Generators
UI: Entry below Module in Logical View; may be nested in folders
Container for model contents limiting dependencies to other Models within the boundaries of the containing Module.
Models can be nested in folders. Folders are only for visual organization, they don't have any effect on storage location, generation or any other aspect.
More info: Module
MPS knows several different types of Models. They differ in their semantics and sometimes presentation. They do not differ from a technical point of view.
UI: Entry below Solution in Logical View
Contains Root Nodes with no special semantics or presentation.
More info: Solution
UI: Entry below Language in Logical View
Aspects are Models within a Language with a special meaning. They are recognized by their name.
More info: Language
Although this Aspect adheres to the MPS Plugin Model naming convention, it should not be used as such. It should only be used to define MPS Extention Points (from Language jetbrains.mps.lang.extension
).
More info: Plugin Disambiguation
UI: Entry below Solution in a special folder named "tests" with special icon in Logical View
Model containing tests. Defined by @tests
Stereotype.
UI: Entry with special icon below Generator in Logical View
Model containing Generator. Defined by @generator
Stereotype.
UI: Last entry below Project in Logical View
Temporary Models produced during generation. Defined by @transient«someNumber»
or @«someNumber»
Stereotype.
More info: Generator
#####Accessories Model UI: Entry below Language in a special folder named "accessories" in Logical View or Entry below Solution in Logical View
Model specially selected by a Language. Nodes contained in these Models are implicitly available on the Java classpath and the Dependencies of any Model using this Language. A use case would be a default library of Concept instances to be available at any place the Language is used.
Accessories Models can be stored at two places: Either as Aspect of a Language (recommended), or as regular Model below a Solution. In both cases, the Model needs to added to Module Runtime Language Settings.
UI: Entry below Language in special folder named "util models" in Logical View
Contain code required in other parts of a Language or Generator, eg. if a Behavior method logic is too complex for inline implementation or a Generator needs to do complex model traversals. They should be created as regular Model within the Language.
More info: Language
UI: Entry below Solution in Logical View
Contains Nodes from Build Language.
UI: Model within a Solution in Logical View
Contains MPS Plugins.
The model name needs to adhere to the naming convention «moduleName».plugin
.
More info: Plugin Disambiguation
UI: Attached to the Model name, separated by "@"
A Model may have a Stereotype. To change, add, or remove a Stereotype, use the Rename Model Refactoring in the context menu of a Model.
Using custom Stereotypes has been reported to interfere with lots of MPS internals and thus is not advised to do.
MPS knows some predefined Stereotypes with special meaning:
- @tests: Denotes Test Models
- @generator: Denotes Generator Models
- @transient«someNumber» or @«someNumber»: Denotes Transient Models
UI: Context menu of Model, Model Properties
For both Dependencies and Used Languages, the settings on Models only restrict the settings from the containing Module.
UI: Tab in Model Properties dialog
Other Models this Model contains references to.
More info: Module Dependencies, Dependencies
UI: Tab in Model Properties dialog
Languages used in this Model.
See below for a discussion of the meaning of language used.
Any Used Language listed in a Model needs to be in the list of Used Languages of the containing Module.
UI: Tab in Model Properties dialog
Other settings for a Model.
-
Languages engaged on generation
Generators contained in Languages listed here will be executed on this Model in any case.
More info: Executed Generators
Abstracted Apache Ant files used to build and package MPS Modules outside the IDE.
Used in Build Models.
Can be executed within MPS via the "Run '«Build Model name»" context menu entry of the Build Model in Logical View.
UI: Section within Build Model
Plugins to the Build Model language providing new entries for Build Models (eg. "generator options", "idea plugin"). These are not regular MPS Generators, but non-extendable plugins outputting Apache Ant XML.
Users may provide their own plugins.
Built-in plugins are:
-
java
Support for pure Java -
mps
Support for MPS Modules -
module-test
Support for running tests including MPS Modules
More info: Plugin Disambiguation
UI: Section within Build Model
Scope import for all references to other Build Models.
Provides access to resulting artifacts of other Build Models.
UI: Section "project structure" in Build Model, subsection "idea plugin", subsection "dependencies"
Contents of IDEA plugin.xml depends
tags.
This plugin will only be loaded if all dependencies listed here could be loaded before. The contents of dependencies are available for this IDEA plugin.
More info: IDEA Plugins, Plugin Disambiguation
UI: Section "mps group" in Build Model, subsection "solution"/"module", Inspector section "dependencies"
Copy of Relations of described Module.
More info: Module Dependencies, Module Used Languages
Copy of Module Runtime Language Settings.
UI: Section "default layout" un Build Model
All jars included in any Java Module Settings need to be included somewhere in this section.
.java files (from Java Source Paths) need to be compiled as java sources inside corresponding build script and manually included into the resulting build layout: corresponding .class files should be jared, .java files should be places in corresponding location if they are referenced by java_source_stub model root.
MPS Plugins are automatically loaded according to the Solution Kind set in Java Module Settings.
MPS Plugins need to be contained in MPS Plugin Models.
More info: Plugin Disambiguation
We need to add a StandalonePluginDescriptor (defined in Language jetbrains.mps.lang.plugin.standalone
) as Root Node to any MPS Plugin Model using a Concept from Language jetbrains.mps.lang.plugin
. Other concepts from Language jetbrains.mps.lang.plugin.standalone
don't need a StandalonePluginDescriptor.
The term "plugin" is used at various places throughout MPS. It describes very different things:
-
IDEA Plugins: A packaged set of contributions to the IntelliJ IDEA Platform, which MPS is based upon.
-
MPS Plugins: Automatically loaded Models.
-
Plugin Language Aspect: Model inside a Language defining Extension Points.
-
Build Model Plugins: Part of Build Model language providing new entries for Build Models.
Non-Project Sources are
- Global Libraries
- IDEA Plugins
- Project Libraries
- Common and Java Module Settings regarding Java classes and Java source files
- IDEA Plugins referenced by a Module
These directories or Jar files are recursively scanned for *.mpl
(Languages), *.msd
(Solutions), and *.devkit
(DevKit) files. If found, the corresponding content is added to the Modules Pool.
Both the Java Classpath and the Relations of a Model are specified by the various settings on Models and Modules. However, these settings affect Classpath and Relations in a different way.
As a rule of thumb, the Classpath contains all Java classes reachable through any kind of relation, ie. the Classpath is populated generously. On the contrary, the Relations are populated reluctantly, ie. they need to be specified explicitly.
The Dependency Relations on Modules and Models are completely separated from the Used Language Relations on Modules and Models. Thus, no Dependency requires a Used Language or vice versa.
More info: Module Dependencies, Model Dependencies, Module Used Languages, Model Used Languages
By default, only Nodes present in the current Model can be referenced. Dependencies add other Models and Modules to be referenced from the current Model.
Models listed as Dependencies of Model A need to be contained within Modules listed in the Dependencies (including transitive entries) of the Module containing this Model. Example:
Module: ModuleA
Model: ModelA.one
Node: ModelA.one.alpha
Model: ModelA.two
Node: ModelA.two.alpha
Module: ModuleB [depends: ModuleA]
Model: ModelB.one [depends: ModelA.one]
Node: ModelB.one.alpha
references: ModelA.one.alpha
references: ModelA.two.alpha !!out of scope,
!!as ModelB.one has
!!no Dependency on
!!ModelA.two
Module: ModuleC
Model: ModelB.one [depends: ModelA.one] !!out of scope,
!!as ModuleC has
!!no Dependency on
!!ModuleA
There is no way to mark a Model internal and hide it from outside access.
More info: Module Dependencies, Model Dependencies, Module Used Languages, Model Used Languages
Re-exports a Module Dependency to be used by Modules depending on this Module. Example:
Module: ModuleA
Model: ModelA.one
Node: ModelA.one.TheNode
Module: ModuleB [depends: ModuleA; export=true]
Module: ModuleC [depends: ModuleA]
Module: ModuleBeta [depends: ModuleB]
Model: ModelBeta.one [depends: ModelA.one]
Node: ModelBeta.one.TheOneNode
references: ModelA.one.TheNode
Model: ModelBeta.two
Node: ModelBeta.two.TheTwoNode
references: ModelA.one.TheNode !!out of scope,
!!as ModelBeta.two has
!!no Dependency on
!!ModelA.one
Module: ModuleGamma [depends: ModuleC]
Model: ModelGamma.one [depends: ModelA.one] !!out of scope,
!!as ModuleC
!!does not export
!!ModuleA
More info: Module Dependencies
Default Scope is available for all Module types (TODO: check for DevKits).
Extends Scope is a superset of Default Scope, ie. we never need to have both a Default Scope and an Extends Scope Dependency on another Module.
More info: Module Dependencies
LanguageB (containing ConceptB) MUST extend LanguageA (containing ConceptA and ConceptInterfaceA), if and only if
- ConceptB extends ConceptA or ConceptB implements ConceptInterfaceA
- LanguageB defines a new Editor for ConceptA (but not if LanguageA only defines the Editor Hint)
- LanguageB defines a new Editor Component for ConceptA
- LanguageB uses an Editor Component defined in LanguageA
- LanguageB defines a new Typesystem for ConceptA
- LanguageB defines a Generator outputting ConceptA and LanguageA has a Runtime Solution
[AS]: Wrong (?): LanguageB uses an Editor Component defined in LanguageA
LanguageB SHOULD NOT extend LanguageA (but needs a Default Scope Dependency) if
- LanguageB defines a new Intention for ConceptA
- ConceptB defines a Child of Type ConceptA
- ConceptB defines a Reference to Type ConceptA
- ConceptB defines a behavior method Using Type ConceptA (eg. as return type, parameter type, or variable type)
LanguageB CANNOT define
- a new Behavior for ConceptA
- a new Constraint for ConceptA
To be precise, it is possible to remove all errors flagged on Behaviors and Constraints in LanguageB. However, they are not taken into account for ConceptA.
More info: Used Language, Module Dependencies, Language, Generator, Implicit Generator Dependencies, Runtime Solution
GeneratorB (inside LanguageB, containing ConceptB) MUST extend GeneratorA (inside LanguageA, containing ConceptA), if and only if
- GeneratorB defines a new Rule for ConceptA
- GeneratorB extends a Switch from GeneratorA
- GeneratorB defines a Generator Priority relative to GeneratorA
More info: Module Dependencies, Generator, Generator Priorities
Some Dependencies are added implicitly, ie. without being listed in the corresponding dialog.
Warning: Even if the Dependencies described below are established implicitly, they are not taken into account in every aspect of MPS. So if an error occurs, make sure we didn't rely on some implicit Dependency. If in doubt, make the Dependency explicit.
A Generator "inherits" some Dependencies from the Language it's defined in:
- The Language's Runtime Solutions are added to the Generator Module Dependencies.
- The Language Module is added to the Generator Module Dependencies.
- The Language is added to the Generator Used Languages.
Except the case of generating a Concept of a Language that has a Runtime Solution (as described above), there is no requirement on the Language's Dependencies or Used Languages stemming from the Generator.
More info: Generator
Both a Used Language and the Language Structure Aspect implicitly allow accessing the Language's Behavior methods. However, they not re-export the complete Behavior Aspect. For example, a BaseLanguage Class contained in the Behavior Aspect is not visible.
More info: Language
- implicitly loaded into the Java classpath of any Module using this Language.
- implicitly added to the Dependencies of the Generator contained in this Language.
-
implicitly loaded into the Dependencies of any Model using this Language.
Accessory Models are not designed to keep any classes. This is "design-only" information. They should not affect Java class path anyhow.
TODO: [AS]: I believe they should be added to the dependencies of the generator module automatically. (if they are saved inside the same language they are visible for generator)
Neither Runtime Solutions nor Accessory Models constitute a Dependency from the Language to the referenced Solution or Model.
More info: Module Runtime Language Settings, Language, Generator
Cyclic Dependencies between Modules should be avoided in general. They tend to render generation orders and other behavior non-deterministic. Languages are explicitly checked not to have a cyclic Extends Scope Dependency.
A special case are Runtime Solutions, Accessories Models, and Utility Models.
In contrast to Runtime Solutions, Utility Models are used while accessing a Behavior or running a Generator. Code within Runtime Solutions is used after the Generator ran from the generated code. Thus, a Runtime Solution SHOULD NOT use or reference the Language it's referred from. A Utility Model CAN use or reference the Language it's referred from.
Accessory Models CAN use or reference the Language they're referred from.
Model Used Languages need to be listed in the containing Module Used Languages.
There are no implicitly available Used Languages except described for Generators. Specifically, if LanguageB has an Extends Scope Dependency on LanguageA and ModuleC uses LanguageB, LanguageA is not a Used Language within ModuleC.
We MUST add LanguageA (containing ConceptA) to ModuleB's and contained ModelB's Used Languages if and only if
- ModelB instantiates ConceptA within the IDE
- ModelB executes Intentions from LanguageA
- ModelB requires Typechecks from LanguageA
- ModelB uses Editors from LanguageA by selecting an Editor Hint (but not if LanguageA only defines the Editor Hint)
- ModuleB is a Generator and outputs instances of ConceptA
[AS]: not sure about: ModelB uses Editors from LanguageA by selecting an Editor Hint (but not if LanguageA only defines the Editor Hint)
More info: Language Extends Scope
GeneratorA contained in LanguageA (containing ConceptA) will be executed for ModelS (contained in ModuleS) if and only if
- ModelS uses LanguageA and contains an instance of ConceptA
- ModelS lists LanguageA in Languages engaged on generation
- above conditions match LanguageB containing GeneratorB extending GeneratorA
For discussion, we establish a continued scenario:
(The Relations listed here are not complete in order to reduce clutter. The complete example is available.)
LanguageBase
defines ConceptBase, ConceptBase2
SolutionBase
contains ModelBase [using LanguageBase]
contains NodeBase [instanceof ConceptBase]
SolutionBase
doesn't change during generation, as LanguageBase
does not define any Generators.
LanguageBaseGen
contains GeneratorBase
defines a rule for ConceptBase
SolutionBaseGen
contains ModelBaseGen [using LanguageBase, LanguageBaseGen]
contains NodeBase [instanceof ConceptBase]
SolutionBaseGen
doesn't change during generation either, as it does not contain any instances from
LanguageBaseGen
, thus removing LanguageBaseGen
from the list of applicable Generators, ending up with
no Generators at all.
SolutionBaseGen2
contains ModelBaseGen2 [using LanguageBase; engages LanguageBaseGen]
contains NodeBase [instanceof ConceptBase]
SolutionBaseGen2
ends up with a transformed NodeBase
, as Languages engaged in generation are never removed.
LanguageBaseGenExtends [extends LanguageBase]
contains GeneratorBaseExtends
defines a rule for ConceptBase2
SolutionBaseGenExtends
contains ModelBaseGenExtends [using LanguageBase; engages LanguageBaseGenExtends]
contains NodeBase [instanceof ConceptBase]
contains NodeBase2 [instanceof ConceptBase2]
SolutionBaseGenExtends
ends up with an unchanged NodeBase
, but a transformed NodeBase2
.
GeneratorBaseExtends
will be executed, because LanguageBaseGenExtends
is listed in the Languages engaged in generation. However, the Dependencies of the Language are not considered for selecting the running Generators.
LanguageBaseGenExtends2 [extends LanguageBase]
contains GeneratorBaseExtends2 [extends GeneratorBase]
defines a rule for ConceptBase2
SolutionBaseGenExtends2
contains ModelBaseGenExtends2 [using LanguageBase; engages LanguageBaseGenExtends2]
contains NodeBase [instanceof ConceptBase]
contains NodeBase2 [instanceof ConceptBase2]
In SolutionBaseGenExtends2
both NodeBase
and NodeBase2
will be transformed, as LanguageBaseGenExtends2
is listed in the Languages engaged in generation and GeneratorBaseExtends2
extends GeneratorBase
.
LanguageExtendsGen [extends LanguageBase]
defines ConceptExtendsGen extending ConceptBase
contains GeneratorExtendsGen
defines a rule for ConceptExtendsGen
SolutionExtendsGen
contains ModelExtendsGen [using LanguageBase, LanguageExtendsGen]
contains NodeBase [instanceof ConceptBase]
contains NodeExtendsGen [instanceof ConceptExtendsGen]
Only NodeExtendsGen
will be transformed in SolutionExtendsGen
, as the only active Generator is
GeneratorExtendsGen
(because we found an instance of ConceptExtendsGen
contained in
the same Language as the Generator), and the Generator does not extend any other applicable Generator.
LanguageExtendsGen2 [extends LanguageBase]
defines ConceptExtendsGen2 extending ConceptBase
contains GeneratorExtendsGen2 [extends GeneratorBase]
defines a rule for ConceptExtendsGen2
SolutionExtendsGen2
contains ModelExtendsGen2 [using LanguageBase, LanguageExtendsGen2]
contains NodeBase [instanceof ConceptBase]
contains NodeExtendsGen2 [instanceof ConceptExtendsGen2]
All nodes within SolutionExtendsGen2
will be transformed, as an instance of ConceptExtendsGen2
was found,
and the generator GeneratorExtendsGen2
contained in the same language extends GeneratorBase
.
Relations on the output Model are defined only by the contents of the output Model that was created by the Generator. Thus,
- all Languages providing the Concepts of generated instances are listed in the Used Languages
- all Models referenced from the output Model are listed in the Dependencies
Additional Relations on anything else (source Module, source Model, Dependencies of the source Model, languages used in the source Model, Dependencies of applied Generators, languages used in applied Generators) are not added to the output Model. Implicit Dependencies apply as described.
Tests are regular or extended JUnit tests that can be executed within MPS or stand-alone.
Tests are contained in Test Models, defined by @tests
Stereotype.
The Stereotype enables
-
the "Run Tests" entry in Solution and Test Model context menu.
-
Build Language test instruction to search the Model for tests.
As soon as we're using any concepts from language jetbrains.mps.lang.test
, we need to have a TestInfo
Root Node in the same model. The TestInfo node needs to refer to a Project to be used to execute the tests. This reference may not use a ${module}
, ${language_descriptor}
, ${solution_descriptor}
, or ${project}
built-in Path Variables. It needs to refer to a Project containing the test.
This section lists all Relations required for a specific task.
If not specified otherwise, all Dependencies should be added
- if no Dependency exists: With Default Scope and no Export flag
- if a Dependency (no matter witch Scope and Export flag) exists: No change
MPS often creates the required Relations on Module level automatically if we add a Relation on Model level. However, this does not work in all cases, so double-check if the Module level Relation was created correctly if there are errors.
ClassB
inside ModelB
inside ModuleB
wants to create a variable of
type ClassA
inside ModelA
inside ModuleA
.
- To
ModelB
, add Dependency toModelA
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
ModuleB
toModuleA
.
More info: Dependencies, Module Dependencies, Model Dependencies
ClassB
inside ModelB
inside ModuleB
extends ClassA
inside ModelA
inside ModuleA
.
ClassC
inside ModelC
inside ModuleC
wants to use ClassB
as simple as possible.
- To
ModuleB
, add the Export Flag to the Dependency onModuleA
. - To
ModelC
, add Dependency toModelB
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
ModuleC
toModuleB
.
[AS]: Not sure we should add the Export Flag to the Dependency on ModuleA
here.
More info: Dependencies, Export Flag, Module Dependencies, Model Dependencies
Directly (aka root node) or indirectly (aka child node) within ModelB
inside ModuleB
, we want to create an instance of ConceptA
inside LanguageA
.
- To
ModelB
, add Used Language toLanguageA
.
Even if MPS complains about the Used Language being "out of scope", click ok. - MPS will automatically add a Used Language from
ModuleB
toLanguageA
.
More info: Used Languages, Module Used Languages, Model Used Languages
Make IntentionC
defined in LanguageC
for ConceptA
inside LanguageA
available in ModelB
inside ModuleB
.
- To
ModelB
, add Used Language toLanguageC
.
Even if MPS complains about the Used Language being "out of scope", click ok. - MPS will automatically add a Used Language from
ModuleB
toLanguageC
.
More info: Used Languages, Module Used Languages, Model Used Languages
Make TypesystemRuleC
defined in LanguageC
for ConceptA
inside LanguageA
available in ModelB
inside ModuleB
.
- To
ModelB
, add Used Language toLanguageC
.
Even if MPS complains about the Used Language being "out of scope", click ok. - MPS will automatically add a Used Language from
ModuleB
toLanguageC
.
More info: Used Languages, Module Used Languages, Model Used Languages
Make EditorC
defined in LanguageC
for ConceptA
inside LanguageA
using HintD
defined in LanguageD
available in ModelB
inside ModuleB
.
- To
ModelB
, add Used Language toLanguageC
.
Even if MPS complains about the Used Language being "out of scope", click ok. - MPS will automatically add a Used Language from
ModuleB
toLanguageC
.
More info: Used Languages, Module Used Languages, Model Used Languages
Assure GeneratorC
defined in LanguageC
for ConceptA
inside LanguageA
is executed for ModelB
inside ModuleB
.
- To
ModelB
, addLanguageC
to Languages engaged on generation. - To
ModuleB
, add Used Language toLanguageC
.
More info: Executed Generators, Generators
ClassB
inside ModelB
inside ModuleB
wants to create a variable of
type node<ConceptA>
inside LanguageA
.
- To
ModelB
, add Dependency toLanguageA.structure
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
ModuleB
toLanguageA
.
More info: Dependencies, Implicit Language Exports, Module Dependencies, Model Dependencies
ClassB
inside ModelB
inside ModuleB
wants to call
Behavior method opA
inside ConceptA
inside LanguageA
.
- To
ModelB
, add Dependency toLanguageA.structure
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
ModuleB
toLanguageA
.
Note: We could also add a Dependency from ModelB
to LanguageA.behavior
. However, as we need
to depend on LanguageA.structure
anyways (to be able to access the type), the recipe presented above is preferred.
More info: Dependencies, Implicit Language Exports, Language Extends Scope, Module Dependencies, Model Dependencies
ConceptB
inside LanguageB
wants to have a child or reference of
type ConceptA
inside LanguageA
.
- To
LanguageB.structure
, add Dependency toLanguageA.structure
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Used Language from
LanguageB
toLanguageA
.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
ConceptB
inside LanguageB
wants to extend / implement
ConceptA
/ ConceptInterfaceA
inside LanguageA
.
- To
LanguageB.structure
, add Dependency toLanguageA.structure
.
Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
. - Make sure the Dependency from
LanguageB
toLanguageA
has Extends Scope, either by setting it manually or by using the Intention on the error appearing onConceptB
.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
LanguageB
wants to define a new editor for EditorHintC
defined in LanguageC
for
ConceptA
inside LanguageA
.
- To
LanguageB.editor
, add Dependency toLanguageC.editor
. - To
LanguageB.editor
, add Dependency toLanguageA.structure
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageC
. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
. - Make sure the Dependency from
LanguageB
toLanguageA
has Extends Scope.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
LanguageB
wants to define a new Editor Component for ConceptA
inside LanguageA
.
- To
LanguageB.editor
, add Dependency toLanguageA.structure
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
. - Make sure the Dependency from
LanguageB
toLanguageA
has Extends Scope.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
LanguageB
wants to use EditorComponentC
defined in LanguageC
for ConceptA
inside LanguageA
.
- To
LanguageB.editor
, add Dependency toLanguageC.editor
. - To
LanguageB.editor
, add Dependency toLanguageA.structure
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageC
. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
. - Make sure the Dependency from
LanguageB
toLanguageC
has Extends Scope.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
LanguageB
wants to define a new Typesystem Rule for ConceptA
inside LanguageA
.
- To
LanguageB.typesystem
, add Dependency toLanguageA.structure
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
. - Make sure the Dependency from
LanguageB
toLanguageA
has Extends Scope.
Note: The overrides flag in Typesystem Rules is not related to Dependencies. This flag specifies if Typesystem Rules of Concepts extended by the applicable Concept are evaluated.
Example:
-
ConceptX
extendsConceptY
extendsConceptZ
-
ConceptZ
defines Typesystem RuleConceptZTypeRule
-
ConceptY
defines Typesystem RuleConceptYTypeRule1[override=true]
andConceptYTypeRule2[override=false]
-
ConceptX
defines Typesystem RuleConceptXTypeRule[override=false]
Then:
-
For
ConceptZ
, Typesystem RuleConceptZTypeRule
is evaluated. -
For
ConceptY
, Typesystem RulesConceptYTypeRule1
andConceptYTypeRule2
are evaluated.
ConceptZTypeRule
is not evaluated, as at least one Rule forConceptY
defines[override=true]
. -
For
ConceptX
, Typesystem RulesConceptYTypeRule1
,ConceptYTypeRule2
and
ConceptXTypeRule
are evaluated.
ConceptYTypeRule1
andConceptYTypeRule2
are included because no Rule forConceptX
defines[override=true]
.
ConceptZTypeRule
is not evaluated because the search for Rules in extended Concepts stops at the first concept having at least one Rule defining[override=true]
.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
LanguageB
wants to define a new Intention for ConceptA
inside LanguageA
.
- To
LanguageB.intentions
, add Dependency toLanguageA.structure
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
LanguageB
toLanguageA
.
More info: Language Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies
Create Generator includes
- Create new Root Mapping
- Create new Reduction Rule
- Create new Switch
GeneratorB
inside LanguageB
wants to create a Generator transforming ConceptA
inside LanguageA
into ConceptC
inside LanguageC
.
- To
GeneratorB.main@generator
, add Dependency toLanguageA.structure
. - To
GeneratorB.main@generator
, add Used Language toLanguageC
. Even if MPS complains about the Dependency or Used Language being "out of scope", click ok. - Don't forget to sort your generator into the generation process by defining some Generator Priority.
- MPS will automatically add a Dependency from
GeneratorB
toLanguageA
. - MPS will automatically add a Used Language from
GeneratorB
toGeneratorA
. - If
LanguageC
defines a Runtime Solution: ToLanguageB
, add Extends Scope Dependency toLanguageC
.
More info: Language Extends Scope, Generator Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies, Module Used Languages, Model Used Languages
Extend Generator includes
- Assure another Generator is always executed if this Generator is executed
- Create new Reduction Rule to be used in another Generator
- Create a new Switch entry for a Switch in another Generator
GeneratorB
inside LanguageB
wants to extend GeneratorA
inside LanguageA
.
GeneratorA
transforms ConceptC
inside LanguageC
into ConceptD
inside LanguageD
.
GeneratorB
transforms ConceptE
inside LanguageE
into ConceptF
inside LanguageF
.
- To
GeneratorB.main@generator
, add Dependency toGeneratorA.main@generator
. Even if MPS complains about the Dependency being "out of scope", click ok. - MPS will automatically add a Dependency from
GeneratorB
toGeneratorA
. - Make sure the Dependency from
GeneratorB
toGeneratorA
has Extends Scope.
More info: Language Extends Scope, Generator Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies, Module Used Languages, Model Used Languages
GeneratorB
inside LanguageB
wants to transform ConceptA
inside LanguageA
into a ConceptAJavaClass
extending ConceptAJavaClassBase
inside ModelC
inside SolutionC
.
- To
GeneratorB.main@generator
, add Dependency toLanguageA.structure
. - To
GeneratorB.main@generator
, add Dependency toModelC
. - To
GeneratorB.main@generator
, add Used Language toBaseLanguage
. Even if MPS complains about the Dependency or Used Language being "out of scope", click ok. - Don't forget to sort your generator into the generation process by defining some Generator Priority.
- MPS will automatically add a Dependency from
GeneratorB
toLanguageA
. - MPS will automatically add a Dependency from
GeneratorB
toSolutionC
. - MPS will automatically add a Used Language from
GeneratorB
toBaseLanguage
. - To
LanguageB
, add Extends Scope Dependency toBaseLanguage
(becauseBaseLanguage
defines a Runtime Solution). - To
LanguageB
, add Runtime Solution toSolutionC
.
More info: Runtime Solutions, Language Extends Scope, Generator Extends Scope, Used Language, Dependencies, Module Dependencies, Model Dependencies, Module Used Languages, Model Used Languages
LanguageB
wants to use SolutionA
as Runtime Solution.
- To
LanguageB
, add Runtime Solution toSolutionA
.
Note: We don't need any other Relation, specifically, no Dependency from LanguageB
to SolutionA
.
More info: Runtime Solutions, Dependencies
BuiltInNodeA
as Instance of BuiltInConcept
inside LanguageA
should be available to be referenced anywhere LanguageA
is a Used Language.
- Create
AccessoryModel
as Aspect inLanguageA
- To
AccessoryModel
, add Used Language toLanguageA
. - Create
BuiltInNodeA
insideAccessoryModel
. - To
LanguageA
, add Accessory Model toAccessoryModel
(if not present already).
Note: We don't need any other Relation, specifically, no Dependency from LanguageA
to AccessorySolution
.
More info: Accessories Model, Dependencies
complexBehavior()
defined for ConceptA
inside LanguageA
needs ComplexBehaviorInternalJavaClass
for its implementation.
or
GeneratorA
inside LanguageA
needs ComplexGeneratorInternalJavaClass
for its execution (eg. for a complex condition or macro).
- Create
BehaviorUtilityModel
/GeneratorUtilityModel
as regular Model withinLanguageA
. - To
BehaviorUtilityModel
/GeneratorUtilityModel
, add Used Language toBaseLanguage
. - Create
ComplexBehaviorInternalJavaClass
/ComplexBehaviorInternalJavaClass
withinBehaviorUtilityModel
/GeneratorUtilityModel
. - To
LanguageA.behavior
/GeneratorA.main@generator
add Dependency toBehaviorUtilityModel
/GeneratorUtilityModel
More info: Utility Model, Dependencies
TODO: IDEA Plugins, MPS Plugins, External Classes, External Sources