MPS 2020.3 ヘルプ

変換メニュー言語

概要

変換メニュー言語は、エディターのさまざまな場所に表示されるサブメニューとアクションの階層構造を記述する変換メニューを定義するために使用されます。現在、変換メニューが表示される可能性のある場所がいくつかあります。サイド変換メニュー代替メニューコンテキストアシスタント、およびコンテキストアクションツールです。言語設計者とプラグイン作成者は、変換メニュー言語の拡張に記載されているように、追加の場所を定義し、場所ごとに必須またはオプションの機能(アイコンやツールチップなど)を指定できます。

メニューを理解する

代替メニューは、現在のノードを別のノードに置き換えるオプションを提供します。提供されるノードは、ノードが最終的に挿入される位置と互換性がある必要があります。代替メニュー定義がルックアップされるとき、ルックアップアルゴリズムへの入力は、既存のノードの概念ではなく、その包含リンクです。それは「場所」です。重要な AST では、現在その場所を占有しているノードではありません。

例として、BaseLanguage の ExpressionStatement コンセプトのインスタンスを考えてみましょう。これには、Expression のコンセプトを期待する「expression」子ロールがあります。それが AssignmentExpression ( `a = 5;`)を保持していると仮定しましょう。ユーザーが ExpressionStatement 内の AssignmentExpression を別のノードに置き換える(置き換える)場合は、ExpressionStatement.expression 包含リンクのターゲットコンセプトであるため、任意の式が機能します。現在のノードは、関連する代替メニュー定義を見つける目的には関係ありません。

ほとんどの概念は、以下を含む代替メニュー定義を暗黙的に使用します。

  • 抽象的でない限り、この概念のノードを作成するためのアクション

  • この概念のすべてのサブコンセプトのデフォルトメニュー定義を含めるための指示

その結果、Expression のメニューを作成するときに、MPS はそのサブコンセプトをトラバースし、それらもメニューに含めます。ただし、スーパーコンセプトは考慮されていないことに注意してください。ExpressionStatement.expression の補完メニューには、BaseConcept のインスタンスを置換することはできず、 のみを置換できるため、BaseConcept の置換メニュー定義からのエントリは含まれません。

変換メニュー定義は、代替メニュー定義とは逆の方法で構成されます。既存のノードを変換したいという考えなので、その概念を調べて、その変換メニューを調べます。その特定の概念に対してメニューが定義されていない場合、MPS はスーパーコンセプトのデフォルトメニューにフォールバックします(コンセプトのインスタンスは、リスコフの置換原則に従って、そのスーパーコンセプトのインスタンスと見なすこともできるため)。デフォルトの変換メニュー定義を作成する場合、フォールバック動作は適用されず、明示的に指定する必要があることに注意してください( `superconceptsmenu` 命令を使用)。BaseConcept_TransformationMenu と呼ばれる BaseConcept のデフォルトの変換メニューを見ると、現在のリンクのデフォルトの代替メニューが含まれていることがわかります。

代替メニュー定義をエディターセルに直接アタッチすることはできません。最初に変換メニューに含める必要があります。デフォルトの代替メニュー定義は、BaseConcept のデフォルトの変換メニュー定義にすでに含まれているため、デフォルトのメニュー定義のみを使用する場合は、これを行う必要がない場合があります。完了メニューは、変換メニュー定義から構築されます。定義に「この代替メニュー定義を含める」と記載されている場合は含まれますが、含まれていない場合は含まれません。

メニューを定義する

変換メニューは、さまざまな場所に表示される UI アクションを定義します。設計時に、メニューはセクションのリストとして指定され、各セクションには特定の場所のセットのメニューパーツのリストが含まれます。実行時には、メニュー部分と場所を使用してメニューの内容(メニュー項目)が生成されます。

メニュー定義には、デフォルト名前付きの 2 つのフレーバーがあります。メニュー定義は、メニューコントリビューションを通じて拡張することもできます。

