読者です 読者をやめる 読者になる 読者になる

Yasuo's Notebook

ソフトウェア開発の話題が中心の備忘録です。

Xtextでクロスリファレンス利用時の要素の絞り込み

Xtextでクロスリファレンスを使用する際に親要素によって絞り込まれた要素名をリファレンスする方法を試してみたので紹介します。

まずは普通のリファレンスを使用する文法をサンプルとして作成します。
スポーツのリーグの構成を定義する簡単な文法を作ってみました。
リーグがあってその下にチームがあって、チームにプレイヤーが所属しているという具合です。
f:id:yasuo99:20140331225836p:plain

この文法を使ってリーグやチームを定義してみます。
f:id:yasuo99:20140331225847p:plain

今回の本題は、両リーグ通じてのMVPを定義するときに以下のようにリーグ.チーム.プレイヤーの階層構造を利用してコンテンツアシストに表示される候補を絞り込む方法です。
具体的には下記のような定義をする際にALeagueの後のチームを選択する候補がXTeamとZTeam、XTeamの後のプレイヤーを選択する候補がPlayer1、Player3となるのが期待結果です。

MVP mvp
    ALeague.XTeam.Player1

まず、上記のようなMVPを定義するために文法を修正します。

f:id:yasuo99:20140331231406p:plain

この状態でMVPの定義をしたらどのような候補が表示されるか試してみましょう。

f:id:yasuo99:20140331231825p:plain

ALeagueを選択しているのでXTeamとZTeamのみが候補として表示されてほしいところですが、YTeamも表示されてしまいます。
期待通りに候補を絞り込むにはScopeProviderに絞り込みの処理を記載する必要があります。
具体的には、以下の部分になります。
f:id:yasuo99:20140331232213p:plain

この部分に記載する絞り込みの処理の形式はXtextのマニュアルのScopingに書かれています。
以下のURLで”Declarative Scoping”の項です。
https://www.eclipse.org/Xtext/documentation.html#scoping

マニュアルには以下のように記載されています。

IScope scope_<TypeToReturn>(<ContextType> ctx, EReference ref)

TypeToReturnというのは、絞り込んだ結果の候補の型です。ContextTypeというのは絞り込みを行う要素を含む型です。今回のケースだとTeamとPlayerがTypeToReturn、ContextTypeがMVPということになります。
以下のように記載してみましょう。

f:id:yasuo99:20140401003544p:plain

再び、MVPの定義を試してみましょう。

f:id:yasuo99:20140401003636p:plain
f:id:yasuo99:20140401003644p:plain

ちゃんと、親要素に応じた選択候補が出るようになりました。