Transformx1

デフォルトメニュー

各概念には、デフォルトの変換メニューが関連付けられています。言語設計者が明示的に提供しない場合は、最も近いスーパーコンセプト用に定義された変換メニューが想定されます。どのスーパーコンセプトにも何も指定されていない場合は、BaseConcept で定義されているものが使用されます。これには、その位置に適した代替アクションが含まれます(以下の代替アクションのセクションを参照)。

デフォルトメニューは、言語設計者が表示するメニューを指定していない場合に使用されます。

Tml1

名前付きメニュー

名前付きメニューは、概念の追加メニューです。デフォルトメニューのようにそれはまた適当な概念を指定しそしてセクションのリストを含んでいる。その用語が示すように、名前付きメニューは明示的に設定された名前を持ちます。名前付きメニューは、セルの変換メニューとして設定すること、またはメニューメニューを含めるを介して別のメニューに含めることを意味します。

Tml2

名前付きメニューをエディターセルに添付する:

Image2016 5 30 17 9 40

注: デフォルトの変換メニューは、メニューと同じ方法で個々のセルに添付することもできます。

メニューコントリビューションは、追加のメニューパーツをコントリビューションすることにより、特定のメニューを拡張します。これは、拡張言語が拡張言語で定義されたメニューにエントリを追加する必要がある場合に特に役立ちます。貢献は、実際には、貢献されているメニューがある言語以外の言語でのみ定義できます。

実行時にメニューが要求されると、元の定義とすべてのコントリビューションがマージされ、結合された定義を使用してメニューが作成されます。貢献に関するいくつかの重要な注意事項:

  1. 個々の定義がマージされる順序は、現在のところ不明です。

  2. 寄付は、寄付するメニューからメニュー部分を削除することはできません。

  3. 概念の暗黙のデフォルトメニューへのコントリビュートを定義することは可能です。

Tml3

セクションの場所

メニュー内のセクションの場所を指定することで、UI のどの部分にアクションを挿入するかを指定します。

Locations1

以下の標準メニューパーツが利用可能です。

  • action –実行するアクション、それに対応するメニューテキストおよび適用性を指定する単純なメニュー項目。

  • グループ - メニュー項目のコレクション。これらの項目を超えて、グループは 1 つ以上の変数を定義し、グループ内のすべてのアクションで共有して、繰り返しの計算を回避することができます。さらに、グループは、グループ内のアクションをユーザーが利用できるようにするタイミングを示す条件を保持します。

  • include- 特定のデフォルトまたは名前付きメニューを(もしあれば、その貢献とともに)含めます。包含サイクルは実行時に検出され、エラーメッセージが生成されます。

  • 代替メニューを含める - このメニューの一部として使用するデフォルトまたは名前付きの代替メニューを含めます。

  • パラメーター化 - 複数の値でパラメーター化されたアクション。

  • サブメニュー–追加のパーツを含むサブメニュー。

  • スーパーコンセプトメニュー–デフォルトでは含まれていないため、該当するコンセプトのスーパーコンセプトのデフォルトメニューが含まれます。

  • 代替メニューの折り返し - 提供されたハンドラーを使用して、指定された概念を折り返します

言語 jetbrains.mps.lang.editor.menus.extras には、変換メニューからさまざまなアクションに似たエンティティを含めるためのアダプターが含まれています。

  • インテンション–インテンション( jetbrains.mps.lang.intentions からの BaseIntentionDeclaration のサブコンセプト)をラップします。

  • リファクタリングjetbrains.mps.lang.refactoring からリファクタリング Refactoring をラップします。

  • プラグインアクション–プラグインアクション ActionDeclarationjetbrains.mps.lang.plugin からラップします。

Oprions5

サイド変換

テキストエディターでコードを編集するときは、左から右のいずれかに入力できます。

1_ press + 1+_ press 2 1+2_

または右から左へ

_1 press 2 2_1 press + 2+_1

この振る舞いをエミュレートするために、MPS には左右の変換という側面の変換アクションがあります。セルの左または右部分を入力したときに利用できるようになるアクションを作成できます。例: MPS では次のことができます。

1_ press + (red cell with + inside appears) 1+_ press 2 (red cell disappear) 1+2_

また

_1 press + (red cell with + inside appears) +_1 press 2 (red cell disappear) 2_+1

最初のケースは右変換と呼ばれます。2 番目のケースは左変換と呼ばれます。

セクションのサイドトランスフォームの場所を選択して、トランスフォーメーションメニューでサイドトランスフォーメーションを定義します。

Side transforms100

この言語を使用すると、言語設計者は、サイドトランスフォームメニューの項目を特定のセルの完了メニューに含めることもできます。これを行うには、完了セクションを含む変換メニューを目的のセルにアタッチします。その補完セクションは、インクルードメニュー部分を保持し、サイドトランスフォームの場所を指定します。サイドトランスフォームメニューのアイテムが最後まで含まれます。

Cellmenu1

含まれるメニューの場所は、インテンションの「場所の指定」を使用して指定できます。

代替メニュー

代用アクションは、モデルの一部に対してユーザーが呼び出した変換を定義し、その間に 1 つのノードが別のノードに置き換えられます。これらの代替アクションのビジュアル UI 要素(補完メニューなど)への実際のマッピングは、変換メニューを介して行われます(上記のセクションを参照)。

通常、代替アクションは、エディターで Ctrl + スペースを押すことによってトリガーされます。表示される完了メニューには、ユーザーが選択すると、キャレットのノードを置き換えるオプションが含まれています。side-transformations、コンテキストアシスタント、またはコンテキストアクションツールとは異なり、置換にはデフォルトの動作があり、言語の作成者が別の方法で定義しない限り、これが有効になります。

コード補完のデフォルトの動作

言語作成者によって明示的に実装されたメニューがなくても、MPS は現在のノードの代わりとなる補完メニューを提供します。

  • カーソルがシングルセルエディターの前面にある

    Transforms10
    Transforms11

  • ユーザがノードのエディター全体を選択しました

    Transforms12
    Transforms13

このような場合、Control + Space を押すと、特定のコンテキストに適用可能なインポートされた言語のすべての概念を含むメニューが表示され、モデル内の現在のノードを置き換えることができます。

MPS は次の手順でデフォルトの補完メニューを作成します。

  1. 選択が概念 A を許す位置の内側にあるなら、A のすべての可能にされた副概念は完了メニューで利用可能になるでしょう。

  2. すべての抽象的な概念は除外されます

  3. 「子になることができる」という制約が false を返すすべての概念は除外されます

  4. 親ノードの「親になることができる」制約が false を返すすべての概念が除外されます

  5. コンセプトに 1:1 の参照が含まれている場合、完了メニュー自体には追加されません。代わりに、その参照のスコープ内の要素ごとにアイテムが追加されます。このようなアイテムには、スマートリファレンスという名前を使用します。

ノード置換をカスタマイズするには、置換メニューを使用します。

代替メニュー (デフォルト)

コンセプトのデフォルトの代替メニューを定義することにより、ユーザーが Control + Space を押したときに表示される完了メニューの内容をカスタマイズできます。また、これらのサブコンセプトが独自のデフォルトの代替メニューを定義していない限り、コンセプトのサブコンセプトにも影響を及ぼします。

Substitution menu 2

ただし、代替メニューをエディターの特定のセルに割り当てる場合は、変換メニューにしか追加できないため、代替メニューを変換メニューに含める必要があります。

Include default substitute1

代替メニュー (名前)

名前付き代替メニューを使用すると、複数の代替メニューを作成してさまざまなコンテキストで使用することができます。名前を付けた代替メニューを有効にするには、最初に別の代替メニューまたは変換メニューに含める必要があります。

代替メニュー投稿

トランスフォームメニューと同様に、代替メニューの貢献は、新しい言語で定義された代替メニューへの新しいエントリを提供します。

オプション

  • 概念の追加 - メニューに単一の概念を追加します

  • 概念リスト - 概念のコレクションを追加します

  • グループ - 条件が満たされた場合、エントリのグループを追加します

  • 包含 - 指定されたメニューを含みます

  • パラメーター化 - パラメーター化された代替アクションを追加します

  • 参照アクション - 参照の可能なターゲットの外観を含めてカスタマイズします

  • サブコンセプトメニュー - コンセプトのすべてのサブコンセプトを含む

  • 代替アクション - 単一の代替アクションを追加します

  • 代用メニューの折り返し - 提供されたハンドラーを使用して指定された概念を折り返します

セルメニューとセル固有の変換メニューの相互作用

セルに "menu" と "transformation menu" の両方が指定されている場合は、両方のメニューから該当するエントリが結合されます。一部のセルメニューパーツ( CellMenuPart_PropertyPostfixHints などの CellMenuPart_Abstract の子孫)には、同等の変換 / 置換メニューパーツがまだありません。

プロパティ / 参照用の変換メニューを含める

プロパティ / 参照セルのメニューのカスタマイズは、プロパティ / 参照変換メニューパーツを使用して行うことができます。参照 / プロパティセルの補完メニューをカスタマイズするとします。以前は、インスペクターで「インラインメニュー」を定義することで実行できました。これで、変換メニューを介して実行することもできます。プロパティと参照変換メニューパーツを導入しました。参照変換メニュー部分には、ターゲットノードを特定の参照に設定するアクションが含まれています。ターゲットノードは、その参照のスコープから取得されます。プロパティメニュー部分についても同じことが言えます。プロパティタイプの値を取得し、値を特定のプロパティに設定するアクションが含まれます。

参照例

参照セルの補完メニューを作成したいとします。メニューには、スコープ内にある参照の通常のターゲットとその他のカスタムアクションが含まれているはずです。これは、次の名前付き変換メニューを参照セルにアタッチすることによって実行できます。

Class creator completion menu

それで、すべての標準的な参照アクションと私たちのカスタムアクションを完成時に受け取るでしょう:

Completion

見ることができるように参照メニュー部分は「インラインメニュー」の「一次選択参照メニュー」部分の類似物です、しかしさらにカスタマイズ可能です。また、セルにメニューが添付されていない場合は、その参照メニューがデフォルトで使用されます。

プロパティの例

もう一つの例 - カーソルがそのプロパティのセルに次のラベルのセル上にあるとき、コンテキストアシスタントで特定のプロパティのためにすべての可能な値を参照するとします。Kaja 言語のコードを見てみましょう。

Kaja code

キャレットを見ているセルに移動したときに、見ている方向のすべてのバリエーションを確認したいと思います。そのため、このラベルセルに次のメニューを添付します。

Looking direction

そして結果を得る:

Dir cont assist result

「インラインメニュー」に対するこれらのメニュー部分の利点は次のとおりです。

  1. これらは、参照 / プロパティセルだけでなく、任意のセルにアタッチできます。

  2. 補完だけでなく、あらゆるメニューの場所(コンテキストアシスタント、コンテキストメニュー)で使用できます。

  3. 参照メニューはよりカスタマイズ可能です(プロパティメニューも間もなくカスタマイズ可能になるでしょう)。

メニュー発見アルゴリズム

MPS がどのように変換メニューを選択するかのプロセスを理解すると、メニューをより自信を持ってデザインできます。

変換メニューを検出するための組み込みの動作は、現在の概念のスーパーコンセプトのメニューを含めることです。デフォルトでは、MPS は、<CurrentConcept> _TransformationMenu という名前の現在の概念の変換を検索し、次にそのスーパーコンセプトを検索します。メニューなど、BaseConcept_TransformationMenu まで。

代替メニューは変換メニューに似ていますが、その発見は反対方向に働きます。ここで、概念 A の変換メニューはそのスーパーコンセプトのメニュー(BaseConcept まで)を含みます。なぜなら、サブ概念だけがモデル内の A を安全に置き換えることができるからです。代替メニューは、既存のノードの概念に基づいて検索されるのではなく、リンクのターゲットの概念に基づいて検索されるため、変換メニューとは少し異なります。

アイテムトレースを表示する

どの変換または代替メニューが完了メニューまたはコンテキストアシスタントに特定のアクションを提供したかを追跡するには、ユーザーは完了メニューエントリで Control/Cmd + Alt + B を押すだけで、対話的なトレースレポートが表示されます。

相互に含まれる代替メニューと変換メニューが多数あるため、完了アシスタントまたはコンテキストアシスタントでアクションがどのように表示されたかを追跡するのが難しい場合があります。これで、完了時に(矢印で)またはコンテキストアシスタントで(cmd/ctrl + alt + Enter を押して)アクションを選択し、cmd/ctrl + alt + B を押すことができます。プロジェクトツールにトレースが表示されます。これは、トップレベルメニューから始まり、アクション宣言で終わる、互いに含まれるメニューとメニュー部分の宣言のトレースです。メニューまたはメニュー部分の宣言が明示的でプロジェクト内にある場合は、ツールで太字になっているため、それをクリックして宣言に移動できます。


キャレットをステートメントに配置し、変数参照の補完を表示してから、「Show ItemTrace」を呼び出すと次のようになります。

Action trace

完成したものが、BaseConcept である superconcept のメニューを含む Statement のデフォルトの変換メニューであることがわかります。それは今度はステートメントの代わりのメニューを含み、今度は式のメニューをラップします。それから、Expression のサブコンセプトになります。その 1 つが VariableReference です。VariableReference は「スマートリファレンス」の概念であるため、Variable 概念の目に見えるすべてのターゲットを見つけようとします。そのため、ステートメントのメニューに変数参照が表示されます。

関連ページ:

エディターのアクション

MPS エディターには、完了アクション、ノード作成ポリシーにかなり実用的なデフォルトがあります。しかし、カスタマイズしたい場合は、アクション言語を使用しなければなりません。ノードファクトリノードが別のノードに置き換えられる場合、置き換えられるノードが保持する値を使用して、置き換えノードの作成プロセスをパラメーター化するか、モデル内の置き換えノードの将来の位置を反映することも役立つ場合があります。ノードファクトリはまさにそれを提供します。置換アクションで、または新しい初期化ノード <>...

コンテキストアシスタント

MPS は、コンテキストでアクションを実行するためのいくつかのメカニズムを提供する: 完了、インテンション、リファクタリング、その他のさまざまなポップアップメニュー: これらのメカニズムには、経験の浅い新しいユーザーにはすぐには表示されないという共通点があります。また、通常、多くの可能な選択肢を提供し、利用可能な機能全体を明らかにします。これは、上級ユーザーには役立ちますが、初心者を圧倒する可能性があります。DSL でスクリプトを作成するプロセスを通じて新しいユーザーをより適切にガイドするために...

コンテキストアクションツール

コンテキストアクションツールは一部の DSL ユーザーのマウスナビゲーションへの好みに対応しています。指定されたコンテキストで適用可能なアクションが、階層的に整理されたサイドバーに一覧表示されます。一般的な動作は、1 回のクリックでアクティブになるカーソル位置で何かをすることです。コンテキストアクションツールは、このコンテキストでどのようなことが実行可能かを明確に伝えるため、探索的な作業を発見するのに最適です。ツールウィンドウでオプションを選択することによって、ユーザーは関連するアクションを起動...